mirror of
https://github.com/teamcapybara/capybara.git
synced 2022-11-09 12:08:07 -05:00
Add the new global setting ignore_hidden_elements that is true by default.
This setting adds a new behaviour in the interaction with hidden elements. By default #locate, #click*, #choose, #select, etc. will ignore hidden elements. You can override this behaviour setting ignore_hidden_elements = false
This commit is contained in:
parent
b3bd6ed44b
commit
07f9ae6b09
15 changed files with 206 additions and 14 deletions
|
@ -9,11 +9,12 @@ module Capybara
|
||||||
class ElementNotFound < CapybaraError; end
|
class ElementNotFound < CapybaraError; end
|
||||||
class NotSupportedByDriverError < CapybaraError; end
|
class NotSupportedByDriverError < CapybaraError; end
|
||||||
class TimeoutError < CapybaraError; end
|
class TimeoutError < CapybaraError; end
|
||||||
|
class LocateHiddenElementError < CapybaraError; end
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
attr_accessor :debug, :asset_root, :app_host
|
attr_accessor :debug, :asset_root, :app_host
|
||||||
attr_writer :default_selector, :default_wait_time
|
attr_writer :default_selector, :default_wait_time
|
||||||
|
attr_writer :ignore_hidden_elements
|
||||||
|
|
||||||
def default_selector
|
def default_selector
|
||||||
@default_selector ||= :xpath
|
@default_selector ||= :xpath
|
||||||
|
@ -23,6 +24,10 @@ module Capybara
|
||||||
@default_wait_time ||= 2
|
@default_wait_time ||= 2
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def ignore_hidden_elements
|
||||||
|
(@ignore_hidden_elements.nil? || @ignore_hidden_elements) ? true : false
|
||||||
|
end
|
||||||
|
|
||||||
def log(message)
|
def log(message)
|
||||||
puts "[capybara] #{message}" if debug
|
puts "[capybara] #{message}" if debug
|
||||||
true
|
true
|
||||||
|
|
|
@ -167,11 +167,13 @@ module Capybara
|
||||||
Capybara::SaveAndOpenPage.save_and_open_page(body)
|
Capybara::SaveAndOpenPage.save_and_open_page(body)
|
||||||
end
|
end
|
||||||
|
|
||||||
#return node identified by locator or raise ElementNotFound(using desc)
|
# Return element identified by locator or raise ElementNotFound (using desc).
|
||||||
|
# If element is hidden raise LocateHiddenElementError.
|
||||||
def locate(locator, fail_msg = nil)
|
def locate(locator, fail_msg = nil)
|
||||||
node = wait_conditionally_until { find(locator) }
|
node = wait_conditionally_until { Capybara.ignore_hidden_elements ? find(locator, :visible => true) : find(locator) }
|
||||||
ensure
|
ensure
|
||||||
raise Capybara::ElementNotFound, fail_msg || "Unable to locate '#{locator}'" unless node
|
raise Capybara::ElementNotFound, fail_msg || "Unable to locate '#{locator}'" unless node
|
||||||
|
raise Capybara::LocateHiddenElementError, "The element selected by '#{locator}' is hidden" unless node.visible?
|
||||||
return node
|
return node
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,8 @@ shared_examples_for 'driver' do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should find the correct number of elements" do
|
it "should find the correct number of elements" do
|
||||||
@driver.find('//a').size.should == 3
|
debugger
|
||||||
|
@driver.find('//a').size.should == 4
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should extract node texts" do
|
it "should extract node texts" do
|
||||||
|
|
|
@ -48,6 +48,22 @@ module AttachFileSpec
|
||||||
running { @session.attach_file('does not exist', 'foo.txt') }.should raise_error(Capybara::ElementNotFound)
|
running { @session.attach_file('does not exist', 'foo.txt') }.should raise_error(Capybara::ElementNotFound)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "with a locator that selects a hidden node" do
|
||||||
|
before do
|
||||||
|
Capybara.ignore_hidden_elements = false
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
Capybara.ignore_hidden_elements = true
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should raise an error" do
|
||||||
|
running do
|
||||||
|
@session.attach_file("hidden_form_upload", 'foo.txt')
|
||||||
|
end.should raise_error(Capybara::LocateHiddenElementError)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -23,6 +23,22 @@ module CheckSpec
|
||||||
running { @session.check('does not exist') }.should raise_error(Capybara::ElementNotFound)
|
running { @session.check('does not exist') }.should raise_error(Capybara::ElementNotFound)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "with a locator that selects a hidden node" do
|
||||||
|
before do
|
||||||
|
Capybara.ignore_hidden_elements = false
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
Capybara.ignore_hidden_elements = true
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should raise an error" do
|
||||||
|
running do
|
||||||
|
@session.check('hidden_unchecked_checkbox')
|
||||||
|
end.should raise_error(Capybara::LocateHiddenElementError)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -23,6 +23,22 @@ module ChooseSpec
|
||||||
running { @session.choose('does not exist') }.should raise_error(Capybara::ElementNotFound)
|
running { @session.choose('does not exist') }.should raise_error(Capybara::ElementNotFound)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "with a locator that selects a hidden node" do
|
||||||
|
before do
|
||||||
|
Capybara.ignore_hidden_elements = false
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
Capybara.ignore_hidden_elements = true
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should raise an error" do
|
||||||
|
running do
|
||||||
|
@session.choose("hidden_gender_male")
|
||||||
|
end.should raise_error(Capybara::LocateHiddenElementError)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -144,6 +144,22 @@ module ClickButtonSpec
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "with a locator that selects a hidden node" do
|
||||||
|
before do
|
||||||
|
Capybara.ignore_hidden_elements = false
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
Capybara.ignore_hidden_elements = true
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should raise an error" do
|
||||||
|
running do
|
||||||
|
@session.click('Hidden button')
|
||||||
|
end.should raise_error(Capybara::LocateHiddenElementError)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
it "should serialize and send GET forms" do
|
it "should serialize and send GET forms" do
|
||||||
@session.visit('/form')
|
@session.visit('/form')
|
||||||
@session.click_button('med')
|
@session.click_button('med')
|
||||||
|
|
|
@ -34,10 +34,26 @@ module ClickLinkSpec
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "with a locator that selects a hidden node" do
|
||||||
|
before do
|
||||||
|
Capybara.ignore_hidden_elements = false
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
Capybara.ignore_hidden_elements = true
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should raise an error" do
|
||||||
|
running do
|
||||||
|
@session.click('hidden link')
|
||||||
|
end.should raise_error(Capybara::LocateHiddenElementError)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
it "should follow redirects" do
|
it "should follow redirects" do
|
||||||
@session.click_link('Redirect')
|
@session.click_link('Redirect')
|
||||||
@session.body.should include('You landed')
|
@session.body.should include('You landed')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -21,6 +21,23 @@ module ClickSpec
|
||||||
end.should raise_error(Capybara::ElementNotFound)
|
end.should raise_error(Capybara::ElementNotFound)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "with a locator that selects a hidden node" do
|
||||||
|
before do
|
||||||
|
@session.visit('/with_html')
|
||||||
|
Capybara.ignore_hidden_elements = false
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
Capybara.ignore_hidden_elements = true
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should raise an error" do
|
||||||
|
running do
|
||||||
|
@session.click('hidden link')
|
||||||
|
end.should raise_error(Capybara::LocateHiddenElementError)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -60,6 +60,22 @@ module FillInSpec
|
||||||
end.should raise_error(Capybara::ElementNotFound)
|
end.should raise_error(Capybara::ElementNotFound)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "with a locator that selects a hidden node" do
|
||||||
|
before do
|
||||||
|
Capybara.ignore_hidden_elements = false
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
Capybara.ignore_hidden_elements = true
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should raise an error" do
|
||||||
|
running do
|
||||||
|
@session.fill_in('First Name', :with => 'Blah blah')
|
||||||
|
end.should raise_error(Capybara::LocateHiddenElementError)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -22,6 +22,24 @@ module LocateSpec
|
||||||
@session.locate(@xpath).value.should == 'John Smith'
|
@session.locate(@xpath).value.should == 'John Smith'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "should return a visible node by default" do
|
||||||
|
@session.visit('/form')
|
||||||
|
@session.locate(Capybara::XPath.text_field('First Name')).should be_visible
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when ignore_hidden_elements is false" do
|
||||||
|
after do
|
||||||
|
Capybara.ignore_hidden_elements = true
|
||||||
|
end
|
||||||
|
it "should raise an exception hitting a hidden element" do
|
||||||
|
Capybara.ignore_hidden_elements = false
|
||||||
|
@session.visit('/form')
|
||||||
|
running do
|
||||||
|
@session.locate(Capybara::XPath.text_field('First Name')).should_not be_visible
|
||||||
|
end.should raise_error(Capybara::LocateHiddenElementError)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context "within a scope" do
|
context "within a scope" do
|
||||||
before do
|
before do
|
||||||
@session.visit('/with_scope')
|
@session.visit('/with_scope')
|
||||||
|
@ -35,4 +53,4 @@ module LocateSpec
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -22,6 +22,22 @@ module SelectSpec
|
||||||
running { @session.select('foo', :from => 'does not exist') }.should raise_error(Capybara::ElementNotFound)
|
running { @session.select('foo', :from => 'does not exist') }.should raise_error(Capybara::ElementNotFound)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "with a locator that selects a hidden node" do
|
||||||
|
before do
|
||||||
|
Capybara.ignore_hidden_elements = false
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
Capybara.ignore_hidden_elements = true
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should raise an error" do
|
||||||
|
running do
|
||||||
|
@session.select("Finish", :from => 'Locale')
|
||||||
|
end.should raise_error(Capybara::LocateHiddenElementError)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -24,6 +24,22 @@ module UncheckSpec
|
||||||
running { @session.uncheck('does not exist') }.should raise_error(Capybara::ElementNotFound)
|
running { @session.uncheck('does not exist') }.should raise_error(Capybara::ElementNotFound)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "with a locator that selects a hidden node" do
|
||||||
|
before do
|
||||||
|
Capybara.ignore_hidden_elements = false
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
Capybara.ignore_hidden_elements = true
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should raise an error" do
|
||||||
|
running do
|
||||||
|
@session.uncheck('hidden_checked_checkbox')
|
||||||
|
end.should raise_error(Capybara::LocateHiddenElementError)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,26 @@
|
||||||
<h1>Form</h1>
|
<h1>Form</h1>
|
||||||
|
|
||||||
<form action="/form" method="post">
|
<form action="/form" method="post">
|
||||||
|
|
||||||
|
<div style="display:none;">
|
||||||
|
<label for="form_first_name_hidden">
|
||||||
|
First Name
|
||||||
|
<input type="text" name="form[first_name]" value="John" id="form_first_name_hidden"/>
|
||||||
|
</label>
|
||||||
|
<button type="submit" id="hidden_button" value="click_me">Hidden button</button>
|
||||||
|
<input type="checkbox" id="hidden_unchecked_checkbox"/>
|
||||||
|
<input type="checkbox" id="hidden_checked_checkbox" checked="checked"/>
|
||||||
|
<label for="hidden_form_locale">Locale</label>
|
||||||
|
<select name="form[locale]" id="hidden_form_locale">
|
||||||
|
<option value="sv">Swedish</option>
|
||||||
|
<option selected="selected" value="en">English</option>
|
||||||
|
<option value="fi">Finish</option>
|
||||||
|
<option value="no">Norwegian</option>
|
||||||
|
</select>
|
||||||
|
<input type="radio" value="male" id="hidden_gender_male"/>
|
||||||
|
<input type="file" id="hidden_form_upload"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<label for="form_first_name">
|
<label for="form_first_name">
|
||||||
First Name
|
First Name
|
||||||
|
|
|
@ -20,4 +20,5 @@
|
||||||
|
|
||||||
<div id="hidden" style="display:none;">
|
<div id="hidden" style="display:none;">
|
||||||
<div id="hidden_via_ancestor">Inside element with hidden ancestor</div>
|
<div id="hidden_via_ancestor">Inside element with hidden ancestor</div>
|
||||||
|
<a href="/with_simple_html" title="awesome title" class="simple">hidden link</a>
|
||||||
</div>
|
</div>
|
Loading…
Add table
Reference in a new issue