Improving Object Identification
When Squish records tests, it uses object properties to identify most objects. For each object that Squish identifies, it creates an entry in the Object Map. Each entry is a pair of names—a symbolic name (a variable name), and a real name (a mapping of property name–value pairs). When tests are run, Squish uses the values of multi-property real names as lookup criteria when searching for objects in the AUT's memory.
Properties can be numbers, strings, or objects. For properties that have object values (i.e., the value is the name of another object, e.g., the container and window properties), another search is done using Squish's object lookup functionality to find it.
Object properties can only be matched exactly, while most string properties can use exact, wildcard, or regex matching. Some special properties also require exact matching such as type
, tagName
(in Squish for Web) and basetype
(in Squish for Java).
Note: In Squish for Web, the className
property is unusual in that its value is a list of strings (class names) and if we use exact matching the match will work if any of the element's class attribute's classes matches the one we have specified.
Matching Objects with Changeable Texts
One commonly encountered problem is that many applications change the texts used by some widgets. For instance, a button's text might change from Pause to Resume and back again, or the application might put the name of the current file or workspace in the main window's title bar caption. For example, lets assume that we have the following real name for a fictional MainWindow
object in our application with the title "AddressBook v1.3 - google contacts.dat":
{'windowTitle': 'AddressBook v1.3 - google contacts.dat', 'type':'MainWindow'}
This multiple property name will match the first object in the application which is of type MainWindow
and whose title matches the one shown above.
Such names work perfectly well in most situations and they are generated automatically when recording a test (see Object Name Generation for more information on that topic). Unfortunately, since the windowTitle changes, this can break object names that point to it or its children.
If we wanted to make the MainWindow
's real name more general, we could remove the property entirely, or use the Wildcard or the RegularExpression matching options. From the Object Map Editor, one can be selected by double-clicking on the Equals operator between the property and the value in a real name, as shown below:
Changing the matching operator in a real name property.
We can see how these object names are represented by looking at the Scripted Object Map's suite_xyz/shared/scripts/names.(py|pl|rb|tcl|js)
file, as shown below:
MainWindow_Wildcard = {"type": "MainWindow", "windowTitle": Wildcard("Address Book*")} MainWindow_Regex = {"type": "MainWindow", "windowTitle": RegularExpression("Address Book.*")}
export var mainWindowWildcard = {"type": "MainWindow", "windowTitle": new Wildcard("Address Book*")}; export var mainWindowRegex = {"type": "MainWindow", "windowTitle": new RegularExpression("Address Book.*")};
our $mainwindow_wildcard = {"type" => "MainWindow", "windowTitle" => wildcard("Address Book*")}; our $mainwindow_regex = {"type" => "MainWindow", "windowTitle" => regularExpression("Address Book.*")};
MainWindow_Wildcard = {:type => "MainWindow", :windowTitle => Wildcard.new("Address Book*")} MainWindow_Regex = {:type => "MainWindow", :windowTitle => RegularExpression.new("Address Book.*")}
set MainWindow_Wildcard [::Squish::ObjectName type MainWindow windowTitle {-wildcard {Address Book*}}] set MainWindow_Regex [::Squish::ObjectName type MainWindow windowTitle {-regularexpression {Address Book.*}}]
In a real world situation, you would not need both of these entries - they are equivalent. Both real names specify that the windowTitle must begin with "Address Book" followed zero or more other characters.
The Wildcard
version uses *
for the wildcard, and it stands for zero or more of any characters. The RegularExpression
version uses dot (.) to match a single character, and star (*) as a quantity-modifying meta-character that applies to the thing before it, making it "zero or more" in quantity. These both should match "AddressBook - Untitled" and also "AddressBook - MyAddresses.adr".
Exact Matching
This kind of matching can be used in all situations, and is the only kind of matching that is allowed for type and for properties whose value is an object (i.e., is specified using a real name). Here is an example:
{"type": "LineEdit", "visible": 1, "buddy": {"text": "Phone:", "type": "QLabel"}}
This real name is used to identify an object of type LineEdit
that has a visible set to true (1) and that has an associated label—a buddy—which in turn is specified using another real name.
Wildcard Matching
The Wildcard syntax is used for inexact matches. This kind of matching cannot be used for the type
property or for symbolic object names.
When wildcard matching is in use the ?
, *
, [
, ]
, and \
characters all take on special meanings and are not matched literally. All other characters are matched literally.
? | This character stands for any one single character no matter what it is |
* | This character stands for any number of any characters—including no characters at all |
?* | These two characters together stand for at least one of any character (i.e., any one single character followed by zero or more of any character) |
[...] | Brackets are used to specify a set of one or more characters any one of which must be matched. For example, [0-9] matches exactly one digit, and [aAbBcC] matches only an "a", "b", or "c", whether upper- or lower-case |
\ | The backslash is used to escape one of the special characters, so \? stands for a literal "?", and \* stands for a literal "*". Unfortunately, brackets cannot be escaped so always have their special meaning, so the only way to match literal brackets is to use ? (which will match anything), or to use regex syntax |
Here is a real name containing a wildcard:
{'type' : 'LineEdit', 'visible':'1', 'buddy': {'type':'Label', 'text':Wildcard("Name*\?"} }
This real name is used to identify an object of type LineEdit
that has a visible property set to true (1) and that has an associated label—a buddy—which in turn is specified using another real name. But here, the buddy's label text is specified using Wildcard matching and must contain the text "Name" followed by zero or more other characters followed by a literal "?".
Here's a real name containing a RegularExpression property match:
{'caption': RegularExpression('UsefulApp v[1-9].[0-9] - ?*.[dD][aA][tT]'), 'type': 'MainWindow'}
Here, caption must have a value that starts with the literal text "UsefulApp v" followed by a digit (but not including zero), then a period, then another digit, then a space, a hyphen, and a space, and then at least one character (indicated by the ?
), then zero or more other characters (due to the *
), followed by ".dat" (in upper- or lower-case). Notice that if we had specified the filename part of the caption as *.[dD][aA][tT]
it would have matched the suffix alone, i.e., ".dat" since the *
symbol can match zero characters. By starting with the ?
we ensure that at least once character is matched in front of the suffix.
Regular Expression Matching
The RegularExpression syntax is used for inexact matches. This kind of matching cannot be used for the type or for properties whose value is an object (i.e., is specified using another real or symbolic name). Regex matching allows us to write more sophisticated—and potentially harder to understand and maintain—matching expressions than can be achieved using wildcard syntax. For this reason, we recommend using wildcard matching where possible simply because it is easier, both to read and write.
Note: In Squish for Web editions, the regex syntax is the same as the one supported by JavaScript. Documentation for this syntax is available from Regular-Expressions.info and w3schools.com. For all other Squish editions the Qt QRegExp
syntax is used—this is documented here: QRegExp.
Real (Multi-Property) Name Properties
Which properties does a particular object have that can be used for identifying an object? The answer is not straightforward because the properties are discovered dynamically.
To take the Qt toolkit as a typical example: Squish exposes all the QObject invokables and properties via QMetaObject introspection, and then adds some Synthetic Properties that are useful to Squish.
In general, any of an object's properties is potentially usable for identifying it (e.g., in a real name for calls to the Object findObject(objectName) and Object waitForObject(objectOrName) functions). However, Synthetic Properties are not selectable from Squish IDE's Verification Point Creator/Editor (because they do not show up in the Properties view), so verification points on those properties must be written manually.
To find out what an object's regular properties are, look up the object's type in its toolkit's documentation, or use the Spy. To use the Spy begin by launching the AUT (see the Launch AUT action), then interact with the AUT until the relevant AUT object is visible. At this point context switch back to the squishide
and invoke the Object Picker () (see the Application Objects view); and pick the object of interest. Now all the object's regular properties will be shown in the Properties view. To find out the object's Synthetic Properties, invoke the context menu on the object in the Application Objects view and copy its real name to the clipboard: any properties in the real name that are not listed in the Properties view are Synthetic Properties, added by Squish.
Synthetic Properties
These are the Synthetic Properties added by Squish.
Property Name | Toolkits | Notes |
---|---|---|
aboveLabel | macOS, iPhone | The symbolic name of the label above the object being identified |
aboveObject | Windows | The symbolic name of the object above the object being identified |
aboveWidget | Java, Qt | The symbolic name of the widget above the object being identified |
aboveWidgetText | Qt | The text held by the widget above the object being identified. Requires aboveWidgetType to also be specified. |
aboveWidgetType | Qt | The type of the widget above the object being identified |
arrowDirection | Java | Holds the direction of SWT buttons that have the arrow style enabled. |
basetype | Java | A more versatile alternative to type for Java toolkits |
buddy | Qt | The symbolic name of the label associated with the object being identified |
buddyName | Qt | The objectName of the label associated with the object being identified |
buddyText | Qt | The text of the label associated with the object being identified |
buttonType | Java | Holds the type of SWT buttons. This property is useful for identifying buttons with arrows. |
caption | Java | Holds the object's title, caption, or text, if this object typically has such text to display. |
column | Java, Qt | The object being identified's column (if it is inside a multi-valued object such as a table or tree) |
columnNumber | macOS | The object being identified's column (if it is inside a multi-valued object such as a table or tree) |
container | Java, Qt, macOS, iPhone, Windows | The symbolic name of the object that contains the object being identified |
containerLabel | Qt | The text label of the object that contains the object being identified |
containerName | Qt | The name (e.g., caption) of the object that contains the object being identified |
containerType | Qt | The type of the object that contains the object being identified |
documentView | macOS | Used for scrollbars (NSScroller ): the symbolic name of the document view which the object being identified belongs to (i.e., the view it scrolls) |
firstItemText | Java | Holds the first text to be found for child SWT ToolItem objects. If no text is found, then the tooltip text is used. This property's value could be the empty string if no text is found and no tooltip text is set. |
firstTabCaption | Java | Holds the caption of the first CTabItem of a CTabFolder . This property's value could be the empty string if no text is found. |
isApplicationMenuItem | macOS | Used for menu items (NSMenuItem ): if this property is 1, then the menu item is the menu item in the menu bar that opens the application menu. For all other menu items, this property is 0. |
leftLabel | macOS, iPhone | The symbolic name of the label left of the object being identified |
leftObject | Windows | The symbolic name of the object to the left of the object being identified |
leftWidget | Java, Qt | The symbolic name of the widget to the left of the object being identified |
leftWidgetText | Qt | The text held by the widget to the left of the object being identified. Requires leftWidgetType to also be specified. |
leftWidgetType | Qt | The type of the widget to the left of the object being identified |
menuStyle | Java | Holds the style of SWT menu—this indicates whether the menu is a menu bar, a popup menu, or a pull-down menu. |
name | Qt | The object being identified's objectName |
occurrence | All | A number that uniquely identifies an object which would otherwise be identical to another object (due to having exactly the same property values) |
parentItem | macOS | The symbolic name of the object being identified's parent object |
rightLabel | macOS, iPhone | The symbolic name of the label right of the object being identified |
row | Java, Qt | The object being identified's row (if it is inside a multi-valued object such as a list, table, or tree) |
rowNumber | macOS | The object being identified's row (if it is inside a multi-valued object such as a list, table, or tree) |
tableView | macOS | The symbolic name of the NSTableView in which the object being identified belongs |
type | All | The name of the object being identified's type (or class). For most GUI toolkits this must always be present in a real (multi-property) name; however, it is not required for Squish for Windows or Squish for Web. |
unnamed | Qt | If the object being identified does not have an objectName , this property's value is "1" ; otherwise its value is "0" |
visible | Qt, iPhone, macOS, Windows | If the object being identified is logically visible (i.e., not completely obscured by one or more other AUT objects), this property's value is "1" ; otherwise its value is "0" . In tests for native Windows applications, this property assumes the value true or false . |
window | Java, Qt, macOS, iPhone | The symbolic name of the window that contains the object being identified |
windowName | Qt | The name (caption) of the window that contains the object being identified |
windowOccurrence | Qt | The occurrence number of the window that contains the object being identified |
windowType | Qt | The type of the window that contains the object being identified |
© 2024 The Qt Company Ltd.
Documentation contributions included herein are the copyrights of
their respective owners.
The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation.
Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property
of their respective owners.