class OperaWatir::Element extend Forwardable attr_reader :node def initialize(node) @node = node end # TODO Need support for this in Webdriver def hash node.hashCode end def ==(other) node.equals other.node end def eql?(other) is_a?(other.class) && self == other end def hash node.hashCode end # Attributes def attr(name) node.getAttribute(name.to_s) end # TODO Move to Webdriver # Relies on getAttribute returning nil def has_attribute?(name) !attr(name).nil? end def method_missing(method, *args, &blk) if !(block_given? || !args.empty?) && has_attribute?(method) attr(method) else super end end def id attr(:id) end def type attr(:type) end def class_name attr(:class) end def_delegator :node, :isEnabled, :enabled? def_delegator :node, :isSelected, :checked? def_delegator :node, :setSelected, :select def_delegator :node, :isSelected, :selected? def_delegator :node, :toggle, :toggle_check! def_delegator :node, :getText, :text def_delegator :node, :getHTML, :html def_delegator :node, :clear, :clear def tag_name node.callMethod('locator.nodeName') end # On elements of type `input`, `textarea` or `select` it will fetch # the texteditable `value` attribute, on every other element type it # returns the DOM attribute `value`. # # @return [String] Value of the element. def value =begin if tag_name =~ /input|textarea|select/i node.getValue # elsif tag_name =~ /button/i text # getVisibleContents else attr :value # attribute @value end =end #node.getValue attr('value') end # # Does the element exist in the DOM? # # @return [Boolean] True if element exists, false otherwise. # def exist? !!!tag_name.empty? end alias_method :exists?, :exist? # LOL Ruby def disabled? !enabled? end def check! node.toggle if not selected? end def uncheck! node.toggle if selected? end # Events # # Clicks on the top left of the element, or the given x,y offset # relative to the element. # # @param [Integer] x The offset from the top left of the element. # @param [Integer] y The offset from the top of the element. # def click(x=1, y=1) node.click(x.to_i, y.to_i) end def click_async node.click 1 end def double_click node.click 2 end def triple_click node.click 3 end def quadruple_click node.click 4 end def right_click node.rightClick end def middle_click node.middleClick end def drag_and_drop_on(other) node.dragAndDropOn other.node end def drag_and_drop_by(x, y) node.dragAndDropBy(x.to_i, y.to_i) end def_delegator :node, :submit, :submit! def text=(input) if attr(:type) =~ /checkbox/i toggle_check! unless checked? else # Focus before typing clear unless value.empty? node.sendKeys(input.to_s.split('').to_java(:string)) end end alias_method :set, :text= alias_method :value=, :text= def send_keys(*list) raise Exceptions::NotImplementedException end # FIXME: This should be migrated to using browserbot.js, as watir-webdriver # is using. def fire_event(event, x = 0, y = 0) loc = location x += loc[:x] y += loc[:y] # In the case that event is given as symbol, we convert it to a # string. event = event.to_s event =~ /on(.*)/i event = $1 if $1 event = event.downcase.to_sym case event when :abort, :blur, :change, :error, :focus, :load, :reset, :resize, :scroll, :submit, :unload type = 'HTMLEvents'; init = "initEvent(\"#{event.to_s}\", true, true)" when :click, :dblclick, :mousedown, :mousemove, :mouseout, :mouseover, :mouseup type = 'MouseEvents' init = "initMouseEvent(\"#{event.to_s}\", true, true, window, 1, 0, 0, #{x}, #{y}, false, false, false, false, 0, null)" else raise Exceptions::NotImplementedException, "Event on#{event} is not a valid ECMAscript event for OperaWatir." end script = "var event = document.createEvent(\"#{type}\"); " + "event.#{init}; " + "locator.dispatchEvent(event);" node.callMethod(script) end def visible? node.isVisible end # UI def screenshot(file_name, time_out) node.saveScreenshot(file_name, time_out) end def_delegator :node, :getImageHash, :visual_hash def location loc = node.getLocation {:x => loc.x.to_i, :y => loc.y.to_i} end private # Finders def find_elements_by_id(value) node.findElementsById(value).to_a.map do |n| OperaWatir::Element.new(n) end end def find_elements_by_class_name(value) node.findElementsByClassName(value).to_a.map do |n| OperaWatir::Element.new(n) end end def find_elements_by_tag_name(value) node.findElementsByTagName(value).to_a.map do |n| OperaWatir::Element.new(n) end end def find_elements_by_css(value) node.findElementsByCssSelector(value).to_a.map do |n| OperaWatir::Element.new(n) end end def find_elements_by_xpath(value) node.findElementsByXPath(value).to_a.map do |n| OperaWatir::Element.new(n) end end def find_elements_by_name(value) node.findElementsByName(value).to_a.map do |n| OperaWatir::Element.new(n) end end end