require 'securerandom' module Watir # A PageContainer contains an HTML Document. In other words, it is a # what JavaScript calls a Window. module PageContainer include Watir::Exception # Execute the given JavaScript string in the context of the current page. # # @example # browser.execute_script "var a=1; var b=a+1; return b" # # @example # browser.execute_script("return {a: 1, b: 2}")["b"] # => 1 # # @note It is needed to call return inside of the JavaScript if the value # is needed at Ruby side. # # @return [Object] appropriate type of the object, which is returned from the # JavaScript via "return" keyword or nil when "return" is omitted. def execute_script(source) result = nil begin source = with_json2_if_needed source result = document.parentWindow.eval(source) rescue WIN32OLERuntimeError, NoMethodError #if eval fails we need to use execScript(source.to_s) which does not return a value, hence the workaround escaped_src = source.gsub(/\r?\n/, "\\n").gsub("'", "\\\\'") wrapper = "_watir_helper_div_#{SecureRandom.uuid}" cmd = "var e = document.createElement('DIV'); e.style.display='none'; e.id='#{wrapper}'; e.innerHTML = eval('#{escaped_src}'); document.body.appendChild(e);" document.parentWindow.execScript(cmd) result = document.getElementById(wrapper).innerHTML end MultiJson.load(result)["value"] rescue nil end # @return [String] html of the current page. def html page.outerhtml end # @return [String] url of the page. def url page.document.location.href end # @return [String] text of the page. def text page.innertext.strip end # @deprecated Use "browser.text.include?(target)" or "browser.text.match(target) instead." def contains_text(target) Kernel.warn "Deprecated(Element#contains_text) - use \"browser.text.include?(target)\" or \"browser.text.match(target)\" instead." if target.kind_of? Regexp self.text.match(target) elsif target.kind_of? String self.text.index(target) else raise ArgumentError, "Argument #{target} should be a string or regexp." end end # @private def set_container container @container = container @page_container = self end private def with_json2_if_needed source %Q[ (function() { if (!window.JSON || !window.JSON.stringify) { var json2=document.createElement('script'); json2.type='text/javascript'; json2.src='file:///#{File.expand_path(File.dirname(__FILE__) + "/ext/json2.js")}'; document.getElementsByTagName('head')[0].appendChild(json2) } return JSON.stringify({value: (function() {#{source}})()}); })() ] end # The HTML Page def page document.documentelement end end # module end