Table of Contents
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™).
![]() | className in Squish for Web |
---|---|
Note that 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. |
One commonly encountered problem is that many applications change the
texts used by some widgets. For instance, a button's text might change
from 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 (Section 7.12) 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
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”.
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.
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.
Table 7.2. The Wildcard Special Characters
? | 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.
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.
![]() | Different Regular Expression Syntaxes |
---|---|
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 |
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
object's base class's properties (i.e., QObject
's
properties), also any object-type-specific properties that have been
added by the supplier or by the AUT (e.g., through subclassing), and
finally some artificial properties that are
especially 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 findObject
and waitForObject
functions). However, only the
non-artificial properties are suitable for use in verifications (e.g.,
in calls to the test.compare
function and
other test
module functions).
To find out what an object's non-artificial properties are, either 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 (Section 8.1.1.22)), then interact with the AUT until the relevant AUT object is visible. At this point context switch back to the Squish IDE and invoke the pick action (see the Application Objects view (Section 8.2.1)); and pick the object of interest. Now all the object's non-artificial properties will be shown in the Properties view (Section 8.2.12). To find out the object's artificial properties, invoke the context menu on the object in the Application Objects view (Section 8.2.1) and copy its real name to the clipboard: any properties in the real name that are not listed in the Properties view (Section 8.2.12) are artificial properties.
Table 7.3. Squish's Key Artificial Properties
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 | 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 |
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 |
column | 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 | 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) |
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 | 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 |
name | Qt | The object being identified's objectName |
occurrence | Qt, macOS, iPhone, Windows | 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 | 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, macOS, iPhone, 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 values true and
false . |
window | 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 |