2
votes

considering this simple Page Object:

require 'watir-webdriver'
require 'page-object'

class SomePage
  include PageObject

  text_field :first_name, :name => "fname"
  text_field :last_name, :name => "lname" 
  text_field :birth_date, :name => "birthday" 
  button :submit, :type => "submit"
end

browser = Watir::Browser.new

page = SomePage.new(browser)

is there a way to iterate over all the text fields (or any elements) to access their "identifier" (i.e. :username, :password or :birth)?

something like:

page.text_fields.each do |text_field|
  puts text_field.identifier.inspect
end

=> :first_name
=> :last_name
=> :birth_date

I'm just looking to see if I could turn this:

page.first_name = @user.first_name
page.last_name = @user.last_name
etc...

into this:

page.text_fields.each do |text_field|

  attribute = text_field.attribute

  text_field = @user[attribute]

end

Anybody knows what I mean?

3

3 Answers

3
votes

The answers already provided definitely will suite your needs, but I would like to add one additional option that uses a feature built into the page-object gem.

It's call populate_page_with() in page_populator.rb. It's used like this so.

Start with a hash that has the element names(I use a CSV file that is loaded into a hash), as defined on your page object, in the keys. The value of the hash contains the value you wish to populate each element with.

form_data = {first_name: @user.first_name, last_name: @user.last_name, birth_date: @user.birth_date}

@page.populate_page_with form_data

That's it. The populate_page method will find the right elements on the page and populate them with whatever value you have set in your source hash. This works for checkbox, radio buttons and text.

This is a very nice time saving method that Cheezy put in for us!

Thanks Cheezy!

1
votes

The names (:first_name, :last_name, :birth_date) are only used to generate the method names such as first_name=, last_name= and birth_date=. The name is not stored or retained for later use.

That said, you could iterate through the page's instance methods to find the text fields. The following text_fields method will:

  1. Get all of the class instance methods.
  2. Find the methods that end with "_element".
  3. Create an array that includes the element names and element.

The page object would be:

class SomePage
  include PageObject
  text_field :first_name, :name => "fname"
  text_field :last_name, :name => "lname" 
  text_field :birth_date, :name => "birthday" 
  button :submit, :type => "submit"

  def text_fields
    self.class.instance_methods(false)
      .grep(/_element$/)
      .map { |m| 
        element = self.send(m)
        [m[/(.+)_element$/, 1].to_sym, element] if element.kind_of?(PageObject::Elements::TextField)
      }.compact
  end
end

You could then iterate through the text fields with access to their name (or attribute) and the TextField element:

page = SomePage.new(browser)
page.text_fields.each do |attribute, text_field|
  text_field.value = @user[attribute]
end
1
votes

I do exactly the "opposite" :

@user.each do | key, value |
  unless value.empty?
    browser.text_field(label: key).set value
  end
end

I make the job done for the datas I have, and not the fields. It allows to test form fill with only some fields.