2016-03-07 19:52:19 -05:00
# frozen_string_literal: true
2016-08-18 16:27:35 -04:00
require 'capybara/selector/selector'
2016-04-27 01:44:48 -04:00
Capybara :: Selector :: FilterSet . add ( :_field ) do
2016-08-29 14:40:53 -04:00
filter ( :checked , :boolean ) { | node , value | not ( value ^ node . checked? ) }
filter ( :unchecked , :boolean ) { | node , value | ( value ^ node . checked? ) }
filter ( :disabled , :boolean , default : false , skip_if : :all ) { | node , value | not ( value ^ node . disabled? ) }
filter ( :multiple , :boolean ) { | node , value | ! ( value ^ node . multiple? ) }
2016-04-27 01:44:48 -04:00
2016-10-05 18:16:00 -04:00
expression_filter ( :name ) { | xpath , val | xpath [ XPath . attr ( :name ) . equals ( val ) ] }
expression_filter ( :placeholder ) { | xpath , val | xpath [ XPath . attr ( :placeholder ) . equals ( val ) ] }
2016-04-27 01:44:48 -04:00
describe do | options |
desc , states = String . new , [ ]
2017-01-26 19:10:51 -05:00
states << 'checked' if options [ :checked ] || ( options [ :unchecked ] == false )
states << 'not checked' if options [ :unchecked ] || ( options [ :checked ] == false )
2016-04-27 01:44:48 -04:00
states << 'disabled' if options [ :disabled ] == true
desc << " that is #{ states . join ( ' and ' ) } " unless states . empty?
desc << " with the multiple attribute " if options [ :multiple ] == true
2017-01-26 19:10:51 -05:00
desc << " without the multiple attribute " if options [ :multiple ] == false
2016-04-27 01:44:48 -04:00
desc
end
end
2016-09-09 19:44:32 -04:00
##
#
# Select elements by XPath expression
2016-09-08 14:01:22 -04:00
#
# @locator An XPath expression
#
2016-08-18 16:27:35 -04:00
Capybara . add_selector ( :xpath ) do
xpath { | xpath | xpath }
end
2016-09-09 19:44:32 -04:00
##
#
# Select elements by CSS selector
2016-09-08 14:01:22 -04:00
#
# @locator A CSS selector
#
2016-08-18 16:27:35 -04:00
Capybara . add_selector ( :css ) do
css { | css | css }
end
2016-09-09 19:44:32 -04:00
##
#
# Select element by id
2016-09-08 14:01:22 -04:00
#
# @locator The id of the element to match
#
2016-08-18 16:27:35 -04:00
Capybara . add_selector ( :id ) do
xpath { | id | XPath . descendant [ XPath . attr ( :id ) == id . to_s ] }
end
2016-09-19 17:47:41 -04:00
2016-09-09 19:44:32 -04:00
##
#
# Select field elements (input [not of type submit, image, or hidden], textarea, select)
2016-09-08 14:01:22 -04:00
#
# @locator Matches against the id, name, or placeholder
# @filter [String] :id Matches the id attribute
# @filter [String] :name Matches the name attribute
# @filter [String] :placeholder Matches the placeholder attribute
# @filter [String] :type Matches the type attribute of the field or element type for 'textarea' and 'select'
# @filter [Boolean] :readonly
# @filter [String] :with Matches the current value of the field
# @filter [String, Array<String>] :class Matches the class(es) provided
# @filter [Boolean] :checked Match checked fields?
# @filter [Boolean] :unchecked Match unchecked fields?
# @filter [Boolean] :disabled Match disabled field?
# @filter [Boolean] :multiple Match fields that accept multiple values
2011-08-26 22:16:15 -04:00
Capybara . add_selector ( :field ) do
2016-10-05 18:16:00 -04:00
xpath do | locator , options |
2016-03-24 14:18:12 -04:00
xpath = XPath . descendant ( :input , :textarea , :select ) [ ~ XPath . attr ( :type ) . one_of ( 'submit' , 'image' , 'hidden' ) ]
2016-10-05 18:16:00 -04:00
locate_field ( xpath , locator , options )
end
expression_filter ( :type ) do | expr , type |
type = type . to_s
if [ 'textarea' , 'select' ] . include? ( type )
expr . axis ( :self , type . to_sym )
else
expr [ XPath . attr ( :type ) . equals ( type ) ]
2016-08-18 16:27:35 -04:00
end
2016-03-24 14:18:12 -04:00
end
2016-04-26 11:51:22 -04:00
2016-10-05 18:16:00 -04:00
filter_set ( :_field ) # checked/unchecked/disabled/multiple/name/placeholder
2016-04-26 11:51:22 -04:00
2016-08-29 14:40:53 -04:00
filter ( :readonly , :boolean ) { | node , value | not ( value ^ node . readonly? ) }
2016-07-28 04:25:24 -04:00
filter ( :with ) do | node , with |
with . is_a? ( Regexp ) ? node . value =~ with : node . value == with . to_s
end
2014-07-02 14:17:53 -04:00
describe do | options |
2016-08-18 16:27:35 -04:00
desc = String . new
2016-10-05 18:16:00 -04:00
( expression_filters . keys - [ :type ] ) . each { | ef | desc << " with #{ ef } #{ options [ ef ] } " if options . has_key? ( ef ) }
2014-07-02 14:17:53 -04:00
desc << " of type #{ options [ :type ] . inspect } " if options [ :type ]
desc << " with value #{ options [ :with ] . to_s . inspect } " if options . has_key? ( :with )
desc
end
2011-08-26 22:16:15 -04:00
end
2016-09-09 19:44:32 -04:00
##
#
# Select fieldset elements
2016-09-08 14:01:22 -04:00
#
# @locator Matches id or contents of wrapped legend
#
# @filter [String] :id Matches id attribute
# @filter [String] :legend Matches contents of wrapped legend
# @filter [String, Array<String>] :class Matches the class(es) provided
#
2011-08-27 17:57:12 -04:00
Capybara . add_selector ( :fieldset ) do
2016-09-22 19:55:54 -04:00
xpath ( :legend ) do | locator , options |
2016-03-24 14:18:12 -04:00
xpath = XPath . descendant ( :fieldset )
2017-05-30 18:51:15 -04:00
xpath = xpath [ XPath . attr ( :id ) . equals ( locator . to_s ) . or XPath . child ( :legend ) [ XPath . string . n . is ( locator . to_s ) ] ] unless locator . nil?
2016-08-18 16:27:35 -04:00
xpath = xpath [ XPath . child ( :legend ) [ XPath . string . n . is ( options [ :legend ] ) ] ] if options [ :legend ]
2016-03-24 14:18:12 -04:00
xpath
end
2011-08-26 22:16:15 -04:00
end
2016-09-09 19:44:32 -04:00
##
#
# Find links ( <a> elements with an href attribute )
2016-09-08 14:01:22 -04:00
#
# @locator Matches the id or title attributes, or the string content of the link, or the alt attribute of a contained img element
#
# @filter [String] :id Matches the id attribute
# @filter [String] :title Matches the title attribute
# @filter [String] :alt Matches the alt attribute of a contained img element
# @filter [String] :class Matches the class(es) provided
2016-12-15 13:59:01 -05:00
# @filter [String, Regexp,nil] :href Matches the normalized href of the link, if nil will find <a> elements with no href attribute
2016-09-08 14:01:22 -04:00
#
2011-08-26 22:16:15 -04:00
Capybara . add_selector ( :link ) do
2016-09-22 19:55:54 -04:00
xpath ( :title , :alt ) do | locator , options = { } |
2016-12-15 13:59:01 -05:00
xpath = XPath . descendant ( :a )
xpath = if options . fetch ( :href , true ) . nil?
xpath [ ~ XPath . attr ( :href ) ]
else
xpath [ XPath . attr ( :href ) ]
end
2016-03-24 14:18:12 -04:00
unless locator . nil?
locator = locator . to_s
2017-05-30 18:51:15 -04:00
matchers = XPath . attr ( :id ) . equals ( locator ) . or (
XPath . string . n . is ( locator ) ) . or (
XPath . attr ( :title ) . is ( locator ) ) . or (
XPath . descendant ( :img ) [ XPath . attr ( :alt ) . is ( locator ) ] )
matchers = matchers . or XPath . attr ( :'aria-label' ) . is ( locator ) if options [ :enable_aria_label ]
2016-08-03 16:16:30 -04:00
xpath = xpath [ matchers ]
2016-03-24 14:18:12 -04:00
end
2016-09-22 19:55:54 -04:00
xpath = [ :title ] . inject ( xpath ) { | memo , ef | memo [ find_by_attr ( ef , options [ ef ] ) ] }
2016-08-18 16:27:35 -04:00
xpath = xpath [ XPath . descendant ( :img ) [ XPath . attr ( :alt ) . equals ( options [ :alt ] ) ] ] if options [ :alt ]
2016-03-24 14:18:12 -04:00
xpath
end
2015-08-25 17:25:42 -04:00
filter ( :href ) do | node , href |
2016-12-15 13:59:01 -05:00
case href
when nil
true
when Regexp
2015-04-27 20:33:39 -04:00
node [ :href ] . match href
else
node . first ( :xpath , XPath . axis ( :self ) [ XPath . attr ( :href ) . equals ( href . to_s ) ] , minimum : 0 )
end
2012-01-03 03:43:11 -05:00
end
2016-03-24 14:18:12 -04:00
2016-12-15 13:59:01 -05:00
describe do | options |
desc = String . new ( )
desc << " with href #{ options [ :href ] . inspect } " if options [ :href ]
desc << " with no href attribute " if options . fetch ( :href , true ) . nil?
end
2011-08-26 22:16:15 -04:00
end
2016-09-09 19:44:32 -04:00
##
#
# Find buttons ( input [of type submit, reset, image, button] or button elements )
#
2016-09-29 23:23:05 -04:00
# @locator Matches the id, value, or title attributes, string content of a button, or the alt attribute of an image type button or of a descendant image of a button
2016-09-19 17:47:41 -04:00
#
# @filter [String] :id Matches the id attribute
# @filter [String] :title Matches the title attribute
# @filter [String] :class Matches the class(es) provided
# @filter [String] :value Matches the value of an input button
#
2011-08-26 22:16:15 -04:00
Capybara . add_selector ( :button ) do
2016-09-22 19:55:54 -04:00
xpath ( :value , :title ) do | locator , options = { } |
2016-03-24 14:18:12 -04:00
input_btn_xpath = XPath . descendant ( :input ) [ XPath . attr ( :type ) . one_of ( 'submit' , 'reset' , 'image' , 'button' ) ]
btn_xpath = XPath . descendant ( :button )
image_btn_xpath = XPath . descendant ( :input ) [ XPath . attr ( :type ) . equals ( 'image' ) ]
unless locator . nil?
locator = locator . to_s
2017-05-30 18:51:15 -04:00
locator_matches = XPath . attr ( :id ) . equals ( locator ) . or XPath . attr ( :value ) . is ( locator ) . or XPath . attr ( :title ) . is ( locator )
locator_matches = locator_matches . or XPath . attr ( :'aria-label' ) . is ( locator ) if options [ :enable_aria_label ]
2016-08-03 16:16:30 -04:00
input_btn_xpath = input_btn_xpath [ locator_matches ]
2017-05-30 18:51:15 -04:00
btn_xpath = btn_xpath [ locator_matches . or XPath . string . n . is ( locator ) . or XPath . descendant ( :img ) [ XPath . attr ( :alt ) . is ( locator ) ] ]
2016-08-03 16:16:30 -04:00
alt_matches = XPath . attr ( :alt ) . is ( locator )
2017-05-30 18:51:15 -04:00
alt_matches = alt_matches . or XPath . attr ( :'aria-label' ) . is ( locator ) if options [ :enable_aria_label ]
2016-08-03 16:16:30 -04:00
image_btn_xpath = image_btn_xpath [ alt_matches ]
2016-03-24 14:18:12 -04:00
end
2017-05-30 18:51:15 -04:00
res_xpath = input_btn_xpath . union ( btn_xpath ) . union ( image_btn_xpath )
2016-08-18 16:27:35 -04:00
2016-10-05 18:16:00 -04:00
res_xpath = expression_filters . keys . inject ( res_xpath ) { | memo , ef | memo [ find_by_attr ( ef , options [ ef ] ) ] }
2016-08-18 16:27:35 -04:00
res_xpath
2016-03-24 14:18:12 -04:00
end
2016-08-29 14:40:53 -04:00
filter ( :disabled , :boolean , default : false , skip_if : :all ) { | node , value | not ( value ^ node . disabled? ) }
2016-03-24 14:18:12 -04:00
2016-08-18 16:27:35 -04:00
describe do | options |
desc = String . new
desc << " that is disabled " if options [ :disabled ] == true
2016-11-21 19:28:45 -05:00
desc << describe_all_expression_filters ( options )
2016-08-18 16:27:35 -04:00
desc
end
2011-08-26 22:16:15 -04:00
end
2016-09-09 19:44:32 -04:00
##
#
# Find links or buttons
#
2016-03-24 14:18:12 -04:00
Capybara . add_selector ( :link_or_button ) do
label " link or button "
2016-08-18 16:27:35 -04:00
xpath do | locator , options |
2017-05-30 18:51:15 -04:00
self . class . all . values_at ( :link , :button ) . map { | selector | selector . xpath . call ( locator , options ) } . reduce ( :union )
2016-03-24 14:18:12 -04:00
end
2016-08-29 14:40:53 -04:00
filter ( :disabled , :boolean , default : false , skip_if : :all ) { | node , value | node . tag_name == " a " or not ( value ^ node . disabled? ) }
2016-03-24 14:18:12 -04:00
describe { | options | " that is disabled " if options [ :disabled ] }
end
2016-09-09 19:44:32 -04:00
##
#
# Find text fillable fields ( textarea, input [not of type submit, image, radio, checkbox, hidden, file] )
#
2016-09-19 17:47:41 -04:00
# @locator Matches against the id, name, or placeholder
# @filter [String] :id Matches the id attribute
# @filter [String] :name Matches the name attribute
# @filter [String] :placeholder Matches the placeholder attribute
# @filter [String] :with Matches the current value of the field
2017-04-24 21:50:14 -04:00
# @filter [String] :type Matches the type attribute of the field or element type for 'textarea'
2016-09-19 17:47:41 -04:00
# @filter [String, Array<String>] :class Matches the class(es) provided
# @filter [Boolean] :disabled Match disabled field?
# @filter [Boolean] :multiple Match fields that accept multiple values
#
2011-08-26 22:16:15 -04:00
Capybara . add_selector ( :fillable_field ) do
2012-06-08 11:07:12 -04:00
label " field "
2016-10-05 18:16:00 -04:00
xpath do | locator , options |
2016-03-24 14:18:12 -04:00
xpath = XPath . descendant ( :input , :textarea ) [ ~ XPath . attr ( :type ) . one_of ( 'submit' , 'image' , 'radio' , 'checkbox' , 'hidden' , 'file' ) ]
2016-08-18 16:27:35 -04:00
locate_field ( xpath , locator , options )
2016-03-24 14:18:12 -04:00
end
2016-10-05 18:16:00 -04:00
expression_filter ( :type ) do | expr , type |
type = type . to_s
if [ 'textarea' ] . include? ( type )
expr . axis ( :self , type . to_sym )
else
expr [ XPath . attr ( :type ) . equals ( type ) ]
end
end
filter_set ( :_field , [ :disabled , :multiple , :name , :placeholder ] )
2016-08-18 16:27:35 -04:00
2016-09-19 17:47:41 -04:00
filter ( :with ) do | node , with |
with . is_a? ( Regexp ) ? node . value =~ with : node . value == with . to_s
end
2016-08-18 16:27:35 -04:00
describe do | options |
desc = String . new
2016-11-21 19:28:45 -05:00
desc << describe_all_expression_filters ( options )
2016-09-19 17:47:41 -04:00
desc << " with value #{ options [ :with ] . to_s . inspect } " if options . has_key? ( :with )
2016-08-18 16:27:35 -04:00
desc
end
2011-08-26 22:16:15 -04:00
end
2016-09-09 19:44:32 -04:00
##
#
# Find radio buttons
#
2016-09-19 17:47:41 -04:00
# @locator Match id, name, or associated label text
# @filter [String] :id Matches the id attribute
# @filter [String] :name Matches the name attribute
# @filter [String, Array<String>] :class Matches the class(es) provided
# @filter [Boolean] :checked Match checked fields?
# @filter [Boolean] :unchecked Match unchecked fields?
# @filter [Boolean] :disabled Match disabled field?
# @filter [String] :option Match the value
#
2011-08-26 22:16:15 -04:00
Capybara . add_selector ( :radio_button ) do
2012-06-08 11:07:12 -04:00
label " radio button "
2016-10-05 18:16:00 -04:00
xpath do | locator , options |
2016-03-24 14:18:12 -04:00
xpath = XPath . descendant ( :input ) [ XPath . attr ( :type ) . equals ( 'radio' ) ]
2016-08-18 16:27:35 -04:00
locate_field ( xpath , locator , options )
2016-03-24 14:18:12 -04:00
end
2016-10-05 18:16:00 -04:00
filter_set ( :_field , [ :checked , :unchecked , :disabled , :name ] )
2016-04-26 11:51:22 -04:00
2013-10-20 13:59:07 -04:00
filter ( :option ) { | node , value | node . value == value . to_s }
2016-03-24 14:18:12 -04:00
2014-07-02 14:17:53 -04:00
describe do | options |
2016-04-27 01:44:48 -04:00
desc = String . new
2014-07-02 14:17:53 -04:00
desc << " with value #{ options [ :option ] . inspect } " if options [ :option ]
2016-11-21 19:28:45 -05:00
desc << describe_all_expression_filters ( options )
2014-07-02 14:17:53 -04:00
desc
end
2011-08-26 22:16:15 -04:00
end
2016-09-09 19:44:32 -04:00
##
#
# Find checkboxes
#
2016-09-19 17:47:41 -04:00
# @locator Match id, name, or associated label text
# @filter [String] :id Matches the id attribute
# @filter [String] :name Matches the name attribute
# @filter [String, Array<String>] :class Matches the class(es) provided
# @filter [Boolean] :checked Match checked fields?
# @filter [Boolean] :unchecked Match unchecked fields?
# @filter [Boolean] :disabled Match disabled field?
# @filter [String] :option Match the value
#
2011-08-26 22:16:15 -04:00
Capybara . add_selector ( :checkbox ) do
2016-10-05 18:16:00 -04:00
xpath do | locator , options |
2016-03-24 14:18:12 -04:00
xpath = XPath . descendant ( :input ) [ XPath . attr ( :type ) . equals ( 'checkbox' ) ]
2016-08-18 16:27:35 -04:00
locate_field ( xpath , locator , options )
2016-03-24 14:18:12 -04:00
end
2016-10-05 18:16:00 -04:00
filter_set ( :_field , [ :checked , :unchecked , :disabled , :name ] )
2016-04-26 11:51:22 -04:00
2013-10-20 13:59:07 -04:00
filter ( :option ) { | node , value | node . value == value . to_s }
2016-03-24 14:18:12 -04:00
2014-07-02 14:17:53 -04:00
describe do | options |
2016-04-27 01:44:48 -04:00
desc = String . new
2014-07-02 14:17:53 -04:00
desc << " with value #{ options [ :option ] . inspect } " if options [ :option ]
2016-11-21 19:28:45 -05:00
desc << describe_all_expression_filters ( options )
2014-07-02 14:17:53 -04:00
desc
end
2011-08-26 22:16:15 -04:00
end
2016-09-09 19:44:32 -04:00
##
#
# Find select elements
#
2016-09-19 17:47:41 -04:00
# @locator Match id, name, placeholder, or associated label text
# @filter [String] :id Matches the id attribute
# @filter [String] :name Matches the name attribute
# @filter [String] :placeholder Matches the placeholder attribute
# @filter [String, Array<String>] :class Matches the class(es) provided
# @filter [Boolean] :disabled Match disabled field?
# @filter [Boolean] :multiple Match fields that accept multiple values
# @filter [Array<String>] :options Exact match options
# @filter [Array<String>] :with_options Partial match options
# @filter [String, Array<String>] :selected Match the selection(s)
2017-06-04 09:51:29 -04:00
# @filter [String, Array<String>] :with_selected Partial match the selection(s)
2016-09-19 17:47:41 -04:00
#
2011-08-26 22:16:15 -04:00
Capybara . add_selector ( :select ) do
2012-06-08 11:07:12 -04:00
label " select box "
2016-10-05 18:16:00 -04:00
xpath do | locator , options |
2016-03-24 14:18:12 -04:00
xpath = XPath . descendant ( :select )
2016-08-18 16:27:35 -04:00
locate_field ( xpath , locator , options )
2016-03-24 14:18:12 -04:00
end
2016-10-05 18:16:00 -04:00
filter_set ( :_field , [ :disabled , :multiple , :name , :placeholder ] )
2016-04-26 11:51:22 -04:00
2012-03-15 23:14:47 -04:00
filter ( :options ) do | node , options |
2015-10-06 16:42:45 -04:00
if node . visible?
actual = node . all ( :xpath , './/option' ) . map { | option | option . text }
else
actual = node . all ( :xpath , './/option' , visible : false ) . map { | option | option . text ( :all ) }
end
2012-03-15 23:14:47 -04:00
options . sort == actual . sort
end
2016-10-06 21:04:14 -04:00
2015-10-06 16:42:45 -04:00
filter ( :with_options ) do | node , options |
finder_settings = { minimum : 0 }
if ! node . visible?
finder_settings [ :visible ] = false
end
options . all? { | option | node . first ( :option , option , finder_settings ) }
end
2016-10-06 21:04:14 -04:00
2012-01-02 11:12:21 -05:00
filter ( :selected ) do | node , selected |
2017-06-04 09:51:29 -04:00
actual = node . all ( :xpath , './/option' , visible : false ) . select ( & :selected? ) . map { | option | option . text ( :all ) }
Array ( selected ) . sort == actual . sort
end
filter ( :with_selected ) do | node , selected |
actual = node . all ( :xpath , './/option' , visible : false ) . select ( & :selected? ) . map { | option | option . text ( :all ) }
( Array ( selected ) - actual ) . empty?
2012-01-02 11:12:21 -05:00
end
2016-03-24 14:18:12 -04:00
2014-07-02 14:17:53 -04:00
describe do | options |
2016-03-01 16:53:19 -05:00
desc = String . new
2014-07-02 14:17:53 -04:00
desc << " with options #{ options [ :options ] . inspect } " if options [ :options ]
desc << " with at least options #{ options [ :with_options ] . inspect } " if options [ :with_options ]
desc << " with #{ options [ :selected ] . inspect } selected " if options [ :selected ]
2017-06-04 09:51:29 -04:00
desc << " with at least #{ options [ :with_selected ] . inspect } selected " if options [ :with_selected ]
2016-11-21 19:28:45 -05:00
desc << describe_all_expression_filters ( options )
2014-07-02 14:17:53 -04:00
desc
end
2011-08-26 22:16:15 -04:00
end
2016-09-09 19:44:32 -04:00
##
#
# Find option elements
#
2016-09-19 17:47:41 -04:00
# @locator Match text of option
# @filter [Boolean] :disabled Match disabled option
# @filter [Boolean] :selected Match selected option
#
2011-08-26 22:16:15 -04:00
Capybara . add_selector ( :option ) do
2016-03-24 14:18:12 -04:00
xpath do | locator |
xpath = XPath . descendant ( :option )
xpath = xpath [ XPath . string . n . is ( locator . to_s ) ] unless locator . nil?
xpath
end
2016-03-24 17:50:42 -04:00
2016-08-29 14:40:53 -04:00
filter ( :disabled , :boolean ) { | node , value | not ( value ^ node . disabled? ) }
filter ( :selected , :boolean ) { | node , value | not ( value ^ node . selected? ) }
2016-03-24 17:50:42 -04:00
describe do | options |
desc = String . new
desc << " that is #{ ' not' unless options [ :disabled ] } disabled " if options . has_key? ( :disabled )
desc << " that is #{ ' not' unless options [ :selected ] } selected " if options . has_key? ( :selected )
desc
end
2011-08-26 22:16:15 -04:00
end
2016-09-09 19:44:32 -04:00
##
#
# Find file input elements
#
2016-09-19 17:47:41 -04:00
# @locator Match id, name, or associated label text
# @filter [String] :id Matches the id attribute
# @filter [String] :name Matches the name attribute
# @filter [String, Array<String>] :class Matches the class(es) provided
# @filter [Boolean] :disabled Match disabled field?
# @filter [Boolean] :multiple Match field that accepts multiple values
#
2011-08-26 22:16:15 -04:00
Capybara . add_selector ( :file_field ) do
2012-06-08 11:07:12 -04:00
label " file field "
2016-10-05 18:16:00 -04:00
xpath do | locator , options |
2016-03-24 14:18:12 -04:00
xpath = XPath . descendant ( :input ) [ XPath . attr ( :type ) . equals ( 'file' ) ]
2016-08-18 16:27:35 -04:00
locate_field ( xpath , locator , options )
2016-03-24 14:18:12 -04:00
end
2016-10-05 18:16:00 -04:00
filter_set ( :_field , [ :disabled , :multiple , :name ] )
2016-08-18 16:27:35 -04:00
describe do | options |
desc = String . new
2016-11-21 19:28:45 -05:00
desc << describe_all_expression_filters ( options )
2016-08-18 16:27:35 -04:00
desc
end
2011-08-26 22:16:15 -04:00
end
2011-08-27 17:54:55 -04:00
2016-09-09 19:44:32 -04:00
##
#
# Find label elements
#
2016-09-19 17:47:41 -04:00
# @locator Match id or text contents
# @filter [Element, String] :for The element or id of the element associated with the label
#
2016-04-06 13:59:11 -04:00
Capybara . add_selector ( :label ) do
label " label "
2016-09-28 14:49:08 -04:00
xpath ( :for ) do | locator , options |
2016-04-06 13:59:11 -04:00
xpath = XPath . descendant ( :label )
2017-05-30 18:51:15 -04:00
xpath = xpath [ XPath . string . n . is ( locator . to_s ) . or XPath . attr ( :id ) . equals ( locator . to_s ) ] unless locator . nil?
2016-09-28 14:49:08 -04:00
if options . has_key? ( :for ) && ! options [ :for ] . is_a? ( Capybara :: Node :: Element )
xpath = xpath [ XPath . attr ( :for ) . equals ( options [ :for ] . to_s ) . or ( ( ~ XPath . attr ( :for ) ) . and ( XPath . descendant ( ) [ XPath . attr ( :id ) . equals ( options [ :for ] . to_s ) ] ) ) ]
end
2016-04-06 13:59:11 -04:00
xpath
end
filter ( :for ) do | node , field_or_value |
if field_or_value . is_a? Capybara :: Node :: Element
2016-09-28 14:49:08 -04:00
if node [ :for ]
field_or_value [ :id ] == node [ :for ]
2016-04-06 13:59:11 -04:00
else
2016-04-06 17:20:23 -04:00
field_or_value . find_xpath ( './ancestor::label[1]' ) . include? node . base
2016-04-06 13:59:11 -04:00
end
else
2016-09-28 14:49:08 -04:00
#Non element values were handled through the expression filter
true
2016-04-06 13:59:11 -04:00
end
end
2016-04-21 17:25:14 -04:00
describe do | options |
desc = String . new
desc << " for #{ options [ :for ] } " if options [ :for ]
2016-04-27 01:44:48 -04:00
desc
2016-04-21 17:25:14 -04:00
end
2016-04-06 13:59:11 -04:00
end
2016-09-09 19:44:32 -04:00
##
#
# Find table elements
#
2016-09-19 17:47:41 -04:00
# @locator id or caption text of table
# @filter [String] :id Match id attribute of table
# @filter [String] :caption Match text of associated caption
# @filter [String, Array<String>] :class Matches the class(es) provided
#
2011-08-27 17:54:55 -04:00
Capybara . add_selector ( :table ) do
2016-09-22 19:55:54 -04:00
xpath ( :caption ) do | locator , options |
2016-03-24 14:18:12 -04:00
xpath = XPath . descendant ( :table )
2017-05-30 18:51:15 -04:00
xpath = xpath [ XPath . attr ( :id ) . equals ( locator . to_s ) . or XPath . descendant ( :caption ) . is ( locator . to_s ) ] unless locator . nil?
2016-08-18 16:27:35 -04:00
xpath = xpath [ XPath . descendant ( :caption ) . equals ( options [ :caption ] ) ] if options [ :caption ]
2016-03-24 14:18:12 -04:00
xpath
end
2016-08-18 16:27:35 -04:00
describe do | options |
desc = String . new
desc << " with caption #{ options [ :caption ] } " if options [ :caption ]
desc
end
2011-08-27 17:54:55 -04:00
end
2016-07-18 16:17:22 -04:00
2016-09-09 19:44:32 -04:00
##
#
# Find frame/iframe elements
#
2016-09-19 17:47:41 -04:00
# @locator Match id or name
# @filter [String] :id Match id attribute
# @filter [String] :name Match name attribute
# @filter [String, Array<String>] :class Matches the class(es) provided
#
2016-07-18 16:17:22 -04:00
Capybara . add_selector ( :frame ) do
2016-09-22 19:55:54 -04:00
xpath ( :name ) do | locator , options |
2017-05-30 18:51:15 -04:00
xpath = XPath . descendant ( :iframe ) . union ( XPath . descendant ( :frame ) )
xpath = xpath [ XPath . attr ( :id ) . equals ( locator . to_s ) . or XPath . attr ( :name ) . equals ( locator ) ] unless locator . nil?
2016-10-05 18:16:00 -04:00
xpath = expression_filters . keys . inject ( xpath ) { | memo , ef | memo [ find_by_attr ( ef , options [ ef ] ) ] }
2016-07-18 16:17:22 -04:00
xpath
end
2016-08-18 16:27:35 -04:00
describe do | options |
desc = String . new
desc << " with name #{ options [ :name ] } " if options [ :name ]
desc
end
2016-07-28 04:25:24 -04:00
end