require "json" require "capybara/webkit/errors" module Capybara::Webkit class Browser def initialize(connection) @connection = connection apply_defaults end def authenticate(username, password) command("Authenticate", username, password) end def enable_logging command "EnableLogging" end def visit(url) command "Visit", url end def header(key, value) command("Header", key, value) end def title command("Title") end def find_xpath(query) command("FindXpath", query).split(",") end def find_css(query) command("FindCss", query).split(",") end def reset! apply_defaults command("Reset") end def body command("Body") end def status_code command("Status").to_i end def console_messages JSON.parse(command("ConsoleMessages")).map do |message| message.inject({}) { |m,(k,v)| m.merge(k.to_sym => v) } end end def error_messages console_messages.select do |message| message[:message] =~ /Error:/ end end def alert_messages JSON.parse(command("JavascriptAlertMessages")) end def confirm_messages JSON.parse(command("JavascriptConfirmMessages")) end def prompt_messages JSON.parse(command("JavascriptPromptMessages")) end def response_headers JSON.parse(command("Headers")) end def current_url command("CurrentUrl") end def frame_focus(selector=nil) if selector.respond_to?(:base) selector.base.invoke("focus_frame") elsif selector.is_a? Fixnum command("FrameFocus", "", selector.to_s) elsif selector command("FrameFocus", selector) else command("FrameFocus") end end def ignore_ssl_errors command("IgnoreSslErrors") end def set_skip_image_loading(skip_image_loading) command("SetSkipImageLoading", skip_image_loading) end def set_raise_javascript_errors(is_enabled) @raise_javascript_errors = is_enabled end def raise_javascript_errors? @raise_javascript_errors end def window_focus(selector) command("WindowFocus", selector) end def window_open command("WindowOpen") end def window_close(selector) command("WindowClose", selector) end def window_resize(handle, width, height) command("WindowResize", handle, width.to_i, height.to_i) end def window_size(handle) JSON.parse(command("WindowSize", handle)) end def window_maximize(handle) command("WindowMaximize", handle) end def get_window_handles JSON.parse(command('GetWindowHandles')) end def window_handles warn '[DEPRECATION] Capybara::Webkit::Browser#window_handles ' \ 'is deprecated. Please use Capybara::Session#windows instead.' get_window_handles end def get_window_handle command('GetWindowHandle') end def window_handle warn '[DEPRECATION] Capybara::Webkit::Browser#window_handle ' \ 'is deprecated. Please use Capybara::Session#current_window instead.' get_window_handle end def accept_confirm(options) command("SetConfirmAction", "Yes", options[:text]) end def accept_js_confirms command("SetConfirmAction", "Yes") end def reject_confirm(options) command("SetConfirmAction", "No", options[:text]) end def reject_js_confirms command("SetConfirmAction", "No") end def accept_prompt(options) if options[:with] command("SetPromptAction", "Yes", options[:text], options[:with]) else command("SetPromptAction", "Yes", options[:text]) end end def accept_js_prompts command("SetPromptAction", "Yes") end def reject_prompt(options) command("SetPromptAction", "No", options[:text]) end def reject_js_prompts command("SetPromptAction", "No") end def set_prompt_text_to(string) command("SetPromptText", string) end def clear_prompt_text command("ClearPromptText") end def accept_alert(options) command("AcceptAlert", options[:text]) end def find_modal(id) command("FindModal", id) end def url_blacklist=(black_list) warn '[DEPRECATION] Capybara::Webkit::Browser#url_blacklist= ' \ 'is deprecated. Please use page.driver.block_url instead.' command("SetUrlBlacklist", *Array(black_list)) end def command(name, *args) @connection.puts name @connection.puts args.size args.each do |arg| @connection.puts arg.to_s.bytesize @connection.print arg.to_s end check response = read_response check_javascript_errors(name) response rescue SystemCallError => exception @connection.restart raise(Capybara::Webkit::CrashError, <<-MESSAGE.strip) The webkit_server process crashed! #{exception.message} This is a bug in capybara-webkit. For help with this crash, please visit: https://github.com/thoughtbot/capybara-webkit/wiki/Reporting-Crashes MESSAGE end def evaluate_script(script, *args) json = command('Evaluate', script, args.to_json) JSON.parse("[#{json}]").first end def execute_script(script, *args) command('Execute', script, args.to_json) end def render(path, width, height) command "Render", path, width, height end def timeout=(timeout_in_seconds) command "SetTimeout", timeout_in_seconds end def timeout command("GetTimeout").to_i end def set_cookie(cookie) command "SetCookie", cookie end def clear_cookies command "ClearCookies" end def get_cookies command("GetCookies").lines.map{ |line| line.strip }.select{ |line| !line.empty? } end def set_proxy(options = {}) options = default_proxy_options.merge(options) command("SetProxy", options[:host], options[:port], options[:user], options[:pass]) end def clear_proxy command("SetProxy") end def version command("Version") end def go_back command("GoBack") end def go_forward command("GoForward") end def allow_url(url) command("AllowUrl", url) end def block_url(url) command("BlockUrl", url) end def block_unknown_urls command("SetUnknownUrlMode", "block") end def allow_unknown_urls allow_url("*") end private def apply_defaults @raise_javascript_errors = false end def check result = @connection.gets result.strip! if result if result.nil? raise NoResponseError, "No response received from the server." elsif result != 'ok' raise JsonError.new(read_response) end result end def check_javascript_errors(command_name) return if command_name == "ConsoleMessages" if raise_javascript_errors? && error_messages.any? raise JavaScriptError, error_messages end end def read_response response_length = @connection.gets.to_i if response_length > 0 response = @connection.read(response_length) response.force_encoding("UTF-8") if response.respond_to?(:force_encoding) response else "" end end def default_proxy_options { :host => "localhost", :port => "0", :user => "", :pass => "" } end end end