Selenium offers several built-in locator strategies.
firstButton.getContainerElement().getDomElement().id = "firstButton";
These are custom locator strategies designed specifically for qooxdoo applications.
This strategy locates elements within the application's widget hierarchy by following relations between JavaScript objects. In order to achieve this, it uses a syntax that is very similar to XPath, but also differs in significant ways.
A qxh locator is a sequence of one or more location steps, separated by /. No leading or trailing / is allowed. All searches are anchored to the root object (which is either the Application object or the application root widget, see further down). During the search each location step selects an object which will be used as the root for the rest of the search. The following possibilities exist to specify a location step:
qxh=mytoolbar
qxh=qx.ui.form.Button
qxh=child[3]
qxh=[@label=".*Label$"]
As for the values, only string comparisons are possible, but you can specify a RegExp as value as the comparisons will be RegExp matches.
qxh=*/[@label="My Button"]
This will recursively search from the first level below the search root for an object with a label property that matches the string “My Button”. As you might expect, these recursive searches take more time than other searches, so it is good advice to be as specific in your locator as possible. To that end, you can use mutliple wildcards in the same locator, like
qxh=*/[@label="Section 3"]/[@page]/*/[@label="First Button"]
This will search recursively from the root for an object with label “Section 3” and then, assuming it is a ButtonView which has a page property, navigate to the corresponding page, where it again searches recursively for an item with label “First Button”. This is much more effective than searching the entire object space with “*/[@label=“First Button”]”.
As with all Selenium locators, there are no set-valued results (as with generic XPath), and each locator has to come up with at most one result element. Therefore, for each location step, the first match wins, i.e. if there are multiple children that match the current specification, the first child is taken as the root for the rest of the search. Backtracking is only done for wildcard (*) searches.
The qxhv= locator works just like qxh=, except that for each step, only qooxdoo widgets with the "visibility" property set to "visible" are considered. This means that no descendants of invisible container widgets will be found. In some cases, this can lead to unexpected results. For example, in many qooxdoo applications, the root folder of a qx.ui.tree.Tree is set to be invisible. In that case, the qxhv locator would never find the root node's descendants, even though they are visible in the GUI.
The qxidv= locator searches for an HTML element with the given ID and looks at the qooxdoo widget it belongs to. Only if the widget is visible is the element returned, otherwise the locator will fail.
The qxhybrid= locator allows you to combine different locator strategies. It consists of multiple sub-locators separated by double ampersands (&&), each of which is applied to the DOM element returned by the previous locator. The first sub-locator can be of any supported type (qx* or any of Selenium's built-in locator types) while the following steps can be either qx* or XPath locators.
The primary use case for this strategy is testing applications where HTML IDs have been assigned to container widgets but not to child widgets such as e.g. list items (that may be generated during the application's runtime).
An example: Suppose an application contains a list widget (qx.ui.form.List) with the HTML ID "options". This is easy to find using Selenium's default ID locator:
options
Now in order to find a list item which has the label text "Foo", the following hybrid locator could be used:
qxhybrid=options&&qxh=[@label=Foo]