When Squish records tests it uses object properties to uniquely identify each object. For each object that Squish identifies it creates an entry in the Object Map. Each entry is essentially a pair of names—a symbolic name (a unique string starting with a colon), and a real (multi-property) name (a braces enclosed space-separated list of property name–value pairs). When tests are run Squish reads the names in the test script as it encounters them and tries to match them to the corresponding application objects.
For properties that have normal values the matching is done on the string value. For properties that have object values (i.e., the value is the real name of another object), the matching is done using Squish's normal object lookup functionality.
Some properties can only be matched using exact matching, while others
can use exact, wildcard, or regex matching. Those properties that can
only use exact matching are the type property (on Squish
for Web this is the tagName property), the
basename property (on Squish for Java™), and any other
properties whose values are object values (i.e., the names of other
objects), e.g., the container and window
properties. 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.
![]() | Java-specific |
|---|---|
Since wildcard and regex matching are not supported for the
|
Starting with Squish 3.2, the syntax of multiple property (real) names has been enhanced to allow for more flexible matching of property values.
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 caption “UsefulApp v1.3 - July Sales.dat”:
{caption='UsefulApp v1.3 - July Sales.dat' type='MainWindow'}
This multiple property name will match the first object in the application which is of type MainWindow and whose caption 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 16.11) for more information on that topic). Unfortunately, since the caption's text is variable it is vulnerable to changes—for example, if we start testing the 1.4 version of the application or if we want to switch to testing a different data file. In either of these cases the caption text will change, and any existing tests that rely on it will now fail.
By default, Squish uses exact matching for property values using the
= (equality) operator. However, Squish also provides two
other matching operators, ?= (wildcard) and ~=
(regular expression, or “regex”).
If we wanted to make the MainWindow's real name more robust we could use the wildcard or the regex operator. Here is an example using the wildcard operator:
{caption?='UsefulApp*' type='MainWindow'}
We'll formally describe the wildcard syntax in a moment, but for now we
will just explain what the example means. This says that the 'caption'
property's text must begin with “UsefulApp” followed zero
or more other characters. (A * stands for zero or more of
any characters—so here we expect it to match, “ v1.3 - July
Sales.dat” or “ v1.4 - August Sales.dat” or similar.
Clearly this is a lot more robust than using the =
(equality) operator, although we do have to learn a few symbols
(actually, just ?, *, \,
[ and ]) to take advantage of this facility.
We could of course achieve the same thing using the regex operator, for example:
{caption~='UsefulApp.*' type='MainWindow'}
This regex match has exactly the same meaning as the wildcard match described above, although in general the regex syntax is much more complicated—and also more versatile—than the wildcard syntax.
The = (equality) operator is used for exact matches. This
kind of matching can be used in all situations, and is the only kind of
matching that is allowed for the type property 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={type='Label' text='Forename:'}}
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 a real name.
The ?= (wildcard) operator is used for inexact matches.
This kind of matching cannot be used for the type property
or for properties whose value is an object (i.e., is specified using a
real name).
When wildcard matching is in force the ?, *,
[, ], and \ characters all take
on special meanings and are not matched literally. All other characters
are matched literally, i.e., they stand for themselves.
Table 16.1. 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 an example:
{type='LineEdit' visible='1' buddy={type='Label' text?='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 a real name. But here the buddy's name 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 second example:
{caption?='UsefulApp v[1-9].[0-9] - ?*.[dD][aA][tT]' type='MainWindow'}
Here, the 'caption' property 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 ~= (regex) operator is used for inexact matches.
This kind of matching cannot be used for the type property
or for properties whose value is an object (i.e., is specified using a
real name). Regex matching allows us to write more
sophisticated—and potentially harder to understand and
maintain—matching expressions than can be achieved using wildcard
matching. In fact we recommend using wildcard matching where possible
simply because it is easier, both to read and write.
For 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.
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, all of an object's properties are potentially usable for
identifying it (e.g., using them in a real name in 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 17.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 17.2.1)); and pick the object of interest. Now all the object's non-artificial properties will be shown in the Properties view (Section 17.2.10). To find out the object's artificial properties, invoke the context menu on the object in the Application Objects view (Section 17.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 17.2.10) are artificial properties.
Table 16.2. Squish's Key Artificial Properties
| Property Name | Toolkits | Notes |
|---|---|---|
aboveLabel | Mac OS X, iPhone | The symbolic name of the label 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 |
aboveWidgetType | Qt | The type of the widget above the object being identified |
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 | Mac OS X | The object being identified's column (if it is inside a multi-valued object such as a table or tree) |
container | Qt, Mac OS X, iPhone | 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 | Mac OS X | Used for scrollbars (NSScroller): the
symbolic name of the document view which the object being identified
belongs to (i.e. the view it scrolls) |
leftLabel | Mac OS X, iPhone | The symbolic name of the label 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 |
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, Mac OS X, iPhone | A number that uniquely identifies an object which would otherwise be identical to another object (due to having exactly the same property values) |
parentItem | Mac OS X | The symbolic name of the object being identified's parent object |
rightLabel | Mac OS X, 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 | Mac OS X | The object being identified's row (if it is inside a multi-valued object such as a list, table, or tree) |
tableView | Mac OS X | 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 has an objectName this property's
value is "1"; otherwise its value is "0" |
visible | Qt | 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" |
window | Qt, Mac OS X, 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 |