Explicitly Naming Objects

Last edited on

Why Should I Explicitly Name Objects?

Squish identifies application objects by their most stable properties to make tests as robust and reliable as possible. However, as an application is developed and maintained, existing widgets get moved around and new widgets get added (both of which Squish can usually cope with), or in some cases, widgets get removed or changed in important ways (such as a button’s text being changed).

Clearly, if a test relies on a widget that’s been removed, the test will need to be updated. But for all other changes it would be best if existing tests would continue to run unchanged to minimize the burden on test engineers.

Unfortunately, in some situations, Squish isn’t able to identify AUT objects in as reliable a way as we would wish. For example, in some situations an object is identified in terms of its neighboring objects, which makes the identification vulnerable simply to widgets being moved around. Or in the case of Web applications, Squish identifies objects using the DOM path of the HTML tag that represents the object, and this might not always be reliable, depending on the HTML layout or the HTML application.

In order to avoid the less reliable ways by which some objects are identified and to make tests as robuts as possible, in some cases, Squish is able to identify objects by explicitly given names.

Ideally every explicitly named object should have a unique name; (although for some toolkits a unique name for any given type is sufficient). One possible way of creating such names is to make them a bit like a hierarchical path, for example, of the form “_ObjectName_Type__/ObjectNameType/…”, e.g., _“AddEdit_Dialog/User_TabPane/ForenameLineEdit”.

Large applications may have hundreds or thousands of objects, most if not all of which Squish can automatically and reliably identify. So, if explicit naming is necessary at all, it will be needed by only a small number of objects, i.e., those which change or are likely to change in ways that Squish cannot automatically adapt to, and for which the use of inexact property matching isn’t possible. (See Improving Object Identification, in particular the coverage of wildcards and regular expressions.)

Overview of Toolkit Object Naming Mechanisms

This table lists the GUI toolkits that Squish supports and whether they support direct object naming.

ToolkitMechanismNote
AndroidView.setContentDescription(CharSequence)
AWT/Swingjava.awt.Component.setName(String)
CocoaSet property identifier, userInterfaceItemIdentifier, accessiblityIdentifier, accessiblityTitle or accessibilityLabelAdditional name generation setup required
CocoaAlternative approach: Sub-class and add properties (i.e. let MyNSButton extend NSButton and add methods NSString MyNSButton.objectName() and MyNSButton.setObjectName(NSString))Additional name generation setup required
MFCMFC does not allow naming of objects, but allows to set an ID which might be usable
iOS (UIKit)Set property “accessibilityLabel”Additional name generator setup required
iOS (UIKit)Alternative approach: Sub-class and add properties (i.e. let MyUIButton extend UIButton and add methods NSString MyUIButton.objectName() and MyUIButton.setObjectName(NSString))Additional name generator setup required
JavaFXjavafx.scene.Node.setId for javafx.scene.Node.id
QtQObject.setObjectName(QString)
SWT/RCPorg.eclipse.swt.widgets.Widget.setData(Object)Additional name generator setup required
TkUnique name as required by Tk at object creation
WebArbitrarily named attribute in the desired HTML tagAdditional name generator setup required
Windows FormsSystem.Windows.Forms.Control.NameAdditional name generator setup required
WPF (Windows Presenation Foundation)System.Windows.FrameworkElement.NameAdditional name generator setup required

Explicitly Naming Objects in Android

For Android applications use the View.setContentDescription(CharSequence) method. This sets the “description” property of individual objects.

This must be done by the application developers.

Squish is smart enough to detect when an object has been explicitly named like this and automatically makes use of such names (as the description property), in addition to other properties.

Explicitly Naming Objects in AWT/Swing (Java)

For AWT/Swing (Java) applications use the java.awt.Component.setName(String) method.

This must be done by the application developers.

Squish is smart enough to detect when an object has been explicitly named like this and automatically makes use of such names (as the description property), in addition to other properties.

Explicitly Naming Objects in Cocoa (Mac OS X)

Solution #1: Set identifier/userInterfaceItemIdentifier

Cocoa offers properties specifically meant to be unique, identifier and userInterfaceItemIdentifier.

More details about “identifier” and “userInterfaceItemIdentifier” can be found at NSUserInterfaceItemIdentification Protocol Reference.

Configuring Squish to use the identifier property

Any object property can be used in a Squish real name. It is even possible to tell Squish which properties you want it to use for object identification: see the Object Name Generation section in the Reference Manual.

Here is the entry that from <SQUISH_DIR>/etc/macwrapper_descriptors.xml that must be changed:

<descriptor>
    <type name="NSObject"/>
    <realidentifiers>
        <group>
            <property>title</property>
            <property>label</property>
        </group>
    </realidentifiers>
    <symbolicidentifiers>
        <group>
            <property>title</property>
            <property>label</property>
            <property>toolTip</property>
        </group>
    </symbolicidentifiers>
</descriptor>
macwrapper_descriptors.xml

It should be changed to this to use these two properties for newly generated ⚠️ object names:

<descriptor>
    <type name="NSObject"/>
    <realidentifiers>
        <group>
            <property>title</property>
            <property>label</property>
        </group>
        <group>
            <property>userInterfaceItemIdentifier</property>
            <property>identifier</property>
            <property>accessibilityLabel</property>
            <property>accessibilityTitle</property>
            <property>accessibilityIdentifier</property>
        </group>
    </realidentifiers>
    <symbolicidentifiers>
        <group>
            <property>title</property>
            <property>label</property>
            <property>toolTip</property>
        </group>
    </symbolicidentifiers>
</descriptor>
macwrapper_descriptors.xml

Also see:

Solution #2: Adding custom properties

Sub-class the respective classes and add properties.

For example let MyNSButton extend NSButton and add the methods NSString MyNSButton.objectName() and MyNSButton.setObjectName(NSString)).

Squish should then be able to make the property “objectName” accessible.

To let Squish generate object names with this property some configuration changes are required for the name generator (see Object Name Generation.

Explicitly Naming Objects in MFC (Windows)

This is not possible because MFC has no mechanism to support the direct naming of objects. However, it may be possible to use the MFC ID functionality to assign unique IDs to the various controls and to let Squish generate object names that include these IDs.

To let Squish generate new object names with the property “id” the file "<SQUISH_DIR>/etc/windowswrapper_descriptors.xml" must be modified for each respective type of control. For example for buttons change the entry…

[...]

<descriptor>
    <type name="Button"/>
    <realidentifiers>
        <property>text</property>
    </realidentifiers>
</descriptor>

[...]
windowswrapper_descriptors.xml

…to…

[...]

<descriptor>
    <type name="Button"/>
    <realidentifiers>
        <property>id</property>
        <property>text</property>
    </realidentifiers>
</descriptor>

[...]
windowswrapper_descriptors.xml

…or…

[...]

<descriptor>
    <type name="Button"/>
    <realidentifiers>
        <group>
            <property>id</property>
            <property>text</property>
        </group>
    </realidentifiers>
</descriptor>

[...]
windowswrapper_descriptors.xml

(The latter uses “id” when available, otherwise “text”.)

Also see TN020: ID Naming and Numbering Conventions.

Explicitly Naming Objects in JavaFX (Java)

For JavaFX (Java) applications use the javafx.scene.Node.id property set by javafx.scene.Node.setId.

This must be done by the application developers.

Squish will automatically detect when an object has been explicitly named, since the default etc/javawrapper_descriptors.xml file already has this id property listed.

Explicitly Naming Objects in Qt

For Qt 5 applications based on QWidgets and Qt 4 applications use the QObject.setObjectName(QString) method. In Qt 3 applications use the QObject.setName(*char) method. For Qt 5 QtQuick applications the objectName property of a component can be set to a string value.

This must be done by the application developers.

Squish is smart enough to detect when an object has been explicitly named like this and automatically makes use of such names (as the objectName property), in addition to other properties.

Explicitly Naming Objects in iOS (UIKit)

For UIKit applications set the accessibilityLabel of the respective objects. (See UIAccessibility Protocol Reference.)

Any property of UIKit objects can be used in a Squish real name. It is even possible to tell Squish which properties you want it to use for object identification: see the Object Name Generation section in the Reference Manual.

In addition to setting the object’s accessibilityLabel Squish should be configured to consider the accessibilityLabel object property for use in real names. This can be done by, for example, changing the following entry in the file macwrapper_descriptors.xml or adding it to macwrapper_user_descriptors.xml:

<descriptor>
    <type name="UIView"/>
    <realidentifiers>
        <property>type</property>
    ...
</descriptor>

Let’s say we want Squish to use and actually favor accessibilityLabel over toolTip, then the entry could look like this:

<descriptor>
    <type name="UIView"/>
    <realidentifiers>
        <property>type</property>
        <group>
            <property>accessibilityLabel</property>
            <property>toolTip</property>
        </group>
        <group> <!-- container objects, most specific first-->
            <object>parentItem</object>
            <object>tableView</object>
            <object>container</object>
            <object>window</object>
        </group>
    </realidentifiers>
    <symbolicidentifiers>
    </symbolicidentifiers>
</descriptor>

Please note that this will only affect every object whose class is based on UIView.

Explicitly Naming Objects in SWT/RCP (Java)

For SWT/RCP (Java) applications use the org.eclipse.swt.widgets.Widget.setData(Object) method.

This must be done by the application developers.

Any Java property can be used in a Squish real name. It is even possible to tell Squish which properties you want it to use for object identification: see the Object Name Generation section in the Reference Manual.

In addition to setting object names via Widget.setData(Object) Squish should be configured to consider the data object property for use in real names. This can be done by adding an entry like the following to the file javawrapper_descriptors.xml or javawrapper_user_descriptors.xml:

<descriptor>
    <type name="org_eclipse_swt_widgets_Widget"/>
    <realidentifiers>
        <property>data</property>
    </realidentifiers>
</descriptor>

Note that this configures Squish to consider the data object property of all objects which extend org.eclipse.swt.widgets.Widget directly or indirectly, so it might be too broad for some use cases. For those just use a smaller scope as type, for example “org_eclipse_swt_widgets_ToolBar”.

Explicitly Naming Objects in Tk

In Tk it is mandatory to create objects with unique names, so this is enforced by the toolkit already.

Explicitly Naming Objects in Windows Forms (.NET, Windows)

For Windows Forms-based applications (.NET, Windows), use the System.Windows.Forms.Control.Name property.

This must be done by the application developers.

In addition, Squish’s name generator must be configured to use the “Name” property (available under the nativeObject property) in favor of the “text” property. This must be configured in <SQUISH_DIR>/etc/windowswrapper_descriptors.xml.

Here is an example entry. Change…

<descriptor>
    <type name="Button"/>
    <realidentifiers>
        <property>text</property>
    </realidentifiers>
</descriptor>
windowswrapper_descriptors.xml

…to…

<descriptor>
    <type name="Button"/>
    <realidentifiers>
        <group>
            <property>nativeObject.Name</property>
            <property>text</property>
        </group>
    </realidentifiers>
</descriptor>
windowswrapper_descriptors.xml

You can download a completely changed windowswrapper_descriptors.xml windowswrapper_descriptors.xml. (Note that this modified copy of the file may be outdated, so if in doubt, please manually add the above entries to your own copy of the windowswrapper_descriptors.xml file.)

Explicitly Naming Objects in WPF (Windows Presentation Foundation) (.NET, Windows)

For WPF-based applications (.NET, Windows), use the System.Windows.FrameworkElement.Name property.

This must be done by the application developers.

In addition, Squish’s name generator must be configured to use the “Name” property (available under the nativeObject property) in favor of the “text” property. This must be configured in <SQUISH_DIR>/etc/windowswrapper_descriptors.xml.

Here is an example entry. Change…

<descriptor>
    <type name="Button"/>
    <realidentifiers>
        <property>text</property>
    </realidentifiers>
</descriptor>
windowswrapper_descriptors.xml

…to…

<descriptor>
    <type name="Button"/>
    <realidentifiers>
        <group>
            <property>nativeObject.Name</property>
            <property>text</property>
        </group>
    </realidentifiers>
</descriptor>
windowswrapper_descriptors.xml

You can download a completely changed windowswrapper_descriptors.xml windowswrapper_descriptors.xml. (Note that this modified copy of the file may be outdated, so if in doubt, please manually add the above entries to your own copy of the windowswrapper_descriptors.xml file.)

Explicitly Naming Objects in Web pages

In Web pages you can simply add a new attribute to objects’ HTML tags.

This must be done by the application developers/web designers who are responsible for creating the application.

HTML tags can have an id attribute and this attribute’s value must be unique (within the page). So, for HTML pages that use stable (i.e., not programmatically generated) id attributes, this is a good property to use for object identification.

Related Information