2016-03-07 19:52:19 -05:00
# frozen_string_literal: true
2018-02-28 19:11:41 -05:00
2016-01-06 20:11:00 -05:00
require 'spec_helper'
RSpec . describe Capybara do
2020-07-04 17:05:29 -04:00
include Capybara :: RSpecMatchers
2016-01-06 20:11:00 -05:00
describe 'Selectors' do
let :string do
2019-07-15 17:49:21 -04:00
described_class . string <<-STRING
2016-01-06 20:11:00 -05:00
< html >
< head >
< title > selectors < / title>
< / head>
< body >
2018-09-26 18:24:58 -04:00
< div class = " aa " id = " page " >
< div class = " bb " id = " content " >
< h1 class = " aa " > Totally awesome < / h1>
2016-01-06 20:11:00 -05:00
< p > Yes it is < / p>
< / div>
2018-09-26 18:24:58 -04:00
< p class = " bb cc " > Some Content < / p>
2018-10-16 17:13:20 -04:00
< p class = " bb dd !mine " > < / p>
2016-01-06 20:11:00 -05:00
< / div>
2016-09-22 19:55:54 -04:00
< div id = " # special " >
< / div>
2018-05-26 13:26:44 -04:00
< div class = " some random words " id = " random_words " >
Something
< / div>
2016-09-22 19:55:54 -04:00
< input id = " 2checkbox " class = " 2checkbox " type = " checkbox " / >
2016-03-24 14:18:12 -04:00
< input type = " radio " / >
2016-09-22 19:55:54 -04:00
< label for = " my_text_input " > My Text Input < / label>
< input type = " text " name = " form[my_text_input] " placeholder = " my text " id = " my_text_input " / >
< input type = " file " id = " file " class = " .special file " / >
2016-10-02 21:28:52 -04:00
< input type = " hidden " id = " hidden_field " value = " this is hidden " / >
2018-04-11 12:23:59 -04:00
< input type = " submit " value = " click me " title = " submit button " / >
2018-12-02 19:07:40 -05:00
< input type = " button " value = " don't click me " title = " Other button 1 " style = " line-height: 30px; " / >
2016-03-24 14:18:12 -04:00
< a href = " # " > link < / a>
< fieldset > < / fieldset>
2016-10-05 18:16:00 -04:00
< select id = " select " >
2016-03-24 14:18:12 -04:00
< option value = " a " > A < / option>
2016-03-24 17:50:42 -04:00
< option value = " b " disabled > B < / option>
< option value = " c " selected > C < / option>
2016-03-24 14:18:12 -04:00
< / select>
< table >
< tr > < td > < / td>< / tr >
2018-05-26 13:26:44 -04:00
< / table>
2019-03-16 22:44:31 -04:00
< table id = " rows " >
< tr >
< td > A < / td><td>B< / td > < td > C < / td>
< / tr>
< tr >
< td > D < / td><td>E< / td > < td > F < / td>
< / tr>
< / table>
< table id = " cols " >
< tbody >
< tr >
< td > A < / td><td>D< / td >
< / tr>
< tr >
< td > B < / td><td>E< / td >
< / tr>
< tr >
< td > C < / td><td>F< / td >
< / tr>
< / tbody>
< / table>
2016-01-06 20:11:00 -05:00
< / body>
< / html>
STRING
end
before do
2019-07-15 17:49:21 -04:00
described_class . add_selector :custom_selector do
2016-01-06 20:11:00 -05:00
css { | css_class | " div. #{ css_class } " }
2018-05-29 17:02:03 -04:00
node_filter ( :not_empty , boolean : true , default : true , skip_if : :all ) { | node , value | value ^ ( node . text == '' ) }
2016-01-06 20:11:00 -05:00
end
2016-09-22 19:55:54 -04:00
2019-07-15 17:49:21 -04:00
described_class . add_selector :custom_css_selector do
2018-10-12 12:39:25 -04:00
css ( :name , :other_name ) do | selector , name : nil , ** |
2018-10-12 13:23:34 -04:00
selector || = ''
selector += " [name=' #{ name } '] " if name
selector
end
expression_filter ( :placeholder ) do | expr , val |
expr + " [placeholder=' #{ val } '] "
end
expression_filter ( :value ) do | expr , val |
expr + " [value=' #{ val } '] "
end
expression_filter ( :title ) do | expr , val |
expr + " [title=' #{ val } '] "
end
2016-09-22 19:55:54 -04:00
end
2018-05-26 13:26:44 -04:00
2019-07-15 17:49:21 -04:00
described_class . add_selector :custom_xpath_selector do
2018-10-12 12:39:25 -04:00
xpath ( :valid1 , :valid2 ) { | selector | selector }
2018-11-16 14:19:40 -05:00
match { | value | value == 'match_me' }
2018-05-26 13:26:44 -04:00
end
2016-01-06 20:11:00 -05:00
end
2018-07-10 17:18:39 -04:00
it 'supports `filter` as an alias for `node_filter`' do
2018-05-29 17:02:03 -04:00
expect do
2019-07-15 17:49:21 -04:00
described_class . add_selector :filter_alias_selector do
2018-07-10 17:18:39 -04:00
css { | _unused | 'div' }
2018-05-29 17:02:03 -04:00
filter ( :something ) { | _node , _value | true }
end
end . not_to raise_error
end
2018-07-10 17:18:39 -04:00
describe 'adding a selector' do
it 'can set default visiblity' do
2019-07-15 17:49:21 -04:00
described_class . add_selector :hidden_field do
2016-10-02 21:28:52 -04:00
visible :hidden
2018-02-28 19:11:41 -05:00
css { | _sel | 'input[type="hidden"]' }
2016-10-02 21:28:52 -04:00
end
expect ( string ) . to have_no_css ( 'input[type="hidden"]' )
expect ( string ) . to have_selector ( :hidden_field )
end
end
2018-07-10 17:18:39 -04:00
describe 'modify_selector' do
it 'allows modifying a selector' do
2018-09-26 18:24:58 -04:00
el = string . find ( :custom_selector , 'aa' )
2016-01-06 20:11:00 -05:00
expect ( el . tag_name ) . to eq 'div'
2019-07-15 17:49:21 -04:00
described_class . modify_selector :custom_selector do
2016-01-06 20:11:00 -05:00
css { | css_class | " h1. #{ css_class } " }
end
2018-09-26 18:24:58 -04:00
el = string . find ( :custom_selector , 'aa' )
2016-01-06 20:11:00 -05:00
expect ( el . tag_name ) . to eq 'h1'
end
it " doesn't change existing filters " do
2019-07-15 17:49:21 -04:00
described_class . modify_selector :custom_selector do
2018-02-28 19:11:41 -05:00
css { | css_class | " p. #{ css_class } " }
2016-01-06 20:11:00 -05:00
end
2018-09-26 18:24:58 -04:00
expect ( string ) . to have_selector ( :custom_selector , 'bb' , count : 1 )
expect ( string ) . to have_selector ( :custom_selector , 'bb' , not_empty : false , count : 1 )
expect ( string ) . to have_selector ( :custom_selector , 'bb' , not_empty : :all , count : 2 )
2016-01-06 20:11:00 -05:00
end
end
2016-03-24 14:18:12 -04:00
2018-11-16 14:19:40 -05:00
describe '::[]' do
it 'can find a selector' do
expect ( Capybara :: Selector [ :field ] ) . not_to be_nil
end
it 'raises if no selector found' do
expect { Capybara :: Selector [ :no_exist ] } . to raise_error ( ArgumentError , / Unknown selector type / )
end
end
describe '::for' do
it 'finds selector that matches the locator' do
expect ( Capybara :: Selector . for ( 'match_me' ) . name ) . to eq :custom_xpath_selector
end
it 'returns nil if no match' do
2022-04-30 13:26:55 -04:00
expect ( Capybara :: Selector . for ( 'nothing' ) ) . to be_nil
2018-11-16 14:19:40 -05:00
end
end
2018-10-12 12:39:25 -04:00
describe 'xpath' do
it 'uses filter names passed in' do
2019-07-15 17:49:21 -04:00
described_class . add_selector :test do
2018-10-12 12:39:25 -04:00
xpath ( :something , :other ) { | _locator | XPath . descendant }
end
2019-04-22 21:04:15 -04:00
selector = Capybara :: Selector . new :test , config : nil , format : nil
2018-10-12 12:39:25 -04:00
expect ( selector . expression_filters . keys ) . to include ( :something , :other )
end
it 'gets filter names from block if none passed to xpath method' do
2019-07-15 17:49:21 -04:00
described_class . add_selector :test do
2018-10-12 12:39:25 -04:00
xpath { | _locator , valid3 : , valid4 : nil | " #{ valid3 } #{ valid4 } " }
end
2019-04-22 21:04:15 -04:00
selector = Capybara :: Selector . new :test , config : nil , format : nil
2018-10-12 12:39:25 -04:00
expect ( selector . expression_filters . keys ) . to include ( :valid3 , :valid4 )
end
it 'ignores block parameters if names passed in' do
2019-07-15 17:49:21 -04:00
described_class . add_selector :test do
2018-10-12 12:39:25 -04:00
xpath ( :valid1 ) { | _locator , valid3 : , valid4 : nil | " #{ valid3 } #{ valid4 } " }
end
2019-04-22 21:04:15 -04:00
selector = Capybara :: Selector . new :test , config : nil , format : nil
2018-10-12 12:39:25 -04:00
expect ( selector . expression_filters . keys ) . to include ( :valid1 )
expect ( selector . expression_filters . keys ) . not_to include ( :valid3 , :valid4 )
end
end
describe 'css' do
2018-10-12 13:23:34 -04:00
it " supports filters specified in 'css' definition " do
expect ( string ) . to have_selector ( :custom_css_selector , 'input' , name : 'form[my_text_input]' )
expect ( string ) . to have_no_selector ( :custom_css_selector , 'input' , name : 'form[not_my_text_input]' )
end
it 'supports explicitly defined expression filters' do
expect ( string ) . to have_selector ( :custom_css_selector , placeholder : 'my text' )
expect ( string ) . to have_no_selector ( :custom_css_selector , placeholder : 'not my text' )
expect ( string ) . to have_selector ( :custom_css_selector , value : 'click me' , title : 'submit button' )
end
2018-10-12 12:39:25 -04:00
it 'uses filter names passed in' do
2019-07-15 17:49:21 -04:00
described_class . add_selector :test do
2018-10-12 12:39:25 -04:00
css ( :name , :other_name ) { | _locator | '' }
end
2019-04-22 21:04:15 -04:00
selector = Capybara :: Selector . new :test , config : nil , format : nil
2018-10-12 12:39:25 -04:00
expect ( selector . expression_filters . keys ) . to include ( :name , :other_name )
end
it 'gets filter names from block if none passed to css method' do
2019-07-15 17:49:21 -04:00
described_class . add_selector :test do
2018-10-12 12:39:25 -04:00
css { | _locator , valid3 : , valid4 : nil | " #{ valid3 } #{ valid4 } " }
end
2019-04-22 21:04:15 -04:00
selector = Capybara :: Selector . new :test , config : nil , format : nil
2018-10-12 12:39:25 -04:00
expect ( selector . expression_filters . keys ) . to include ( :valid3 , :valid4 )
end
it 'ignores block parameters if names passed in' do
2019-07-15 17:49:21 -04:00
described_class . add_selector :test do
2018-10-12 12:39:25 -04:00
css ( :valid1 ) { | _locator , valid3 : , valid4 : nil | " #{ valid3 } #{ valid4 } " }
end
2019-04-22 21:04:15 -04:00
selector = Capybara :: Selector . new :test , config : nil , format : nil
2018-10-12 12:39:25 -04:00
expect ( selector . expression_filters . keys ) . to include ( :valid1 )
expect ( selector . expression_filters . keys ) . not_to include ( :valid3 , :valid4 )
end
2018-10-12 13:23:34 -04:00
end
2018-07-10 17:18:39 -04:00
describe 'builtin selectors' do
context 'when locator is nil' do
it 'devolves to just finding element types' do
2016-03-24 17:50:42 -04:00
selectors = {
field : " .//*[self::input | self::textarea | self::select][not(./@type = 'submit' or ./@type = 'image' or ./@type = 'hidden')] " ,
2018-07-10 17:18:39 -04:00
fieldset : './/fieldset' ,
link : './/a[./@href]' ,
2018-02-28 19:11:41 -05:00
link_or_button : " .//a[./@href] | .//input[./@type = 'submit' or ./@type = 'reset' or ./@type = 'image' or ./@type = 'button'] | .//button " ,
2016-03-24 17:50:42 -04:00
fillable_field : " .//*[self::input | self::textarea][not(./@type = 'submit' or ./@type = 'image' or ./@type = 'radio' or ./@type = 'checkbox' or ./@type = 'hidden' or ./@type = 'file')] " ,
radio_button : " .//input[./@type = 'radio'] " ,
checkbox : " .//input[./@type = 'checkbox'] " ,
2018-07-10 17:18:39 -04:00
select : './/select' ,
option : './/option' ,
2016-03-24 17:50:42 -04:00
file_field : " .//input[./@type = 'file'] " ,
2018-07-10 17:18:39 -04:00
table : './/table'
2016-03-24 17:50:42 -04:00
}
selectors . each do | selector , xpath |
2018-02-28 19:11:41 -05:00
results = string . all ( selector , nil ) . to_a . map ( & :native )
2016-03-24 17:50:42 -04:00
expect ( results . size ) . to be > 0
expect ( results ) . to eq string . all ( :xpath , xpath ) . to_a . map ( & :native )
end
end
end
2018-07-10 17:18:39 -04:00
context 'with :id option' do
it 'works with compound css selectors' do
expect ( string . all ( :custom_css_selector , 'div, h1' , id : 'page' ) . size ) . to eq 1
expect ( string . all ( :custom_css_selector , 'h1, div' , id : 'page' ) . size ) . to eq 1
2016-09-22 19:55:54 -04:00
end
it " works with 'special' characters " do
2018-07-10 17:18:39 -04:00
expect ( string . find ( :custom_css_selector , 'div' , id : '#special' ) [ :id ] ) . to eq '#special'
expect ( string . find ( :custom_css_selector , 'input' , id : '2checkbox' ) [ :id ] ) . to eq '2checkbox'
2016-09-22 19:55:54 -04:00
end
2018-05-26 13:26:44 -04:00
2018-07-10 17:18:39 -04:00
it 'accepts XPath expression for xpath based selectors' do
2018-05-26 13:26:44 -04:00
expect ( string . find ( :custom_xpath_selector , './/div' , id : XPath . contains ( 'peci' ) ) [ :id ] ) . to eq '#special'
expect ( string . find ( :custom_xpath_selector , './/input' , id : XPath . ends_with ( 'box' ) ) [ :id ] ) . to eq '2checkbox'
end
2018-07-10 17:18:39 -04:00
it 'errors XPath expression for CSS based selectors' do
expect { string . find ( :custom_css_selector , 'div' , id : XPath . contains ( 'peci' ) ) }
2018-05-26 13:26:44 -04:00
. to raise_error ( ArgumentError , / not supported / )
end
2018-10-01 16:15:00 -04:00
it 'accepts Regexp for xpath based selectors' do
expect ( string . find ( :custom_xpath_selector , './/div' , id : / peci / ) [ :id ] ) . to eq '#special'
expect ( string . find ( :custom_xpath_selector , './/div' , id : / pEcI /i ) [ :id ] ) . to eq '#special'
end
it 'accepts Regexp for css based selectors' do
expect ( string . find ( :custom_css_selector , 'div' , id : / sp.*al / ) [ :id ] ) . to eq '#special'
end
2016-09-22 19:55:54 -04:00
end
2018-07-10 17:18:39 -04:00
context 'with :class option' do
it 'works with compound css selectors' do
2018-09-26 18:24:58 -04:00
expect ( string . all ( :custom_css_selector , 'div, h1' , class : 'aa' ) . size ) . to eq 2
expect ( string . all ( :custom_css_selector , 'h1, div' , class : 'aa' ) . size ) . to eq 2
2016-09-22 19:55:54 -04:00
end
2018-07-10 17:18:39 -04:00
it 'handles negated classes' do
2018-09-26 18:24:58 -04:00
expect ( string . all ( :custom_css_selector , 'div, p' , class : [ 'bb' , '!cc' ] ) . size ) . to eq 2
expect ( string . all ( :custom_css_selector , 'div, p' , class : [ '!cc' , '!dd' , 'bb' ] ) . size ) . to eq 1
expect ( string . all ( :custom_xpath_selector , XPath . descendant ( :div , :p ) , class : [ 'bb' , '!cc' ] ) . size ) . to eq 2
expect ( string . all ( :custom_xpath_selector , XPath . descendant ( :div , :p ) , class : [ '!cc' , '!dd' , 'bb' ] ) . size ) . to eq 1
2018-05-29 19:46:04 -04:00
end
2018-10-16 18:27:56 -04:00
it 'handles classes starting with ! by requiring negated negated first' do
2018-10-16 17:13:20 -04:00
expect ( string . all ( :custom_css_selector , 'div, p' , class : [ '!!!mine' ] ) . size ) . to eq 1
expect ( string . all ( :custom_xpath_selector , XPath . descendant ( :div , :p ) , class : [ '!!!mine' ] ) . size ) . to eq 1
end
2016-09-22 19:55:54 -04:00
it " works with 'special' characters " do
2018-07-10 17:18:39 -04:00
expect ( string . find ( :custom_css_selector , 'input' , class : '.special' ) [ :id ] ) . to eq 'file'
expect ( string . find ( :custom_css_selector , 'input' , class : '2checkbox' ) [ :id ] ) . to eq '2checkbox'
2016-09-22 19:55:54 -04:00
end
2018-05-26 13:26:44 -04:00
2018-07-10 17:18:39 -04:00
it 'accepts XPath expression for xpath based selectors' do
2018-05-26 13:26:44 -04:00
expect ( string . find ( :custom_xpath_selector , './/div' , class : XPath . contains ( 'dom wor' ) ) [ :id ] ) . to eq 'random_words'
expect ( string . find ( :custom_xpath_selector , './/div' , class : XPath . ends_with ( 'words' ) ) [ :id ] ) . to eq 'random_words'
end
2018-07-10 17:18:39 -04:00
it 'errors XPath expression for CSS based selectors' do
expect { string . find ( :custom_css_selector , 'div' , class : XPath . contains ( 'random' ) ) }
2018-05-26 13:26:44 -04:00
. to raise_error ( ArgumentError , / not supported / )
end
2018-10-01 16:15:00 -04:00
it 'accepts Regexp for XPath based selectors' do
expect ( string . find ( :custom_xpath_selector , './/div' , class : / dom wor / ) [ :id ] ) . to eq 'random_words'
expect ( string . find ( :custom_xpath_selector , './/div' , class : / dOm WoR /i ) [ :id ] ) . to eq 'random_words'
end
2021-01-23 16:13:04 -05:00
it 'accepts Regexp for CSS based selectors' do
2018-10-01 16:15:00 -04:00
expect ( string . find ( :custom_css_selector , 'div' , class : / random / ) [ :id ] ) . to eq 'random_words'
end
2021-01-23 16:13:04 -05:00
it 'accepts Regexp for individual class names for XPath based selectors' do
expect ( string . find ( :custom_xpath_selector , './/div' , class : [ / random / , 'some' ] ) [ :id ] ) . to eq 'random_words'
expect ( string . find ( :custom_xpath_selector , './/div' , class : [ / om / , / wor / ] ) [ :id ] ) . to eq 'random_words'
expect { string . find ( :custom_xpath_selector , './/div' , class : [ / not / , / wor / ] ) } . to raise_error ( Capybara :: ElementNotFound )
expect { string . find ( :custom_xpath_selector , './/div' , class : [ / dom wor / ] ) } . to raise_error ( Capybara :: ElementNotFound )
end
it 'accepts Regexp for individual class names for CSS based selectors' do
expect ( string . find ( :custom_css_selector , 'div' , class : [ / random / ] ) [ :id ] ) . to eq 'random_words'
expect ( string . find ( :custom_css_selector , 'div' , class : [ / om / , / wor / , 'some' ] ) [ :id ] ) . to eq 'random_words'
expect { string . find ( :custom_css_selector , 'div' , class : [ / not / , / wor / ] ) } . to raise_error ( Capybara :: ElementNotFound )
expect { string . find ( :custom_css_selector , 'div' , class : [ / dom wor / ] ) } . to raise_error ( Capybara :: ElementNotFound )
end
2016-09-22 19:55:54 -04:00
end
2018-12-02 19:07:40 -05:00
context 'with :style option' do
it 'accepts string for CSS based selectors' do
expect ( string . find ( :custom_css_selector , 'input' , style : 'line-height: 30px;' ) [ :title ] ) . to eq 'Other button 1'
end
it 'accepts Regexp for CSS base selectors' do
expect ( string . find ( :custom_css_selector , 'input' , style : / 30px / ) [ :title ] ) . to eq 'Other button 1'
end
end
2016-09-22 19:55:54 -04:00
# :css, :xpath, :id, :field, :fieldset, :link, :button, :link_or_button, :fillable_field, :radio_button, :checkbox, :select,
# :option, :file_field, :label, :table, :frame
2018-07-10 17:18:39 -04:00
describe ':css selector' do
it 'finds by CSS locator' do
expect ( string . find ( :css , 'input#my_text_input' ) [ :name ] ) . to eq 'form[my_text_input]'
2016-09-22 19:55:54 -04:00
end
end
2018-07-10 17:18:39 -04:00
describe ':xpath selector' do
it 'finds by XPath locator' do
2016-09-22 19:55:54 -04:00
expect ( string . find ( :xpath , './/input[@id="my_text_input"]' ) [ :name ] ) . to eq 'form[my_text_input]'
end
end
2018-07-10 17:18:39 -04:00
describe ':id selector' do
it 'finds by locator' do
expect ( string . find ( :id , 'my_text_input' ) [ :name ] ) . to eq 'form[my_text_input]'
2018-11-14 02:00:41 -05:00
expect ( string . find ( :id , / my_text_input / ) [ :name ] ) . to eq 'form[my_text_input]'
expect ( string . find ( :id , / _text_ / ) [ :name ] ) . to eq 'form[my_text_input]'
expect ( string . find ( :id , / i[nmo] / ) [ :name ] ) . to eq 'form[my_text_input]'
2016-09-22 19:55:54 -04:00
end
end
2018-07-10 17:18:39 -04:00
describe ':field selector' do
it 'finds by locator' do
2016-09-22 19:55:54 -04:00
expect ( string . find ( :field , 'My Text Input' ) [ :id ] ) . to eq 'my_text_input'
expect ( string . find ( :field , 'my_text_input' ) [ :id ] ) . to eq 'my_text_input'
expect ( string . find ( :field , 'form[my_text_input]' ) [ :id ] ) . to eq 'my_text_input'
end
2018-10-01 16:15:00 -04:00
it 'finds by id string' do
2016-09-22 19:55:54 -04:00
expect ( string . find ( :field , id : 'my_text_input' ) [ :name ] ) . to eq 'form[my_text_input]'
end
2018-10-01 16:15:00 -04:00
it 'finds by id regexp' do
expect ( string . find ( :field , id : / my_text_inp / ) [ :name ] ) . to eq 'form[my_text_input]'
end
2018-07-10 17:18:39 -04:00
it 'finds by name' do
2016-09-22 19:55:54 -04:00
expect ( string . find ( :field , name : 'form[my_text_input]' ) [ :id ] ) . to eq 'my_text_input'
end
2018-07-10 17:18:39 -04:00
it 'finds by placeholder' do
2016-09-22 19:55:54 -04:00
expect ( string . find ( :field , placeholder : 'my text' ) [ :id ] ) . to eq 'my_text_input'
end
2018-07-10 17:18:39 -04:00
it 'finds by type' do
2016-09-22 19:55:54 -04:00
expect ( string . find ( :field , type : 'file' ) [ :id ] ) . to eq 'file'
2016-10-05 18:16:00 -04:00
expect ( string . find ( :field , type : 'select' ) [ :id ] ) . to eq 'select'
2016-09-22 19:55:54 -04:00
end
end
2018-07-10 17:18:39 -04:00
describe ':option selector' do
it 'finds disabled options' do
2016-03-24 17:50:42 -04:00
expect ( string . find ( :option , disabled : true ) . value ) . to eq 'b'
end
2018-07-10 17:18:39 -04:00
it 'finds selected options' do
2016-03-24 17:50:42 -04:00
expect ( string . find ( :option , selected : true ) . value ) . to eq 'c'
end
2018-07-10 17:18:39 -04:00
it 'finds not selected and not disabled options' do
2016-03-24 17:50:42 -04:00
expect ( string . find ( :option , disabled : false , selected : false ) . value ) . to eq 'a'
2016-03-24 14:18:12 -04:00
end
end
2018-04-11 12:23:59 -04:00
2018-07-10 17:18:39 -04:00
describe ':button selector' do
it 'finds by value' do
2018-04-11 12:23:59 -04:00
expect ( string . find ( :button , 'click me' ) . value ) . to eq 'click me'
end
2018-07-10 17:18:39 -04:00
it 'finds by title' do
2018-04-11 12:23:59 -04:00
expect ( string . find ( :button , 'submit button' ) . value ) . to eq 'click me'
end
2018-07-10 17:18:39 -04:00
it 'includes non-matching parameters in failure message' do
2018-04-11 12:23:59 -04:00
expect { string . find ( :button , 'click me' , title : 'click me' ) } . to raise_error ( / with title click me / )
end
end
2018-05-24 18:27:34 -04:00
2018-07-10 17:18:39 -04:00
describe ':element selector' do
it 'finds by any attributes' do
2018-05-24 18:27:34 -04:00
expect ( string . find ( :element , 'input' , type : 'submit' ) . value ) . to eq 'click me'
end
2018-09-21 15:26:55 -04:00
it 'supports regexp matching' do
expect ( string . find ( :element , 'input' , type : / sub / ) . value ) . to eq 'click me'
expect ( string . find ( :element , 'input' , title : / sub \ w.*button / ) . value ) . to eq 'click me'
expect ( string . find ( :element , 'input' , title : / sub.* b.*ton / ) . value ) . to eq 'click me'
expect ( string . find ( :element , 'input' , title : / sub.*mit.* / ) . value ) . to eq 'click me'
expect ( string . find ( :element , 'input' , title : / ^submit button$ / ) . value ) . to eq 'click me'
expect ( string . find ( :element , 'input' , title : / ^(?:submit|other) button$ / ) . value ) . to eq 'click me'
2018-09-26 17:55:56 -04:00
expect ( string . find ( :element , 'input' , title : / SuB.*mIt /i ) . value ) . to eq 'click me'
expect ( string . find ( :element , 'input' , title : / ^Su.*Bm.*It /i ) . value ) . to eq 'click me'
expect ( string . find ( :element , 'input' , title : / ^Ot.*he.*r b.* \ d /i ) . value ) . to eq " don't click me "
2018-09-21 15:26:55 -04:00
end
2018-07-10 17:18:39 -04:00
it 'still works with system keys' do
2018-05-24 18:27:34 -04:00
expect { string . all ( :element , 'input' , type : 'submit' , count : 1 ) } . not_to raise_error
end
2018-08-15 13:11:32 -04:00
it 'works without element type' do
expect ( string . find ( :element , type : 'submit' ) . value ) . to eq 'click me'
end
2018-08-15 13:44:34 -04:00
it 'validates attribute presence when true' do
expect ( string . find ( :element , name : true ) [ :id ] ) . to eq 'my_text_input'
end
it 'validates attribute absence when false' do
expect ( string . find ( :element , 'option' , disabled : false , selected : false ) . value ) . to eq 'a'
end
2018-07-10 17:18:39 -04:00
it 'includes wildcarded keys in description' do
2018-08-15 13:44:34 -04:00
expect { string . find ( :element , 'input' , not_there : 'bad' , presence : true , absence : false , count : 1 ) }
2018-05-24 18:27:34 -04:00
. to ( raise_error do | e |
expect ( e ) . to be_a ( Capybara :: ElementNotFound )
2018-07-10 17:18:39 -04:00
expect ( e . message ) . to include 'not_there => bad'
2018-08-15 13:44:34 -04:00
expect ( e . message ) . to include 'with presence attribute'
expect ( e . message ) . to include 'without absence attribute'
2018-07-10 17:18:39 -04:00
expect ( e . message ) . not_to include 'count 1'
2018-05-24 18:27:34 -04:00
end )
end
2018-07-10 17:18:39 -04:00
it 'accepts XPath::Expression' do
2018-05-24 18:27:34 -04:00
expect ( string . find ( :element , 'input' , type : XPath . starts_with ( 'subm' ) ) . value ) . to eq 'click me'
expect ( string . find ( :element , 'input' , type : XPath . ends_with ( 'ext' ) ) [ :type ] ) . to eq 'text'
expect ( string . find ( :element , 'input' , type : XPath . contains ( 'ckb' ) ) [ :type ] ) . to eq 'checkbox'
expect ( string . find ( :element , 'input' , title : XPath . contains_word ( 'submit' ) ) [ :type ] ) . to eq 'submit'
2018-09-26 17:55:56 -04:00
expect ( string . find ( :element , 'input' , title : XPath . contains_word ( 'button 1' ) ) [ :type ] ) . to eq 'button'
2018-05-24 18:27:34 -04:00
end
end
2018-11-16 00:49:46 -05:00
describe ':link_or_button selector' do
2020-05-16 18:29:41 -04:00
around do | example |
2019-07-15 17:49:21 -04:00
described_class . modify_selector ( :link_or_button ) do
2018-11-16 00:49:46 -05:00
expression_filter ( :random ) { | xpath , _ | xpath } # do nothing filter
end
example . run
2018-11-16 13:15:26 -05:00
Capybara :: Selector [ :link_or_button ] . expression_filters . delete ( :random )
2018-11-16 00:49:46 -05:00
end
2019-04-02 15:08:52 -04:00
it 'should not find links when disabled == true' do
expect ( string . all ( :link_or_button , disabled : true ) . size ) . to eq 0
end
2018-11-16 00:49:46 -05:00
context 'when modified' do
it 'should still work' do
2018-11-16 13:15:26 -05:00
filter = Capybara :: Selector [ :link_or_button ] . expression_filters [ :random ]
2018-11-16 12:51:40 -05:00
allow ( filter ) . to receive ( :apply_filter ) . and_call_original
2018-11-16 00:49:46 -05:00
expect ( string . find ( :link_or_button , 'click me' , random : 'blah' ) . value ) . to eq 'click me'
2018-11-16 12:51:40 -05:00
expect ( filter ) . to have_received ( :apply_filter ) . with ( anything , :random , 'blah' , anything )
2018-11-16 00:49:46 -05:00
end
end
end
2019-03-16 22:44:31 -04:00
describe ':table selector' do
it 'finds by rows' do
expect ( string . find ( :table , with_rows : [ %w[ D E F ] ] ) [ :id ] ) . to eq 'rows'
end
it 'finds by columns' do
expect ( string . find ( :table , with_cols : [ %w[ A B C ] ] ) [ :id ] ) . to eq 'cols'
end
end
2016-03-24 14:18:12 -04:00
end
2016-01-06 20:11:00 -05:00
end
end