Lapis Lazuli:Selecting an element

From Test Automation Wiki
Revision as of 13:55, 20 June 2016 by Gijsp (talk | contribs)
Jump to: navigation, search

Find() variants

The find module extends the Watir browser with some powerful functionality for making it easier to find elements on a web page.

There are four ways to find an element:

  1. browser.find finds a single element matching the specifications passed to it.
  2. browser.find_all finds all elements matching the specifications passed to it.
  3. browser.multi_find finds a single element matching one of multiple specifications passed to it. Specifications are handled in order and only the first match is returned.
  4. browser.multi_find_all finds all elements matching one of multiple specifications passed to it. Specifications are handled in order and only elements belonging to the first match are returned.

In addition, a helper function is exposed that allows you to pick an element from a collection (array) of elements.

Picking an Element

The pick_one helper function is easily explained in isolation, but it should be noted that it also underlies the find and multi_find functions:

browser.pick_one(:first, collection)  # returns the first item from the collection
browser.pick_one(:last, collection)   # returns the last item from the collection
browser.pick_one(:random, collection) # returns a random item from the collection
browser.pick_one(12, collection)      # returns the 12th item from the collection

You should not usually need to use this function directly, but instead use one of the find functions.

Find Function Syntax

All find functions accept much the same parameters; the general syntax is this:

browser.find(selector1)
browser.find(:some_option => value, :selectors => [selector1])

# browser.find_all same as browser.find

browser.multi_find(selector1, selector2, ...)
browser.multi_find(:some_option => value, :selectors => [selector1, selector2, ...])

# browser.multi_find_all same as browser.multi_find

This syntax affords the flexibility of providing options to the functions, without forcing you to provide any.

Find Options

The following options are interpreted by all find functions:

  • :selectors - a list of selectors by which to find elements. Implicit when no other options are provided (see above).
  • :pick - one of the possible first parameter values to the pick_one function. Note that for find and :multi_find, the default is to pick the first element found.
  • :mode - one of match_one or match_all - determines whether the multi find functions return after finding a single element matching any _one_ of the provided selectors, or only when _all_ selectors given match at least one element.
  • :filter_by - the expected value is a symbol that the element responds to, e.g. :present?. If provided, only present elements (in the example) will be matched.
  • :context - give a found element to search within.
  • :message - when failing, raise a custom message.

Selectors

Selectors can be the kind of selectors that would be passed to the Watir browser's functions, but LapisLazuli affors far greater flexibility here.

  1. If a selector is a string, e.g. "a", then elements with the symbol name are found, using Watir's built-in functions.
  2. If a selector is a symbol, e.g. :a, then elements with the symbol name are found, but using XPath instead.
  3. If a selector is a hash, it is considered to be a regular Watir selector, e.g. :id => /some-id/.
    1. If this hash contains a :like key, the value of this key is further interpreted before passing the entire hash on to Watir (see below).
    2. If this hash contains a :context key, the value of this key is expected to be a Watir element, and a search will be performed relative to this element. If the context is not provided, the search starts at the document root.

Like Selectors

Like selectors are shorthands for more complex XPath-based selection. A like selector is either of:

  1. A symbol, e.g. :a, in which case an XPath query is constructed for finding a elements.
  2. An array of three elements, in which case an XPath query is constructed with the following components:
    1. The first is interpreted as the element name (as above),
    2. The second is interpreted as an attribute to match, and
    3. The third is interpreted as an attribute value to match.

Note that like selectors **add** to a regular Watir selector. It's perfectly legitimate to use regular selectors and like selectors in combination, but the result may be unexpected.

Examples

# Find any link. same as browser.a
browser.find(:a)                      
browser.find({:like => :a}) # xpath


# same as browser.a(:href => /test/)
browser.find(:a => {:href => /test/})

# More complicated version:
browser.find(
  {:a => {:class => "loginButton"}}, 
  {:a => {:href => /login/}},
  {:button => {:name => "login"}}
)

# Find element where an attribute contains something. 
# Uses XPath instead of the slower regexes:
# browser.a(:href => /account\/login/)
browser.find(:like => {
    :element => :a, 
    :attribute => :href, 
    :include => "account/login"
})

# A shorthand
browser.find(:like => [:a, :href, "account/login"])

# Finding a single class is also possible if you add spaces around it
browser.find(:like => [:a, :class, " login "])

# And also support for XPath text
browser.find(:like => {
    :element => :a, 
    :attribute => :text, 
    :include => "Login"
})

# Finding based on name, id or text
browser.find("login")

# Finding an element within another element
form = browser.find("register_form")
firstname_field = browser.find(
    :input => {:name => 'firstname'},
    :context => form
)