class Metallize::Form

Attributes

action[RW]
buttons[R]
checkboxes[R]
elements[R]
encoding[RW]

Character encoding of form data (i.e. UTF-8)

enctype[RW]

Content-Type for form data (i.e. application/x-www-form-urlencoded)

fields[R]
file_uploads[R]
form_node[R]
ignore_encoding_error[RW]

When true, character encoding errors will never be never raised on form submission. Default is false

method[RW]
name[RW]
page[R]
radiobuttons[R]

Public Class Methods

new(driver, form) click to toggle source
# File lib/metallize/form.rb, line 32
def initialize(driver, form)
  @driver = driver
  @form   = form
  @method = (@form.attribute('method') || 'GET').upcase
  @action = @form.attribute('action')
  parse
end

Public Instance Methods

[](field_name) click to toggle source

Fetch the value of the first input field with the name passed in. Example:

puts form['name']
# File lib/metallize/form.rb, line 206
def [](field_name)
  f = field(field_name)
  f && f.value
end
[]=(field_name, value) click to toggle source

Set the value of the first input field with the name passed in. Example:

form['name'] = 'Aaron'
# File lib/metallize/form.rb, line 213
def []=(field_name, value)
  f = field(field_name)
  if f
    f.value = value
  else
    add_field!(field_name, value)
  end
end
add_field!(field_name, value = nil) click to toggle source

Add a field with field_name and value

# File lib/metallize/form.rb, line 166
def add_field!(field_name, value = nil)
  fields << Field.new({'name' => field_name}, value)
end
dom_class() click to toggle source

This method is a shortcut to get form's DOM class. Common usage:

page.form_with(:dom_class => "foorm")

Note that you can also use :class to get to this method:

page.form_with(:class => "foorm")
# File lib/metallize/form.rb, line 161
def dom_class
  form_node['class']
end
dom_id() click to toggle source

This method is a shortcut to get form's DOM id. Common usage:

page.form_with(:dom_id => "foorm")

Note that you can also use :id to get to this method:

page.form_with(:id => "foorm")
# File lib/metallize/form.rb, line 152
def dom_id
  form_node['id']
end
has_value?(value) click to toggle source
# File lib/metallize/form.rb, line 78
def has_value?(value)
  fields.find { |f| f.value == value }
end
hidden_field?(field_name) click to toggle source

Returns whether or not the form contains a Hidden field named field_name

# File lib/metallize/form.rb, line 138
def hidden_field?(field_name)
  hiddens.find { |f| f.name == field_name }
end
hiddens() click to toggle source

Returns all fields of type Hidden

# File lib/metallize/form.rb, line 108
def hiddens
  @hiddens ||= fields.select { |f| f.class == Hidden }
end
keygens() click to toggle source

Returns all fields of type Keygen

# File lib/metallize/form.rb, line 118
def keygens
  @keygens ||= fields.select { |f| f.class == Keygen }
end
keys() click to toggle source

Returns all field names (keys) for this form

# File lib/metallize/form.rb, line 83
def keys
  fields.map { |f| f.name }
end
parse() click to toggle source
# File lib/metallize/form.rb, line 44
def parse
  @fields       = []
  @buttons      = []

  form_node = @driver.find_elements(:tag_name, 'input')
  form_node.each do |node|
    type = (node.attribute('type') || 'text').downcase
    name = node.attribute('name')
    next if name.nil? && !%w[submit button image].include?(type)
    case type
      when 'submit'
        @buttons << Submit.new(node)
      when 'button'
        @buttons << Button.new(node)
      when 'hidden'
        @fields << Hidden.new(node, node.attribute('value') || '')
      when 'text'
        @fields << Text.new(node, node.attribute('value') || '')
      else
        @fields << Field.new(node, node.attribute('value') || '')
    end

    form_node = @driver.find_elements(:tag_name, 'select')
    form_node.each do |node|
      next unless node['name']
      @fields << SelectList.new(node)
    end

    form_node = @driver.find_elements(:tag_name, 'button')
    form_node.each do |node|
      @buttons << Button.new(node)
    end
  end

  def has_value?(value)
    fields.find { |f| f.value == value }
  end

  # Returns all field names (keys) for this form
  def keys
    fields.map { |f| f.name }
  end

  # Returns all field values for this form
  def values
    fields.map { |f| f.value }
  end

  # Returns all buttons of type Submit
  def submits
    @submits ||= buttons.select { |f| f.class == Submit }
  end

  # Returns all buttons of type Reset
  def resets
    @resets ||= buttons.select { |f| f.class == Reset }
  end

  # Returns all fields of type Text
  def texts
    @texts ||= fields.select { |f| f.class == Text }
  end

  # Returns all fields of type Hidden
  def hiddens
    @hiddens ||= fields.select { |f| f.class == Hidden }
  end

  # Returns all fields of type Textarea
  def textareas
    @textareas ||= fields.select { |f| f.class == Textarea }
  end

  # Returns all fields of type Keygen
  def keygens
    @keygens ||= fields.select { |f| f.class == Keygen }
  end

  # Returns whether or not the form contains a Submit button named +button_name+
  def submit_button?(button_name)
    submits.find { |f| f.name == button_name }
  end

  # Returns whether or not the form contains a Reset button named +button_name+
  def reset_button?(button_name)
    resets.find { |f| f.name == button_name }
  end

  # Returns whether or not the form contains a Text field named +field_name+
  def text_field?(field_name)
    texts.find { |f| f.name == field_name }
  end

  # Returns whether or not the form contains a Hidden field named +field_name+
  def hidden_field?(field_name)
    hiddens.find { |f| f.name == field_name }
  end

  # Returns whether or not the form contains a Textarea named +field_name+
  def textarea_field?(field_name)
    textareas.find { |f| f.name == field_name }
  end

  # This method is a shortcut to get form's DOM id.
  # Common usage:
  #   page.form_with(:dom_id => "foorm")
  # Note that you can also use +:id+ to get to this method:
  #   page.form_with(:id => "foorm")
  def dom_id
    form_node['id']
  end

  # This method is a shortcut to get form's DOM class.
  # Common usage:
  #   page.form_with(:dom_class => "foorm")
  # Note that you can also use +:class+ to get to this method:
  #   page.form_with(:class => "foorm")
  def dom_class
    form_node['class']
  end

  # Add a field with +field_name+ and +value+
  def add_field!(field_name, value = nil)
    fields << Field.new({'name' => field_name}, value)
  end

  ##
  # This method sets multiple fields on the form.  It takes a list of +fields+
  # which are name, value pairs.
  #
  # If there is more than one field found with the same name, this method will
  # set the first one found.  If you want to set the value of a duplicate
  # field, use a value which is a Hash with the key as the index in to the
  # form.  The index is zero based.
  #
  # For example, to set the second field named 'foo', you could do the
  # following:
  #
  #   form.set_fields :foo => { 1 => 'bar' }
  def set_fields fields = {}
    fields.each do |name, v|
      case v
        when Hash
          v.each do |index, value|
            self.fields_with(:name => name.to_s)[index].value = value
          end
        else
          value = nil
          index = 0

          [v].flatten.each do |val|
            index = val.to_i if value
            value = val unless value
          end

          self.fields_with(:name => name.to_s)[index].value = value
      end
    end
  end

  # Fetch the value of the first input field with the name passed in. Example:
  #  puts form['name']
  def [](field_name)
    f = field(field_name)
    f && f.value
  end

  # Set the value of the first input field with the name passed in. Example:
  #  form['name'] = 'Aaron'
  def []=(field_name, value)
    f = field(field_name)
    if f
      f.value = value
    else
      add_field!(field_name, value)
    end
  end

end
reset_button?(button_name) click to toggle source

Returns whether or not the form contains a Reset button named button_name

# File lib/metallize/form.rb, line 128
def reset_button?(button_name)
  resets.find { |f| f.name == button_name }
end
resets() click to toggle source

Returns all buttons of type Reset

# File lib/metallize/form.rb, line 98
def resets
  @resets ||= buttons.select { |f| f.class == Reset }
end
set_fields(fields = {}) click to toggle source

This method sets multiple fields on the form. It takes a list of fields which are name, value pairs.

If there is more than one field found with the same name, this method will set the first one found. If you want to set the value of a duplicate field, use a value which is a Hash with the key as the index in to the form. The index is zero based.

For example, to set the second field named 'foo', you could do the following:

form.set_fields :foo => { 1 => 'bar' }
# File lib/metallize/form.rb, line 183
def set_fields fields = {}
  fields.each do |name, v|
    case v
      when Hash
        v.each do |index, value|
          self.fields_with(:name => name.to_s)[index].value = value
        end
      else
        value = nil
        index = 0

        [v].flatten.each do |val|
          index = val.to_i if value
          value = val unless value
        end

        self.fields_with(:name => name.to_s)[index].value = value
    end
  end
end
submit() click to toggle source
# File lib/metallize/form.rb, line 252
def submit
  # 1. Loop through the non hidden fields and if they're active and displayed enter the value
  @fields.each do |field|
    unless field.kind_of?(Metallize::Form::Hidden)

      element = @driver.find_element(name: field.name)
      if element.displayed? and !field.value.empty?
        element.send_keys field.value
      end

    end
  end

  # 2. Submit Form
  @buttons.first.node.click

  wait_for_page(@driver)

  # 4. Return new Page
  Metallize::Page.new(@driver)

end
submit_button?(button_name) click to toggle source

Returns whether or not the form contains a Submit button named button_name

# File lib/metallize/form.rb, line 123
def submit_button?(button_name)
  submits.find { |f| f.name == button_name }
end
submits() click to toggle source

Returns all buttons of type Submit

# File lib/metallize/form.rb, line 93
def submits
  @submits ||= buttons.select { |f| f.class == Submit }
end
text_field?(field_name) click to toggle source

Returns whether or not the form contains a Text field named field_name

# File lib/metallize/form.rb, line 133
def text_field?(field_name)
  texts.find { |f| f.name == field_name }
end
textarea_field?(field_name) click to toggle source

Returns whether or not the form contains a Textarea named field_name

# File lib/metallize/form.rb, line 143
def textarea_field?(field_name)
  textareas.find { |f| f.name == field_name }
end
textareas() click to toggle source

Returns all fields of type Textarea

# File lib/metallize/form.rb, line 113
def textareas
  @textareas ||= fields.select { |f| f.class == Textarea }
end
texts() click to toggle source

Returns all fields of type Text

# File lib/metallize/form.rb, line 103
def texts
  @texts ||= fields.select { |f| f.class == Text }
end
values() click to toggle source

Returns all field values for this form

# File lib/metallize/form.rb, line 88
def values
  fields.map { |f| f.value }
end
wait_for_page(driver) click to toggle source
# File lib/metallize/form.rb, line 275
def wait_for_page(driver)
  # 3. Wait for the Page State to Return
  wait = Selenium::WebDriver::Wait.new(:timeout => 10)
  wait.until {
    driver.execute_script("return document.readyState;") == "complete"
  }
end