lib/honeydew/device.rb in honeydew-0.12.0 vs lib/honeydew/device.rb in honeydew-0.14.0

- old
+ new

@@ -1,79 +1,114 @@ -require "honeydew/device_matchers" -require "honeydew/device_actions" +require 'net/http' +require 'honeydew/device_matchers' +require 'honeydew/device_actions' + module Honeydew class Device include Honeydew::DeviceActions include Honeydew::DeviceMatchers + ServerTimeoutError = Class.new(Timeout::Error) + ActionFailedError = Class.new(Timeout::Error) + FinderTimeout = Class.new(Timeout::Error) + attr_reader :serial, :port def initialize(serial) - if serial.to_s.empty? - raise ArgumentError, 'HoneyDew: Invalid serial or no device connected' + @serial = serial + + unless Honeydew.attached_devices.include?(@serial) + raise ArgumentError, "No device with serial #{@serial} attached" end + @port = Honeydew.config.obtain_new_port - @serial = serial - start_uiautomator_server + start_honeydew_server end - def contains_textview_text?(text, timeout = Honeydew.config.timeout) - response = has_textview_text? text, timeout - response['success'] - rescue - false + def using_timeout timeout + old_timeout = Honeydew.config.timeout + Honeydew.config.timeout = timeout + yield + ensure + Honeydew.config.timeout = old_timeout end - def contains_element_with_description?(description, timeout = Honeydew.config.timeout) - response = has_element_with_description? description, timeout - response['success'] - rescue - false + private + + def perform_assertion action, arguments = {}, options = {} + ensure_device_ready + + log "performing assertion #{action} with arguments #{arguments}" + Timeout.timeout Honeydew.config.timeout.to_i, FinderTimeout do + begin + send_command action, arguments + rescue ActionFailedError + sleep 0.3 + retry + end + end + + rescue FinderTimeout end - def contains_button?(text, timeout = Honeydew.config.timeout) - response = has_button? text, timeout - response['success'] - rescue - false + def perform_action action, arguments = {}, options = {} + ensure_device_ready + + log "performing action #{action} with arguments #{arguments}" + send_command action, arguments end - def is_app_installed?(package_name) - has_app_installed?(package_name) + def send_command action, arguments + uri = device_endpoint('/command') + + request = Net::HTTP::Post.new uri.path + request.set_form_data action: action, arguments: arguments.to_json.to_s + + response = Net::HTTP.start(uri.hostname, uri.port) do |http| + http.read_timeout = Honeydew.config.server_timeout + http.request request + end + + case response + when Net::HTTPOK + true + when Net::HTTPRequestedRangeNotSatisfiable + raise ActionFailedError.new response.body + else + raise "honeydew-server failed to process command, response: #{response.value}" + end end - def clear_directory(directory) - all_files_in_directory_path = [directory.chomp('/'), '/*'].join - adb "shell rm -r #{all_files_in_directory_path}" + def log message + return unless Honeydew.config.debug + STDERR.puts "Device #{serial}: #{message}" end - private - def ensure_tablet_ready + def ensure_device_ready @device_ready ||= begin - wait_for_android_server + wait_for_honeydew_server true end end - def wait_for_android_server - log 'Waiting for server to come up' - retriable :on => [RestClient::ServerBrokeConnection, Errno::ECONNRESET, Errno::ECONNREFUSED], :interval => 0.3, :tries => 30 do - RestClient.head device_endpoint - end + def timeout_server_operation &block + Timeout.timeout(Honeydew.config.server_timeout.to_i, ServerTimeoutError, &block) end - def retriable(options, &block) - tries = options[:tries] - yield - rescue *[*options[:on]] - tries -= 1 - if tries > 0 - sleep options[:interval] - retry - else - raise + def wait_for_honeydew_server + log 'waiting for honeydew-server to respond' + timeout_server_operation do + sleep 0.1 until honeydew_server_alive? end + log 'honeydew-server is alive and awaiting commands' + + rescue ServerTimeoutError + raise 'timed out waiting for honeydew-server to respond' end + def honeydew_server_alive? + Net::HTTP.get_response(device_endpoint('/status')).code.to_i == 200 + rescue Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::ENETRESET, EOFError + end end end