mirror of
https://github.com/teamcapybara/capybara.git
synced 2022-11-09 12:08:07 -05:00
automatically click label if checkbox is hidden
This commit is contained in:
parent
3f515ff826
commit
37d7df5f1c
7 changed files with 135 additions and 2 deletions
|
@ -114,7 +114,17 @@ module Capybara
|
|||
#
|
||||
def check(locator, options={})
|
||||
locator, options = nil, locator if locator.is_a? Hash
|
||||
find(:checkbox, locator, options).set(true)
|
||||
begin
|
||||
find(:checkbox, locator, options).set(true)
|
||||
rescue Capybara::ElementNotFound => e
|
||||
begin
|
||||
cbox = find(:checkbox, locator, options.merge({wait: 0, visible: :all}))
|
||||
label = find(:label, for: cbox, wait: 0)
|
||||
label.click if !cbox.checked?
|
||||
rescue
|
||||
raise e
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -133,7 +143,17 @@ module Capybara
|
|||
#
|
||||
def uncheck(locator, options={})
|
||||
locator, options = nil, locator if locator.is_a? Hash
|
||||
find(:checkbox, locator, options).set(false)
|
||||
begin
|
||||
find(:checkbox, locator, options).set(false)
|
||||
rescue Capybara::ElementNotFound => e
|
||||
begin
|
||||
cbox = find(:checkbox, locator, options.merge({wait: 0, visible: :all}))
|
||||
label = find(:label, for: cbox, wait: 0)
|
||||
label.click if cbox.checked?
|
||||
rescue
|
||||
raise e
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
|
|
|
@ -60,6 +60,16 @@ class Capybara::RackTest::Node < Capybara::Driver::Node
|
|||
((tag_name == 'button') and type.nil? or type == "submit")
|
||||
associated_form = form
|
||||
Capybara::RackTest::Form.new(driver, associated_form).submit(self) if associated_form
|
||||
elsif (tag_name == 'label')
|
||||
labelled_control = if native[:for]
|
||||
find_xpath("//input[@id='#{native[:for]}']").first
|
||||
else
|
||||
find_xpath(".//input").first
|
||||
end
|
||||
|
||||
if labelled_control && (labelled_control.checkbox? || labelled_control.radio?)
|
||||
labelled_control.set(!labelled_control.checked?)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -183,6 +193,8 @@ private
|
|||
self[attribute] && !self[attribute].empty?
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def checkbox?
|
||||
input_field? && type == 'checkbox'
|
||||
end
|
||||
|
|
|
@ -368,6 +368,11 @@ Capybara.add_selector(:label) do
|
|||
node[:for] == field_or_value.to_s
|
||||
end
|
||||
end
|
||||
|
||||
describe do |options|
|
||||
desc = String.new
|
||||
desc << " for #{options[:for]}" if options[:for]
|
||||
end
|
||||
end
|
||||
|
||||
Capybara.add_selector(:table) do
|
||||
|
|
|
@ -111,4 +111,31 @@ Capybara::SpecHelper.spec "#check" do
|
|||
end.to raise_error(Capybara::ElementNotFound)
|
||||
end
|
||||
end
|
||||
|
||||
context "when checkbox hidden", hidden: true do
|
||||
it "should check via clicking the label with :for attribute if possible" do
|
||||
expect(@session.find(:checkbox, 'form_cars_tesla', unchecked: true, visible: :hidden)).to be
|
||||
@session.check('form_cars_tesla')
|
||||
@session.click_button('awesome')
|
||||
expect(extract_results(@session)['cars']).to include('tesla')
|
||||
end
|
||||
|
||||
it "should check via clicking the wrapping label if possible" do
|
||||
expect(@session.find(:checkbox, 'form_cars_mclaren', unchecked: true, visible: :hidden)).to be
|
||||
@session.check('form_cars_mclaren')
|
||||
@session.click_button('awesome')
|
||||
expect(extract_results(@session)['cars']).to include('mclaren')
|
||||
end
|
||||
|
||||
it "should not click the label if unneeded" do
|
||||
expect(@session.find(:checkbox, 'form_cars_jaguar', checked: true, visible: :hidden)).to be
|
||||
@session.check('form_cars_jaguar')
|
||||
@session.click_button('awesome')
|
||||
expect(extract_results(@session)['cars']).to include('jaguar')
|
||||
end
|
||||
|
||||
it "should raise original error when no label available" do
|
||||
expect { @session.check('form_cars_ariel') }.to raise_error(Capybara::ElementNotFound, 'Unable to find checkbox "form_cars_ariel"')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -38,4 +38,31 @@ Capybara::SpecHelper.spec "#uncheck" do
|
|||
end.to raise_error(Capybara::ElementNotFound)
|
||||
end
|
||||
end
|
||||
|
||||
context "when checkbox hidden", hidden: true do
|
||||
it "should uncheck via clicking the label with :for attribute if possible" do
|
||||
expect(@session.find(:checkbox, 'form_cars_jaguar', checked: true, visible: :hidden)).to be
|
||||
@session.uncheck('form_cars_jaguar')
|
||||
@session.click_button('awesome')
|
||||
expect(extract_results(@session)['cars']).not_to include('jaguar')
|
||||
end
|
||||
|
||||
it "should uncheck via clicking the wrapping label if possible" do
|
||||
expect(@session.find(:checkbox, 'form_cars_koenigsegg', checked: true, visible: :hidden)).to be
|
||||
@session.uncheck('form_cars_koenigsegg')
|
||||
@session.click_button('awesome')
|
||||
expect(extract_results(@session)['cars']).not_to include('koenigsegg')
|
||||
end
|
||||
|
||||
it "should not click the label if unneeded" do
|
||||
expect(@session.find(:checkbox, 'form_cars_tesla', unchecked: true, visible: :hidden)).to be
|
||||
@session.uncheck('form_cars_tesla')
|
||||
@session.click_button('awesome')
|
||||
expect(extract_results(@session)['cars']).not_to include('tesla')
|
||||
end
|
||||
|
||||
it "should raise original error when no label available" do
|
||||
expect { @session.uncheck('form_cars_ariel') }.to raise_error(Capybara::ElementNotFound, 'Unable to find checkbox "form_cars_ariel"')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -167,6 +167,24 @@ New line after and before textarea tag
|
|||
<label for="form_pets_hamster">Hamster</label>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<input type="checkbox" value="jaguar" name="form[cars][]" id="form_cars_jaguar" checked="checked" style="display: none"/>
|
||||
<label for="form_cars_jaguar">Jaguar</label>
|
||||
<input type="checkbox" value="tesla" name="form[cars][]" id="form_cars_tesla" style="display: none"/>
|
||||
<label for="form_cars_tesla">Tesla</label>
|
||||
<input type="checkbox" value="ferrari" name="form[cars][]" id="form_cars_ferrari" checked="checked" style="display: none"/>
|
||||
<label for="form_cars_ferrari">Ferrari</label>
|
||||
<input type="checkbox" value="ariel" name="form[cars][]" id="form_cars_ariel" style="display: none"/>
|
||||
<label>
|
||||
McLaren
|
||||
<input type="checkbox" value="mclaren" name="form[cars][]" id="form_cars_mclaren" style="display: none"/>
|
||||
</label>
|
||||
<label>
|
||||
Koenigsegg
|
||||
<input type="checkbox" value="koenigsegg" name="form[cars][]" id="form_cars_koenigsegg" checked="checked" style="display: none"/>
|
||||
</label>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<input type="checkbox" name="form[valueless_checkbox]" id="valueless_checkbox" checked="checked"/>
|
||||
<label for="valueless_checkbox">Valueless Checkbox</label>
|
||||
|
|
|
@ -80,6 +80,30 @@ RSpec.describe Capybara::Session do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#click" do
|
||||
context "on a label" do
|
||||
it "should toggle the associated checkbox" do
|
||||
@session.visit("/form")
|
||||
expect(@session).to have_unchecked_field('form_pets_cat')
|
||||
@session.find(:label, 'Cat').click
|
||||
expect(@session).to have_checked_field('form_pets_cat')
|
||||
@session.find(:label, 'Cat').click
|
||||
expect(@session).to have_unchecked_field('form_pets_cat')
|
||||
@session.find(:label, 'McLaren').click
|
||||
expect(@session).to have_checked_field('form_cars_mclaren', visible: :hidden)
|
||||
end
|
||||
|
||||
it "should toggle the associated radio" do
|
||||
@session.visit("/form")
|
||||
expect(@session).to have_unchecked_field('gender_male')
|
||||
@session.find(:label, 'Male').click
|
||||
expect(@session).to have_checked_field('gender_male')
|
||||
@session.find(:label, 'Female').click
|
||||
expect(@session).to have_unchecked_field('gender_male')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue