module Tapestry::Element
Private Instance Methods
This method provides the means to get the aspects of an accessor signature. The “aspects” refer to the locator information and any qualifier information that was provided along with the locator. This is important because the qualifier is not used to locate an element but rather to put conditions on how the state of the element is checked as it is being looked for.
Note that “qualifiers” here refers to Watir
boolean methods.
# File lib/tapestry/element.rb, line 78 def accessor_aspects(element, *signature) identifier = signature.shift locator_args = {} qualifier_args = {} gather_aspects(identifier, element, locator_args, qualifier_args) [locator_args, qualifier_args] end
Returns the block or proc that serves as a context for an element definition. Consider the following element definitions:
ul :facts, id: 'fact-list' span :fact, -> { facts.span(class: 'site-item')}
Here the second element definition provides a proc that contains a context for another element definition. That leads to the following construction being sent to the browser:
@browser.ul(id: 'fact-list').span(class: 'site-item')
# File lib/tapestry/element.rb, line 61 def context_from_signature(*signature, &block) if block_given? block else context = signature.shift context.is_a?(Proc) && signature.empty? ? context : nil end end
Defines an accessor method for an element that allows the “friendly name” (identifier) of the element to be proxied to a Watir
element object that corresponds to the element type. When this identifier is referenced, it generates an accessor method for that element in the browser. Consider this element definition defined on a class with an instance of `page`:
text_field :username, id: 'username'
This allows:
page.username.set 'tester'
So any element identifier can be called as if it were a method on the interface (class) on which it is defined. Because the method is proxied to Watir
, you can use the full Watir
API by calling methods (like `set`, `click`, etc) on the element identifier.
It is also possible to have an element definition like this:
text_field :password
This would allow access like this:
page.username(id: 'username').set 'tester'
This approach would lead to the *values variable having an array like this: [{:id => 'username'}].
A third approach would be to utilize one element definition within the context of another. Consider the following element definitions:
article :practice, id: 'practice' a :page_link do |text| practice.a(text: text) end
This would allow access like this:
page.page_link('Drag and Drop').click
This approach would lead to the *values variable having an array like this: [“Drag and Drop”].
# File lib/tapestry/element.rb, line 172 def define_element_accessor(identifier, *signature, element, &block) locators, qualifiers = accessor_aspects(element, signature) define_method(identifier.to_s) do |*values| if block_given? instance_exec(*values, &block) else locators = values[0] if locators.empty? access_element(element, locators, qualifiers) end end end
This method is used to separate the two aspects of an accessor – the locators and the qualifiers. Part of this process involves querying the Watir
driver library to determine what qualifiers it handles natively. Consider the following:
select_list :accounts, id: 'accounts', selected: 'Select Option'
Given that, this method will return with the following:
locator_args: {:id=>"accounts"} qualifier_args: {:selected=>"Select Option"}
Consider this:
p :login_form, id: 'open', index: 0, visible: true
Given that, this method will return with the following:
locator_args: {:id=>"open", :index=>0, :visible=>true} qualifier_args: {}
Notice that the `visible` qualifier is part of the locator arguments as opposed to being a qualifier argument, like `selected` was in the previous example. This is because Watir
6.x handles the `visible` qualifier natively. “Handling natively” means that when a qualifier is part of the locator, Watir
knows how to intrpret the qualifier as a condition on the element, not as a way to locate the element.
# File lib/tapestry/element.rb, line 113 def gather_aspects(identifier, element, locator_args, qualifier_args) identifier.each_with_index do |hashes, index| next if hashes.nil? || hashes.is_a?(Proc) hashes.each do |k, v| methods = Watir.element_class_for(element).instance_methods if methods.include?(:"#{k}?") && !NATIVE_QUALIFIERS.include?(k) qualifier_args[k] = identifier[index][k] else locator_args[k] = v end end end [locator_args, qualifier_args] end
A “signature” consists of a full element definition. For example:
text_field :username, id: 'username'
The signature of this element definition is:
[:username, {:id=>"username"}]
This is the identifier of the element (`username`) and the locator provided for it. This method separates out the identifier and the locator.
# File lib/tapestry/element.rb, line 46 def parse_signature(signature) [signature.shift, signature.shift] end