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:
Andrea Fazzi 2010-01-11 14:45:36 +01:00
parent b3bd6ed44b
commit 07f9ae6b09
15 changed files with 206 additions and 14 deletions

View File

@ -9,11 +9,12 @@ module Capybara
class ElementNotFound < CapybaraError; end
class NotSupportedByDriverError < CapybaraError; end
class TimeoutError < CapybaraError; end
class LocateHiddenElementError < CapybaraError; end
class << self
attr_accessor :debug, :asset_root, :app_host
attr_writer :default_selector, :default_wait_time
attr_writer :ignore_hidden_elements
def default_selector
@default_selector ||= :xpath
@ -23,6 +24,10 @@ module Capybara
@default_wait_time ||= 2
end
def ignore_hidden_elements
(@ignore_hidden_elements.nil? || @ignore_hidden_elements) ? true : false
end
def log(message)
puts "[capybara] #{message}" if debug
true

View File

@ -167,11 +167,13 @@ module Capybara
Capybara::SaveAndOpenPage.save_and_open_page(body)
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)
node = wait_conditionally_until { find(locator) }
node = wait_conditionally_until { Capybara.ignore_hidden_elements ? find(locator, :visible => true) : find(locator) }
ensure
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
end

View File

@ -35,7 +35,8 @@ shared_examples_for 'driver' do
end
it "should find the correct number of elements" do
@driver.find('//a').size.should == 3
debugger
@driver.find('//a').size.should == 4
end
it "should extract node texts" do

View File

@ -48,6 +48,22 @@ module AttachFileSpec
running { @session.attach_file('does not exist', 'foo.txt') }.should raise_error(Capybara::ElementNotFound)
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

View File

@ -23,6 +23,22 @@ module CheckSpec
running { @session.check('does not exist') }.should raise_error(Capybara::ElementNotFound)
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

View File

@ -23,6 +23,22 @@ module ChooseSpec
running { @session.choose('does not exist') }.should raise_error(Capybara::ElementNotFound)
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

View File

@ -144,6 +144,22 @@ module ClickButtonSpec
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
@session.visit('/form')
@session.click_button('med')

View File

@ -34,6 +34,22 @@ module ClickLinkSpec
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
@session.click_link('Redirect')
@session.body.should include('You landed')

View File

@ -21,6 +21,23 @@ module ClickSpec
end.should raise_error(Capybara::ElementNotFound)
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

View File

@ -60,6 +60,22 @@ module FillInSpec
end.should raise_error(Capybara::ElementNotFound)
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

View File

@ -22,6 +22,24 @@ module LocateSpec
@session.locate(@xpath).value.should == 'John Smith'
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
before do
@session.visit('/with_scope')

View File

@ -22,6 +22,22 @@ module SelectSpec
running { @session.select('foo', :from => 'does not exist') }.should raise_error(Capybara::ElementNotFound)
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

View File

@ -24,6 +24,22 @@ module UncheckSpec
running { @session.uncheck('does not exist') }.should raise_error(Capybara::ElementNotFound)
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

View File

@ -1,6 +1,26 @@
<h1>Form</h1>
<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>
<label for="form_first_name">
First Name

View File

@ -20,4 +20,5 @@
<div id="hidden" style="display:none;">
<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>