module Watir
# This module contains the factory methods that are used to access most html objects
#
# For example, to access a button on a web page that has the following html
#
#
# the following watir code could be used
#
# ie.button(:name, 'b1').click
#
# or
#
# ie.button(:value, 'Click Me').to_s
#
# there are many methods available to the Button object
#
# Is includable for classes that have @container, document and ole_inner_elements
module Container
include Watir::Exception
# Note: @container is the container of this object, i.e. the container
# of this container.
# In other words, for ie.table().this_thing().text_field().set,
# container of this_thing is the table.
# This is used to change the typing speed when entering text on a page.
attr_accessor :typingspeed
attr_accessor :type_keys
# The color we want to use for the active object. This can be any valid web-friendly color.
attr_accessor :activeObjectHighLightColor
# The PageContainer object containing this element
attr_accessor :page_container
def copy_test_config(container) # only used by form and frame
@typingspeed = container.typingspeed
@type_keys = container.type_keys
@activeObjectHighLightColor = container.activeObjectHighLightColor
end
private :copy_test_config
# Write the specified string to the log.
def log(what)
@container.logger.debug(what) if @logger
end
# Wait until Internet Explorer has finished loading the page.
def wait(no_sleep=false)
@container.wait(no_sleep)
end
# Determine the how and what when defaults are possible.
def process_default(default_attribute, how, what)
if what.nil? && String === how
what = how
how = default_attribute
end
return how, what
end
private :process_default
def set_container container
@container = container
@page_container = container.page_container
end
private
def self.def_creator(method_name, klass_name=nil)
klass_name ||= method_name.to_s.capitalize
class_eval "def #{method_name}(how, what=nil)
#{klass_name}.new(self, how, what)
end"
end
def self.def_creator_with_default(method_name, default_symbol)
klass_name = method_name.to_s.capitalize
class_eval "def #{method_name}(how, what=nil)
how, what = process_default :#{default_symbol}, how, what
#{klass_name}.new(self, how, what)
end"
end
#
# Factory Methods
#
# this method is the main way of accessing a frame
# * how - how the frame is accessed. This can also just be the name of the frame.
# * what - what we want to access.
#
# Valid values for 'how' are listed in the Watir Wiki - http://wiki.openqa.org/display/WTR/Methods+supported+by+Element
#
# returns a Frame object
#
# Typical usage:
#
# ie.frame(:index, 1)
# ie.frame(:name, 'main_frame')
# ie.frame('main_frame') # in this case, just a name is supplied
public
def frame(how, what=nil)
how, what = process_default :name, how, what
Frame.new(self, how, what)
end
# this method is used to access a form.
# available ways of accessing it are, :index, :name, :id, :method, :action, :xpath
# * how - symbol - What mecahnism we use to find the form, one of
# the above. NOTE if what is not supplied this parameter is the NAME of the form
# * what - String - the text associated with the symbol
#
# Valid values for 'how' are listed in the Watir Wiki - http://wiki.openqa.org/display/WTR/Methods+supported+by+Element
#
# returns a Form object
def form(how, what=nil)
how, what = process_default :name, how, what
Form.new(self, how, what)
end
# This method is used to get a table from the page.
# :index (1 based counting) and :id are supported.
# NOTE :name is not supported, as the table tag does not have a name attribute. It is not part of the DOM.
# :index can be used when there are multiple tables on a page.
# :xpath can be used to select table using XPath query.
# The first form can be accessed with :index 1, the second :index 2, etc.
# * how - symbol - how we access the table, :index, :id, :xpath etc
# * what - string the thing we are looking for, ex. id, index or xpath query, of the object we are looking for
#
# Valid values for 'how' are listed in the Watir Wiki - http://wiki.openqa.org/display/WTR/Methods+supported+by+Element
#
# returns a Table object
def table(how, what=nil)
Table.new(self, how, what)
end
# this is the main method for accessing the tables iterator. It returns a Tables object
#
# Typical usage:
#
# ie.tables.each { |t| puts t.to_s } # iterate through all the tables on the page
# ie.tables[1].to_s # goto the first table on the page
# ie.tables.length # show how many tables are on the page. Tables that are nested will be included in this
def tables
Tables.new(self)
end
# this method accesses a table cell.
# how - symbol - how we access the cell, valid values are
# :id - find the table cell with given id.
# :xpath - find the table cell using xpath query.
#
# returns a TableCell Object
def cell(how, what=nil)
TableCell.new(self, how, what)
end
def cells
TableCells.new(self)
end
# this method accesses a table row.
# how - symbol - how we access the row, valid values are
# :id - find the table row with given id.
# :xpath - find the table row using xpath query.
#
# returns a TableRow object
def row(how, what=nil)
TableRow.new(self, how, what)
end
def rows
TableRows.new(self)
end
# Access a modal web dialog, which is a PageContainer, like IE or Frame.
# Returns a ModalDialog object.
#
# Typical Usage
# ie.modal_dialog # access the modal dialog of ie
# ie.modal_dialog(:title, 'Title') # access the modal dialog by title
# ie.modal_dialog.modal_dialog # access a modal dialog's modal dialog XXX untested!
#
# This method will not work when
# Watir/Ruby is run under a service (instead of a user).
# Note: unlike Watir.attach, this returns before the page is assured to have
# loaded.
def modal_dialog(how=nil, what=nil)
ModalDialog.new(self, how, what)
end
# This is the main method for accessing a button. Often declared as an tag.
# * how - symbol - how we access the button, :index, :id, :name etc
# * what - string, integer or regular expression - what we are looking for,
#
# Valid values for 'how' are listed in the Watir Wiki - http://wiki.openqa.org/display/WTR/Methods+supported+by+Element
#
# Returns a Button object.
#
# Typical usage
#
# ie.button(:id, 'b_1') # access the button with an ID of b_1
# ie.button(:name, 'verify_data') # access the button with a name of verify_data
# ie.button(:value, 'Login') # access the button with a value (the text displayed on the button) of Login
# ie.button(:caption, 'Login') # same as above
# ie.button(:value, /Log/) # access the button that has text matching /Log/
# ie.button(:index, 2) # access the second button on the page (1 based, so the first button is accessed with :index,1)
# ie.button(:class, 'my_custom_button_class') # access the button with a class of my_custom_button_class
# ie.button(:xpath, "//input[@value='Click Me']/") # access the button with a value of Click Me
#
# Accessing a Button nested within another element
# ie.div(:class, 'xyz').button(:index, 2) # access a div of class xyz, and the 2nd button within that div
#
# If only a single parameter is supplied, then :value is used
# ie.button('Click Me') # access the button with a value of Click Me
def button(how, what=nil)
how, what = process_default :value, how, what
Button.new(self, how, what)
end
# this is the main method for accessing the buttons iterator. It returns a Buttons object
#
# Typical usage:
#
# ie.buttons.each { |b| puts b.to_s } # iterate through all the buttons on the page
# ie.buttons[1].to_s # goto the first button on the page
# ie.buttons.length # show how many buttons are on the page.
def buttons
Buttons.new(self)
end
# This is the main method for accessing a file field. Usually an HTML tag.
# * how - symbol - how we access the field, valid values are
# :index - find the file field using index
# :id - find the file field using id attribute
# :name - find the file field using name attribute
# :xpath - find the file field using xpath query
# * what - string, integer, regular expression, or xpath query - what we are looking for,
#
# returns a FileField object
#
# Typical Usage
#
# ie.file_field(:id, 'up_1') # access the file upload field with an ID of up_1
# ie.file_field(:name, 'upload') # access the file upload field with a name of upload
# ie.file_field(:index, 2) # access the second file upload on the page (1 based, so the first field is accessed with :index,1)
#
def file_field(how, what=nil)
FileField.new(self, how, what)
end
# this is the main method for accessing the file_fields iterator. It returns a FileFields object
#
# Typical usage:
#
# ie.file_fields.each { |f| puts f.to_s } # iterate through all the file fields on the page
# ie.file_fields[1].to_s # goto the first file field on the page
# ie.file_fields.length # show how many file fields are on the page.
def file_fields
FileFields.new(self)
end
# This is the main method for accessing a text field. Usually an HTML tag. or a text area - a