From bb887c5d1d22e4ba5ecd881dafc5179205153157 Mon Sep 17 00:00:00 2001 From: Louis T Date: Fri, 8 Jan 2010 00:08:55 -0500 Subject: [PATCH 1/5] added basic html5 input types --- lib/capybara/xpath.rb | 28 +++++++++------------------- spec/views/form.erb | 23 +++++++++++++++++++++++ spec/xpath_spec.rb | 33 ++++++++++++++++++++++++++++++++- 3 files changed, 64 insertions(+), 20 deletions(-) diff --git a/lib/capybara/xpath.rb b/lib/capybara/xpath.rb index 40576a98..aa2f4cdc 100644 --- a/lib/capybara/xpath.rb +++ b/lib/capybara/xpath.rb @@ -38,7 +38,8 @@ module Capybara end def fillable_field(locator) - text_field(locator).password_field(locator).text_area(locator) + text_field(locator).password_field(locator).text_area(locator).email(locator)\ + .url(locator).search(locator).tel(locator).color(locator) end def content(locator) @@ -62,32 +63,21 @@ module Capybara xpath.append("//button[@id=#{s(locator)} or contains(@value,#{s(locator)}) or contains(.,#{s(locator)})]") end - def text_field(locator) - add_field(locator, "//input[@type='text']") - end - - def password_field(locator) - add_field(locator, "//input[@type='password']") - end - def text_area(locator) add_field(locator, "//textarea") end - def radio_button(locator) - add_field(locator, "//input[@type='radio']") - end - - def checkbox(locator) - add_field(locator, "//input[@type='checkbox']") - end - def select(locator) add_field(locator, "//select") end - def file_field(locator) - add_field(locator, "//input[@type='file']") + [ :text_field, :password_field, :radio_button, :checkbox, :file_field, + :email, :url, :search, :tel, :color + ].each do |input_type| + define_method(input_type) do |locator| + input_type = input_type.to_s.gsub("_field", "").gsub("_button", "") + add_field(locator, "//input[@type='#{input_type}']") + end end def scope(scope) diff --git a/spec/views/form.erb b/spec/views/form.erb index c5aaa5c2..7b6104c3 100644 --- a/spec/views/form.erb +++ b/spec/views/form.erb @@ -145,3 +145,26 @@

+ +
+

+ + +

+

+ + +

+

+ + +

+

+ + +

+

+ + +

+
diff --git a/spec/xpath_spec.rb b/spec/xpath_spec.rb index 2afe9a90..dfc6e821 100644 --- a/spec/xpath_spec.rb +++ b/spec/xpath_spec.rb @@ -99,7 +99,7 @@ describe Capybara::XPath do @query = @xpath.fillable_field('Description').to_s @driver.find(@query).first.text.should == 'Descriptive text goes here' end - + it "should be chainable" do @query = @xpath.fillable_field('First Name').password_field('First Name').to_s @driver.find(@query).first.value.should == 'John' @@ -220,4 +220,35 @@ describe Capybara::XPath do end end + [ [:email, 'html5_email', 'Html5 Email', 'person@email.com'], + [:url, 'html5_url', 'Html5 Url', 'http://www.example.com'], + [:search, 'html5_search', 'Html5 Search', 'what are you looking for'], + [:tel, 'html5_tel', 'Html5 Tel', '911'], + [:color, 'html5_color', 'Html5 Color', '#FFF']].each do |method, id, label, output| + describe "##{method}" do + it "should find a file field by label" do + @query = @xpath.send(method, label).to_s + @driver.find(@query).first.value.should == output + end + + it "should find a file field by id" do + @query = @xpath.send(method, id).to_s + @driver.find(@query).first.value.should == output + end + + it "should be chainable" do + @query = @xpath.send(method, label).password_field(label).to_s + @driver.find(@query).first.value.should == output + @query = @xpath.send(method, 'Password').password_field('Password').to_s + @driver.find(@query).first.value.should == 'seeekrit' + end + + it "should be a #fillable_field" do + @query = @xpath.fillable_field(label).to_s + @driver.find(@query).first.value.should == output + end + end + + end + end From 6e885bec4da13c8afa9ec3553243bf53cbbc012f Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Mon, 11 Jan 2010 20:36:05 +0100 Subject: [PATCH 2/5] refactored XPath --- lib/capybara/xpath.rb | 32 ++++++++++++++++++++++---------- spec/xpath_spec.rb | 14 +++++++------- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/lib/capybara/xpath.rb b/lib/capybara/xpath.rb index aa2f4cdc..7b45785a 100644 --- a/lib/capybara/xpath.rb +++ b/lib/capybara/xpath.rb @@ -34,12 +34,13 @@ module Capybara end def field(locator) - fillable_field(locator).file_field(locator).checkbox(locator).radio_button(locator).select(locator) + fillable_field(locator).input_field(:file, locator).checkbox(locator).radio_button(locator).select(locator) end def fillable_field(locator) - text_field(locator).password_field(locator).text_area(locator).email(locator)\ - .url(locator).search(locator).tel(locator).color(locator) + [:text, :password, :email, :url, :search, :tel, :color].inject(text_area(locator)) do |all, type| + all.input_field(type, locator) + end end def content(locator) @@ -71,13 +72,8 @@ module Capybara add_field(locator, "//select") end - [ :text_field, :password_field, :radio_button, :checkbox, :file_field, - :email, :url, :search, :tel, :color - ].each do |input_type| - define_method(input_type) do |locator| - input_type = input_type.to_s.gsub("_field", "").gsub("_button", "") - add_field(locator, "//input[@type='#{input_type}']") - end + def input_field(type, locator) + add_field(locator, "//input[@type='#{type}']") end def scope(scope) @@ -96,6 +92,22 @@ module Capybara XPath.new(*[XPath.wrap(path).paths, @paths].flatten) end + def checkbox(locator) + input_field(:checkbox, locator) + end + + def radio_button(locator) + input_field(:radio, locator) + end + + [:text, :password, :email, :url, :search, :tel, :color, :file].each do |type| + class_eval <<-RUBY, __FILE__, __LINE__+1 + def #{type}_field(locator) + input_field(:#{type}, locator) + end + RUBY + end + protected def add_field(locator, field) diff --git a/spec/xpath_spec.rb b/spec/xpath_spec.rb index dfc6e821..937901b3 100644 --- a/spec/xpath_spec.rb +++ b/spec/xpath_spec.rb @@ -83,9 +83,9 @@ describe Capybara::XPath do end it "should be chainable" do - @query = @xpath.field('First Name').password_field('First Name').to_s + @query = @xpath.field('First Name').input_field(:password, 'First Name').to_s @driver.find(@query).first.value.should == 'John' - @query = @xpath.field('Password').password_field('Password').to_s + @query = @xpath.field('Password').input_field(:password, 'Password').to_s @driver.find(@query).first.value.should == 'seeekrit' end end @@ -220,11 +220,11 @@ describe Capybara::XPath do end end - [ [:email, 'html5_email', 'Html5 Email', 'person@email.com'], - [:url, 'html5_url', 'Html5 Url', 'http://www.example.com'], - [:search, 'html5_search', 'Html5 Search', 'what are you looking for'], - [:tel, 'html5_tel', 'Html5 Tel', '911'], - [:color, 'html5_color', 'Html5 Color', '#FFF']].each do |method, id, label, output| + [ [:email_field, 'html5_email', 'Html5 Email', 'person@email.com'], + [:url_field, 'html5_url', 'Html5 Url', 'http://www.example.com'], + [:search_field, 'html5_search', 'Html5 Search', 'what are you looking for'], + [:tel_field, 'html5_tel', 'Html5 Tel', '911'], + [:color_field, 'html5_color', 'Html5 Color', '#FFF']].each do |method, id, label, output| describe "##{method}" do it "should find a file field by label" do @query = @xpath.send(method, label).to_s From 67e834245ced650620fe89fb3dce1f64a22a8fa7 Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Mon, 11 Jan 2010 20:36:37 +0100 Subject: [PATCH 3/5] Added Louis T. to contributors --- README.rdoc | 1 + 1 file changed, 1 insertion(+) diff --git a/README.rdoc b/README.rdoc index dacfcd77..107db0f9 100644 --- a/README.rdoc +++ b/README.rdoc @@ -337,6 +337,7 @@ The following people have dedicated their time and effort to Capybara: * Aaron Patterson * Dan Dofter * Thorbjørn Hermansen +* Louis T. == License: From 159424151b4848d1f9f98c61bc6666b6eae981bf Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Mon, 11 Jan 2010 21:18:32 +0100 Subject: [PATCH 4/5] Prefer exact matches over partial, links & buttons This aligns links and buttons with the behaviour of fields for more consistent behaviour --- lib/capybara/xpath.rb | 7 +++++-- spec/dsl/click_button_spec.rb | 10 ++++++++++ spec/dsl/click_link_spec.rb | 20 ++++++++++++++++++++ spec/views/form.erb | 9 +++++++++ spec/views/with_html.erb | 2 ++ 5 files changed, 46 insertions(+), 2 deletions(-) diff --git a/lib/capybara/xpath.rb b/lib/capybara/xpath.rb index 7b45785a..ce80d0e7 100644 --- a/lib/capybara/xpath.rb +++ b/lib/capybara/xpath.rb @@ -56,12 +56,15 @@ module Capybara end def link(locator) - append("//a[@id=#{s(locator)} or contains(.,#{s(locator)}) or @title=#{s(locator)}]") + xpath = append("//a[@id=#{s(locator)} or contains(.,#{s(locator)}) or contains(@title,#{s(locator)})]") + xpath.prepend("//a[text()=#{s(locator)} or @title=#{s(locator)}]") end def button(locator) xpath = append("//input[@type='submit' or @type='image'][@id=#{s(locator)} or contains(@value,#{s(locator)})]") - xpath.append("//button[@id=#{s(locator)} or contains(@value,#{s(locator)}) or contains(.,#{s(locator)})]") + xpath = xpath.append("//button[@id=#{s(locator)} or contains(@value,#{s(locator)}) or contains(.,#{s(locator)})]") + xpath = xpath.prepend("//input[@type='submit' or @type='image'][@value=#{s(locator)}]") + xpath = xpath.prepend("//button[@value=#{s(locator)} or text()=#{s(locator)}]") end def text_area(locator) diff --git a/spec/dsl/click_button_spec.rb b/spec/dsl/click_button_spec.rb index 18564fe3..d8d7334e 100644 --- a/spec/dsl/click_button_spec.rb +++ b/spec/dsl/click_button_spec.rb @@ -115,6 +115,11 @@ module ClickButtonSpec @session.click_button('Click') extract_results(@session)['first_name'].should == 'John' end + + it "should prefer exact matches over partial matches" do + @session.click_button('Just an input') + extract_results(@session)['button'].should == 'button_second' + end end context "with id given on a button defined by + + + +

+ \ No newline at end of file diff --git a/spec/views/with_html.erb b/spec/views/with_html.erb index 2da4833d..f661434d 100644 --- a/spec/views/with_html.erb +++ b/spec/views/with_html.erb @@ -16,6 +16,8 @@

+ A link came first + A link