Visual Relationships for Selection of GuiElements

Arjuna supports specifying visual relationships with other GuiElements.

This feature is built on top of Selenium’s relative locators but is extended to provide much more powerful way of using it as compared to directly using Selenium.

Visual relationships act as selection-time filters. Depending on usage (coded vs GNS, direct vs nested locating) the relationship is specified with respect to a:
  • GuiElement

  • GuiPartialElement

  • GuiWidgetDefinition

  • GNS Label

Types of Visual Relationships

The visual relationships supported by Arjuna are:

below

Specifies that GuiWidget to be found is below a given GuiWidget.

above

Specifies that GuiWidget to be found is above a given GuiWidget.

right_of

Specifies that GuiWidget to be found is to the right of a given GuiWidget.

left_of

Specifies that GuiWidget to be found is to the left of a given GuiWidget.

near

Specifies that GuiWidget to be found is near (atmost 50px) a given GuiWidget.

Basic Usage of Visual Relationships

Coded

All relationships in code are provided as a keyword argument in the locator calls of a Gui.

The object can be a GuiElement or GuiWidgetDefinition.

Following is an example of locating a submit button to the right of remember me checkbox. Other relations can be used in the same manner:

# right_of with GuiElement as its value
app.element(classes="button", right_of=app.element(id="rememberme"))

# right_of with widget (GuiWidgetDefinition) as its value
app.element(classes="button", right_of=widget(id="rememberme"))

GNS

You can also use visual relationships in GNS files. The relationship can be provided with another label in the same GNS file.

Following is an example of locating a submit button to the right of remember me checkbox. Other relations can be used in the same manner:

remember_cbox:
    id: rememberme

submit_btn:
    classes: button
    right_of: remember_cbox

Now you can use this in code as usual:

app.gns.submit_btn

Specifying Multiple Visual Relationships

You can specify multiple visual relationships together.

Following coded and GNS examples locate Publish date link which is in Date Column (below Date heading) and for the row cell containing “Test1” (to right of this entry in the same row).

Coded

test1 = app.element(link="Test1")
date_col = app.element(id="date")
test1_date = app.element(classes="column-date", right_of=test1, below=date_col)

GNS

test1:
    link: Test1

date_col:
    id: date

test1_date:
    classes: column-date
    right_of: test1
    below: date_col

Now you can use this in code as usual:

app.gns.test1_date

Visual Relationships and Alternative Locators (OR Relationship)

Arjuna supports Alternative Locators - Specifying Multiple Locators with OR Relationship.

When multiple locators are specified and you also provide one or more visual relationships, then these relationships are used for EACH one of the alternative locators provided.

In the following coded and GNS example, Arjuna will attempt to locate the GuiElement in following sequence:
  • name = choice1, above = pass_label

  • id = choice2, above = pass_label

  • tags = input, above = pass_label

Coded

pass_label = app.element(attr=attr(name="plabel"))
e = app.element(name="choice1", id="choice2", tags="input", above=pass_label)

GNS

pass_label:
    name: plabel

submit_btn:
    name: choice1
    id: choice2
    tags: input
    above: pass_label

Visual Relationships in a Nested GuiWidget Finding Context

Arjuna wraps Selenium’s relative locator feature. Selenium converts such usage to a JavaScript call which can be executed only at WebDriver level and not WebElement level. Because of this, Selenium currently throws an exception which relates to JSON serialization of RelativeBy object, but in simple words, means that it is not supported.

Arjuna has some contexts, where nested element finding is enforced on all elements depending on a specification. For example, if you define a root element for a GuiSection GNS file or specify the same in its constructor, all GuiWidgets in this GuiSection are found in a nested manner. Hence, default Selenium behavior will disrupt the model.

Arjuna follows a fallback approach to this problem. When Visual Relationships are used in a nested element finding context, the finding logic uses GuiAutomator and not GuiWidget for finding. In simple words, rather than nested element finding in this case, Arjuna will resort to finding the GuiWidget from the root of HTML page.

Which Locators are Supported for Visual Relationships?

Currently Selenium supports relative locators only when the By type is a Tag name. This is an artificial limit imposed by the way Selenium’s relative_by module is structured.

Arjuna gets rid of this artificial limit and supports ALL Arjuna built-in as well as locator extensions created by you in withx.yaml or withx sections, except the following few cases:
  • js locator

  • point locator

  • Any withx extensions built on top of js and point locators.