lib/calabash-android/operations.rb in calabash-android-0.4.7.pre9 vs lib/calabash-android/operations.rb in calabash-android-0.4.7.pre10

- old
+ new

@@ -115,10 +115,22 @@ def set_gps_coordinates(latitude, longitude) default_device.set_gps_coordinates(latitude, longitude) end + def get_preferences(name) + default_device.get_preferences(name) + end + + def set_preferences(name, hash) + default_device.set_preferences(name, hash) + end + + def clear_preferences(name) + default_device.clear_preferences(name) + end + def query(uiquery, *args) converted_args = [] args.each do |arg| if arg.is_a?(Hash) and arg.count == 1 converted_args << {:method_name => arg.keys.first, :arguments => [ arg.values.first ]} @@ -176,12 +188,12 @@ attr_reader :app_path, :test_server_path, :serial, :server_port, :test_server_port def initialize(cucumber_world, serial, server_port, app_path, test_server_path, test_server_port = 7102) @cucumber_world = cucumber_world - @serial = serial - @server_port = server_port + @serial = serial || default_serial + @server_port = server_port || default_server_port @app_path = app_path @test_server_path = test_server_path @test_server_port = test_server_port forward_cmd = "#{adb_command} forward tcp:#{@server_port} tcp:#{@test_server_port}" @@ -222,11 +234,11 @@ succeeded = result.include?("Success") unless succeeded ::Cucumber.wants_to_quit = true raise "#{pn} did not get updated. Aborting!" - end + end end def uninstall_app(package_name) log "Uninstalling: #{package_name}" log `#{adb_command} uninstall #{package_name}` @@ -398,27 +410,48 @@ else %Q("#{ENV["ANDROID_HOME"]}/platform-tools/adb") end end - def serial - @serial || default_serial - end - def default_serial devices = connected_devices log "connected_devices: #{devices}" raise "No connected devices" if devices.empty? raise "More than one device connected. Specify device serial using ADB_DEVICE_ARG" if devices.length > 1 devices.first end + def default_server_port + require 'yaml' + File.open(File.expand_path(server_port_configuration), File::RDWR|File::CREAT) do |f| + f.flock(File::LOCK_EX) + state = YAML::load(f) || {} + ports = state['server_ports'] ||= {} + return ports[serial] if ports.has_key?(serial) + + port = 34777 + port += 1 while ports.has_value?(port) + ports[serial] = port + + f.rewind + f.write(YAML::dump(state)) + f.truncate(f.pos) + + log "Persistently allocated port #{port} to #{serial}" + return port + end + end + + def server_port_configuration + File.expand_path(ENV['CALABASH_SERVER_PORTS'] || "~/.calabash.yaml") + end + def connected_devices lines = `#{adb} devices`.split("\n") lines.shift lines.collect { |l| l.split("\t").first} - end + end def wake_up wake_up_cmd = "#{adb_command} shell am start -a android.intent.action.MAIN -n #{package_name(@test_server_path)}/sh.calaba.instrumentationbackend.WakeUp" log "Waking up device using:" log wake_up_cmd @@ -549,12 +582,119 @@ end def set_gps_coordinates(latitude, longitude) perform_action('set_gps_coordinates', latitude, longitude) end - end + def get_preferences(name) + log "Get preferences: #{name}, app running? #{app_running?}" + preferences = {} + + if app_running? + json = perform_action('get_preferences', name); + else + + logcat_id = get_logcat_id() + cmd = "#{adb_command} shell am instrument -e logcat #{logcat_id} -e name \"#{name}\" #{package_name(@test_server_path)}/sh.calaba.instrumentationbackend.GetPreferences" + + raise "Could not get preferences" unless system(cmd) + + logcat_cmd = get_logcat_cmd(logcat_id) + logcat_output = `#{logcat_cmd}` + + json = get_json_from_logcat(logcat_output) + + raise "Could not get preferences" unless json != nil and json["success"] + end + + # at this point we have valid json, coming from an action + # or instrumentation, but we don't care, just parse + if json["bonusInformation"].length > 0 + json["bonusInformation"].each do |item| + json_item = JSON.parse(item) + preferences[json_item["key"]] = json_item["value"] + end + end + + preferences + end + + def set_preferences(name, hash) + + log "Set preferences: #{name}, #{hash}, app running? #{app_running?}" + + if app_running? + perform_action('set_preferences', name, hash); + else + + params = hash.map {|k,v| "-e \"#{k}\" \"#{v}\""}.join(" ") + + logcat_id = get_logcat_id() + cmd = "#{adb_command} shell am instrument -e logcat #{logcat_id} -e name \"#{name}\" #{params} #{package_name(@test_server_path)}/sh.calaba.instrumentationbackend.SetPreferences" + + raise "Could not set preferences" unless system(cmd) + + logcat_cmd = get_logcat_cmd(logcat_id) + logcat_output = `#{logcat_cmd}` + + json = get_json_from_logcat(logcat_output) + + raise "Could not set preferences" unless json != nil and json["success"] + end + end + + def clear_preferences(name) + + log "Clear preferences: #{name}, app running? #{app_running?}" + + if app_running? + perform_action('clear_preferences', name); + else + + logcat_id = get_logcat_id() + cmd = "#{adb_command} shell am instrument -e logcat #{logcat_id} -e name \"#{name}\" #{package_name(@test_server_path)}/sh.calaba.instrumentationbackend.ClearPreferences" + raise "Could not clear preferences" unless system(cmd) + + logcat_cmd = get_logcat_cmd(logcat_id) + logcat_output = `#{logcat_cmd}` + + json = get_json_from_logcat(logcat_output) + + raise "Could not clear preferences" unless json != nil and json["success"] + end + end + + def get_json_from_logcat(logcat_output) + + logcat_output.split(/\r?\n/).each do |line| + begin + json = JSON.parse(line) + return json + rescue + # nothing to do here, just discarding logcat rubbish + end + end + + return nil + end + + def get_logcat_id() + # we need a unique logcat tag so we can later + # query the logcat output and filter out everything + # but what we are interested in + + random = (0..10000).to_a.sample + "#{Time.now.strftime("%s")}_#{random}" + end + + def get_logcat_cmd(tag) + # returns raw logcat output for our tag + # filtering out everthing else + + "#{adb_command} logcat -d -v raw #{tag}:* *:S" + end + end def label(uiquery) ni end