From 4d3e7f785b05a45d4a80b5d3771114fb00700be2 Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Thu, 6 Nov 2008 03:19:52 -0500 Subject: [PATCH] More work on integrating locator strategies --- lib/webrat/core/field.rb | 2 +- lib/webrat/core/form.rb | 14 ++-- lib/webrat/core/locators.rb | 82 ++++++++++++--------- lib/webrat/core/scope.rb | 32 +++++--- lib/webrat/core_extensions/detect_mapped.rb | 12 +++ 5 files changed, 88 insertions(+), 54 deletions(-) create mode 100644 lib/webrat/core_extensions/detect_mapped.rb diff --git a/lib/webrat/core/field.rb b/lib/webrat/core/field.rb index d78db0f..9288f38 100644 --- a/lib/webrat/core/field.rb +++ b/lib/webrat/core/field.rb @@ -173,7 +173,7 @@ module Webrat if collection_name? super else - checkbox_with_same_name = @form.find_field(name, CheckboxField) + checkbox_with_same_name = @form.field(name, CheckboxField) if checkbox_with_same_name.to_param.blank? super diff --git a/lib/webrat/core/form.rb b/lib/webrat/core/form.rb index ed64796..39ce99b 100644 --- a/lib/webrat/core/form.rb +++ b/lib/webrat/core/form.rb @@ -11,10 +11,10 @@ module Webrat @fields = nil end - def find_field(locator, *field_types) - field_by_id(locator, *field_types) || - field_by_name(locator, *field_types) || - field_by_label(locator, *field_types) || + def field(locator, *field_types) + field_with_id(locator, *field_types) || + field_named(locator, *field_types) || + field_labeled(locator, *field_types) || nil end @@ -48,17 +48,17 @@ module Webrat @session.request_page(form_action, form_method, params) end - def field_by_id(id, *field_types) + def field_with_id(id, *field_types) possible_fields = fields_by_type(field_types) possible_fields.detect { |possible_field| possible_field.matches_id?(id) } end - def field_by_name(name, *field_types) + def field_named(name, *field_types) possible_fields = fields_by_type(field_types) possible_fields.detect { |possible_field| possible_field.matches_name?(name) } end - def field_by_label(label, *field_types) + def field_labeled(label, *field_types) possible_fields = fields_by_type(field_types) matching_fields = possible_fields.select do |possible_field| possible_field.matches_label?(label) diff --git a/lib/webrat/core/locators.rb b/lib/webrat/core/locators.rb index e0150b0..0edf4c7 100644 --- a/lib/webrat/core/locators.rb +++ b/lib/webrat/core/locators.rb @@ -1,69 +1,83 @@ +require "webrat/core_extensions/detect_mapped" + module Webrat module Locators - def find_field(*args) + def field(*args) # This is the default locator strategy - - field_with_id(*args) || - field_with_name(*args) || - field_labeled(*args) + find_field_with_id(*args) || + find_field_named(*args) || + field_labeled(*args) || + flunk("Could not find field: #{args.inspect}") end def field_labeled(label, *field_types) - forms.each do |form| - result = form.field_by_label(label, *field_types) - return result if result - end - - flunk("Could not find #{field_types.inspect}: #{label.inspect}") + find_field_labeled(label, *field_types) || + flunk("Could not find field labeled #{label.inspect}") + end + + def field_named(name, *field_types) + find_field_named(name, *field_types) || + flunk("Could not find field named #{name.inspect}") end def field_with_id(id, *field_types) - forms.each do |form| - result = form.field_by_id(id, *field_types) - return result if result - end - - return nil + find_field_with_id(id, *field_types) || + flunk("Could not find field with id #{id.inspect}") end - def field_with_name(name, *field_types) - forms.each do |form| - result = form.field_by_name(name, *field_types) - return result if result + def find_field_labeled(label, *field_types) + forms.detect_mapped do |form| + form.field_labeled(label, *field_types) + end + end + + def find_field_named(name, *field_types) + forms.detect_mapped do |form| + form.field_named(name, *field_types) + end + end + + def find_field_with_id(id, *field_types) + forms.detect_mapped do |form| + form.field_with_id(id, *field_types) end - - return nil end def find_select_option(option_text, id_or_name_or_label) if id_or_name_or_label - field = find_field(id_or_name_or_label, SelectField) + field = field(id_or_name_or_label, SelectField) return field.find_option(option_text) else - forms.each do |form| - result = form.find_select_option(option_text) - return result if result + select_option = forms.detect_mapped do |form| + form.find_select_option(option_text) end + + return select_option if select_option end flunk("Could not find option #{option_text.inspect}") end def find_button(value) - forms.each do |form| - button = form.find_button(value) - return button if button + button = forms.detect_mapped do |form| + form.find_button(value) + end + + if button + return button + else + flunk("Could not find button #{value.inspect}") end - flunk("Could not find button #{value.inspect}") end def find_area(area_name) - areas.select{|area| area.matches_text?(area_name)}.first || flunk("Could not find area with name #{area_name}") + areas.detect { |area| area.matches_text?(area_name) } || + flunk("Could not find area with name #{area_name}") end - def find_link(text, selector = nil) - matching_links = links_within(selector).select do |possible_link| + def find_link(text) + matching_links = links.select do |possible_link| possible_link.matches_text?(text) end diff --git a/lib/webrat/core/scope.rb b/lib/webrat/core/scope.rb index 3d8d8bd..b79b792 100644 --- a/lib/webrat/core/scope.rb +++ b/lib/webrat/core/scope.rb @@ -26,8 +26,8 @@ module Webrat # The field value is required, and must be specified in options[:with]. # field can be either the value of a name attribute (i.e. user[email]) # or the text inside a element that points at the field. - def fill_in(id_or_name_or_label, options = {}) - field = find_field(id_or_name_or_label, TextField, TextareaField, PasswordField) + def fill_in(field_locator, options = {}) + field = locate_field(field_locator, TextField, TextareaField, PasswordField) field.raise_error_if_disabled field.set(options[:with]) end @@ -39,8 +39,8 @@ module Webrat # # Example: # check 'Remember Me' - def check(id_or_name_or_label) - find_field(id_or_name_or_label, CheckboxField).check + def check(field_locator) + locate_field(field_locator, CheckboxField).check end alias_method :checks, :check @@ -50,8 +50,8 @@ module Webrat # # Example: # uncheck 'Remember Me' - def uncheck(id_or_name_or_label) - find_field(id_or_name_or_label, CheckboxField).uncheck + def uncheck(field_locator) + locate_field(field_locator, CheckboxField).uncheck end alias_method :unchecks, :uncheck @@ -61,8 +61,8 @@ module Webrat # # Example: # choose 'First Option' - def choose(label) - find_field(label, RadioField).choose + def choose(field_locator) + locate_field(field_locator, RadioField).choose end alias_method :chooses, :choose @@ -89,8 +89,8 @@ module Webrat # Example: # attaches_file "Resume", "/path/to/the/resume.txt" # attaches_file "Photo", "/path/to/the/image.png", "image/png" - def attaches_file(id_or_name_or_label, path, content_type = nil) - find_field(id_or_name_or_label, FileField).set(path, content_type) + def attaches_file(field_locator, path, content_type = nil) + locate_field(field_locator, FileField).set(path, content_type) end alias_method :attach_file, :attaches_file @@ -146,6 +146,14 @@ module Webrat protected + def locate_field(field_locator, *field_types) + if field_locator.is_a?(Field) + field_locator + else + field(field_locator, *field_types) + end + end + def scoped_html @scoped_html ||= begin if @selector @@ -162,8 +170,8 @@ module Webrat end end - def links_within(selector) - (dom / selector / "a[@href]").map do |link_element| + def links + (dom / "a[@href]").map do |link_element| Link.new(@session, link_element) end end diff --git a/lib/webrat/core_extensions/detect_mapped.rb b/lib/webrat/core_extensions/detect_mapped.rb new file mode 100644 index 0000000..e7a5a66 --- /dev/null +++ b/lib/webrat/core_extensions/detect_mapped.rb @@ -0,0 +1,12 @@ +class Array + + def detect_mapped + each do |element| + result = yield element + return result if result + end + + return nil + end + +end \ No newline at end of file