module Symbiont module Platforms module WatirWebDriver class PlatformObject def initialize(browser) @browser = browser end ## Browser-Level Actions ## def visit(url) @browser.goto(url) end def url @browser.url end def screenshot(file) @browser.wd.save_screenshot(file) end def run_script(script) @browser.execute_script(script) end def back @browser.back end def forward @browser.forward end def refresh @browser.refresh end def remove_cookies @browser.cookies.clear end ## Page-Level Actions ## def text @browser.text end def markup @browser.html end def title @browser.title end def focus web_object = @browser.execute_script("return document.activeElement") type = web_object.type.to_sym if web_object.tag_name.to_sym == :input object_class = ::Symbiont::WebObjects.get_class_for(web_object.tag_name, type) object_class.new(web_object) end ## Encloser Methods ## # Platform method to wait for an action to complete in a given time. # @see Symbiont::Enclosers#wait_for def wait_for(timeout, message="wait condition not found", &block) @browser.wait_until(timeout, message, &block) end # Platform method to reference web objects in the context of a # window. # @see Symbiont::Enclosers#within_window def within_window(locator, &block) identifier = {locator.keys.first => /#{Regexp.escape(locator.values.first)}/} @browser.window(identifier).use(&block) end def within_frame(locator, encloser=nil, &block) encloser = [] if encloser.nil? encloser << locator block.call(encloser) end # Platform method to handle an alert message box. # @see Symbiont::Enclosers#will_alert def will_alert(encloser=nil, &block) switch_to_frame(encloser) yield value = nil if @browser.alert.exists? value = @browser.alert.text @browser.alert.ok end ### ##@browser.wd.execute_script("window.alert = function(msg) { window.__lastWatirAlert=msg; }") ##yield ##value = @browser.wd.execute_script("return window.__lastWatirAlert") switch_to_default_content(encloser) value end # Platform method to handle a confirmation message box # @see Symbiont::Enclosers#will_confirm def will_confirm(response, encloser=nil, &block) switch_to_frame(encloser) yield value = nil if @browser.alert.exists? value = @browser.alert.text response ? @browser.alert.ok : @browser.alert.close end ##@browser.wd.execute_script("window.confirm = function(msg) { window.__lastWatirConfirm=msg; return #{!!response} }") ##yield ##value = @browser.wd.execute_script("return window.__lastWatirConfirm") switch_to_default_content(encloser) value end # Platform method to handle a prompt message box. # @see Symbiont::Enclosers#will_prompt def will_prompt(response, encloser=nil, &block) switch_to_frame(encloser) @browser.wd.execute_script("window.prompt = function(text, value) { window.__lastWatirPrompt = { message: text, default_value: value }; return #{!!response}; }") yield result = @browser.wd.execute_script("return window.__lastWatirPrompt") switch_to_default_content(encloser) result && result.dup.each_key { |k| result[k.to_sym] = result.delete(k) } result end ## Generator Methods ## ## Paragraphs ## def paragraph_element(locator) reference_web_object("p(locator)", WebObjects::Paragraph, locator, 'p') end def paragraph_text_for(locator) access_web_object("p(locator).text", WebObjects::Paragraph, locator, nil, 'p') end ## Labels ## def label_element(locator) reference_web_object("label(locator)", WebObjects::Label, locator, 'label') end def label_text_for(locator) access_web_object("label(locator).text", WebObjects::Label, locator, nil, 'label') end ## Links ## def link_element(locator) reference_web_object("link(locator)", WebObjects::Link, locator) end def click_link_for(locator) access_web_object("link(locator).click", WebObjects::Link, locator) end ## Buttons ## def button_element(locator) reference_web_object("button(locator)", WebObjects::Button, locator) end def click_button_for(locator) access_web_object("button(locator).click", WebObjects::Button, locator) end ## Text Fields ## def text_field_element(locator) reference_web_object("text_field(locator)", WebObjects::TextField, locator) end def get_text_field_value_for(locator) access_web_object("text_field(locator).value", WebObjects::TextField, locator) end def set_text_field_value_for(locator, value) access_web_object("text_field(locator).set(value)", WebObjects::TextField, locator, value) end ## Text Areas ## def text_area_element(locator) reference_web_object("text_area(locator)", WebObjects::TextArea, locator) end def get_text_area_value_for(locator) access_web_object("text_area(locator).value", WebObjects::TextArea, locator) end def set_text_area_value_for(locator, value) access_web_object("text_area(locator).set(value)", WebObjects::TextArea, locator, value) end ## Hidden Fields ## def hidden_field_element(locator) reference_web_object("hidden(locator)", WebObjects::HiddenField, locator) end def get_hidden_field_value_for(locator) access_web_object("hidden(locator).value", WebObjects::HiddenField, locator) end ## Checkboxes ## def checkbox_element(locator) reference_web_object("checkbox(locator)", WebObjects::CheckBox, locator) end def check_checkbox_for_checked(locator) access_web_object("checkbox(locator).set?", WebObjects::CheckBox, locator) end def check_checkbox_for(locator) access_web_object("checkbox(locator).set", WebObjects::CheckBox, locator) end def uncheck_checkbox_for(locator) access_web_object("checkbox(locator).clear", WebObjects::CheckBox, locator) end ## Select Lists ## def select_list_element(locator) reference_web_object("select_list(locator)", WebObjects::SelectList, locator) end def get_select_list_item_for(locator) access_web_object("select_list(locator).selected_options[0].text", WebObjects::SelectList, locator) # Should I consider: select_list(identifier).options.find {|o| o.selected?}.text end def get_select_list_value_for(locator) access_web_object("select_list(locator).value", WebObjects::SelectList, locator) end def set_select_list_value_for(locator, value) access_web_object("select_list(locator).select(value)", WebObjects::SelectList, locator, value) end ## Radios ## def radio_element(locator) reference_web_object("radio(locator)", WebObjects::Radio, locator) end def check_radio_for_selected(locator) access_web_object("radio(locator).set?", WebObjects::Radio, locator) end def select_radio_for(locator) access_web_object("radio(locator).set", WebObjects::Radio, locator) end ## Table Elements ## def table_element(locator) reference_web_object("table(locator)", WebObjects::Table, locator, 'table') end def table_text_for(locator) access_web_object("table(locator).text", WebObjects::Table, locator, nil, 'table') end def cell_element(locator) reference_web_object("td(locator)", WebObjects::TableCell, locator, 'td') end def get_table_cell_text_for(locator) access_web_object("td(locator).text", WebObjects::TableCell, locator, nil, 'td') end ## Sectional Elements ## def div_element(locator) reference_web_object("div(locator)", WebObjects::Div, locator, 'div') end def div_text_for(locator) access_web_object("div(locator).text", WebObjects::Div, locator, nil, 'div') end def span_element(locator) reference_web_object("span(locator)", WebObjects::Span, locator, 'span') end def span_text_for(locator) access_web_object("span(locator).text", WebObjects::Span, locator, nil, 'span') end ## Header Elements ## def h1_element(locator) reference_web_object("h1(locator)", WebObjects::Heading, locator, 'h1') end def h1_text_for(locator) access_web_object("h1(locator).text", WebObjects::Heading, locator, nil, 'h1') end def h2_element(locator) reference_web_object("h2(locator)", WebObjects::Heading, locator, 'h2') end def h2_text_for(locator) access_web_object("h2(locator).text", WebObjects::Heading, locator, nil, 'h2') end ## List Elements ## def ordered_list_element(locator) reference_web_object("ol(locator)", WebObjects::OrderedList, locator, 'ol') end def ordered_list_text_for(locator) access_web_object("ol(locator).text", WebObjects::OrderedList, locator, nil, 'ol') end def ordered_lists_elements(locator) reference_web_object("ols(locator)", WebObjects::OrderedList, locator, 'ol') end def unordered_list_element(locator) reference_web_object("ul(locator)", WebObjects::UnorderedList, locator, 'ul') end def unordered_list_text_for(locator) access_web_object("ul(locator).text", WebObjects::UnorderedList, locator, nil, 'ul') end def unordered_lists_elements(locator) reference_web_object("uls(locator)", WebObjects::UnorderedList, locator, 'ul') end def list_item_element(locator) reference_web_object("li(locator)", WebObjects::ListItem, locator, 'li') end def list_item_text_for(locator) access_web_object("li(locator).text", WebObjects::ListItem, locator, nil, 'li') end def list_items_elements(locator) reference_web_object("lis(locator)", WebObjects::ListItem, locator, 'li') end private # This method is called by any platform methods that require getting # an object reference. # # @param [String] action the driver logic to be sent to the browser # @param [Object] object_type the type of web object that will receive the action # @param [Hash] locator the specific web object selector, mainly for parsing # @return [Object] the web object identified by the action def reference_web_object(action, object_type, locator, object_tag=nil) #puts "[ref_obj] Locator (1): #{locator}" locator, enclosers = qualify_locators(locator, object_type, object_tag) #puts "[ref_obj] Locator (2): #{locator}" web_object = @browser.instance_eval "#{enclosed_by(enclosers)}#{action}" switch_to_default_content(enclosers) object_type.new(web_object) end # This method is called by any platform methods that require accessing # a web object with the intent of manipulating it or getting information # from it. # # @param [String] action the driver logic to be sent to the browser # @param [Hash] locator the specific web object selector, mainly for parsing # @param [String] value any specific information that must be sent to the web object # @param [String] object_tag the tag that represents the web object in a browser # # @return [Any] the information or object returned by the action def access_web_object(action, object_type, locator, value=nil, object_tag=nil) #puts "[acc_obj] Locator (1): #{locator}" locator, enclosers = qualify_locators(locator, object_type, object_tag) #puts "[acc_obj] Locator (2): #{locator}" web_object = @browser.instance_eval "#{enclosed_by(enclosers)}#{action}" switch_to_default_content(enclosers) web_object end # This method is used to qualify any locators with necessary information that # is required to find the web objects during execution. # # @param [String] locator the locator being used # @param [Object] object_type the object type that the locator applies to # @param [String] object_tag the tag that represents the web object in a browser def qualify_locators(locator, object_type, object_tag=nil) enclosers = locator.delete(:frame) #puts "[qualify] Locator (1): #{locator}" locator = use_tagname_for_name(locator, object_tag) if object_tag #puts "[qualify] Locator (2): #{locator}" locator = object_type.provide_locator_for(locator) #puts "[qualify] Locator (3): #{locator}" return locator, enclosers end # This method uses an object tag for the locator for a web object # if the locator being used was :name. # # @param [String] locator the locator being used # @param [String] object_tag the tag that represents the web object in a browser def use_tagname_for_name(locator, object_tag) #puts "[use_tagname] Locator (1): #{locator}" return locator if locator.length < 2 and not locator[:name] locator[:tag_name] = object_tag if locator[:name] #puts "[use_tagname] Locator (2): #{locator}" locator end # This method is used to wrap a web object locator within the locator for an # enclosing web object. Currently the only enclosing objects this makes sense # for are iframes and frames. # # @param [Hash] enclosers locator information for enclosing web objects # @return [Hash] driver-specific frame selector def enclosed_by(enclosers) return if enclosers.nil? key = enclosers[0].keys.first value = enclosers[0].values.first encloser_locator = "frame(:#{key} => '#{value}')." end def switch_to_default_content(locator) @browser.wd.switch_to.default_content unless locator.nil? end def switch_to_frame(locator) unless locator.nil? locator.each do |frame| value = frame.values.first @browser.wd.switch_to.frame(value) end end end end # class: PlatformObject end # module: WatirWebDriver end # module: Platforms end # module: Symbiont require 'symbiont/web_objects' Dir["#{File.dirname(__FILE__)}/../web_objects/**/*.rb"].sort.each { |file| require file }