Module: Calabash::Android::Operations

Includes:
DragHelpers, EnvironmentHelpers, TextHelpers, TouchHelpers, WaitHelpers
Included in:
Calabash::ABase
Defined in:
lib/calabash-android/operations.rb

Defined Under Namespace

Classes: Device

Constant Summary

Constants included from MonkeyHelpers

MonkeyHelpers::MAX_RETRIES

Constants included from WaitHelpers

WaitHelpers::DEFAULT_OPTS

Class Method Summary collapse

Instance Method Summary collapse

Methods included from DragHelpers

#drag_and_drop, #drag_coordinates

Methods included from MonkeyHelpers

#adb_command, #existing_monkey_pids, #get_monkey_port, #kill_existing_monkey_processes, #kill_monkey_processes_on_device, #kill_monkey_processes_on_host, #monkey_move_from, #monkey_tap, #monkey_touch, #start_monkey

Methods included from EnvironmentHelpers

#xamarin_test_cloud?

Methods included from WaitHelpers

#handle_error_with_options, #screenshot_and_retry, #until_element_does_not_exist, #until_element_exists, #wait_error, #wait_for, #wait_for_activity, #wait_for_element_does_not_exist, #wait_for_element_exists, #wait_for_elements_do_not_exist, #wait_for_elements_exist, #wait_for_text, #wait_for_text_to_disappear, #wait_poll, #when_element_exists

Methods included from TouchHelpers

#double_tap, #drag, #execute_gesture, #find_coordinate, #flick, #flick_down, #flick_left, #flick_right, #flick_up, #long_press, #long_press_when_element_exists, #pan, #pan_down, #pan_left, #pan_right, #pan_up, #pinch, #pinch_in, #pinch_out, #query_result?, #tap, #tap_mark, #tap_when_element_exists, #touch

Methods included from TextHelpers

#assert_text, #clear_text, #clear_text_in, #enter_text, #escape_backslashes, #escape_newlines, #escape_quotes, #escape_string, #has_text?, #keyboard_enter_char, #keyboard_enter_text, #keyboard_visible?, #set_selection, #wait_for_keyboard

Class Method Details

.extended(base) ⇒ Object



42
43
44
45
46
47
48
49
50
51
# File 'lib/calabash-android/operations.rb', line 42

def self.extended(base)
  if (class << base; included_modules.map(&:to_s).include?('Cucumber::RbSupport::RbWorld'); end)
    unless instance_methods.include?(:embed)
      original_embed = base.method(:embed)
      define_method(:embed) do |*args|
        original_embed.call(*args)
      end
    end
  end
end

Instance Method Details

#app_to_background(secs) ⇒ Object



1281
1282
1283
# File 'lib/calabash-android/operations.rb', line 1281

def app_to_background(secs)
  ni
end

#backdoor(method_name, arguments = [], options = {}) ⇒ Object



1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
# File 'lib/calabash-android/operations.rb', line 1351

def backdoor(method_name, arguments = [], options={})
  arguments = [arguments] unless arguments.is_a?(Array)

  result = JSON.parse(http('/backdoor', {method_name: method_name, arguments: arguments}))

  if result['outcome'] != 'SUCCESS'
    raise result.to_s
  end

  result['result']
end

#cell_swipe(options = {}) ⇒ Object



1142
1143
1144
# File 'lib/calabash-android/operations.rb', line 1142

def cell_swipe(options={})
  ni
end

#check_element_does_not_exist(query) ⇒ Object



1303
1304
1305
1306
1307
# File 'lib/calabash-android/operations.rb', line 1303

def check_element_does_not_exist( query )
  if element_exists( query )
    screenshot_and_raise "Expected no elements to match query: #{query}"
  end
end

#check_element_exists(query) ⇒ Object



1297
1298
1299
1300
1301
# File 'lib/calabash-android/operations.rb', line 1297

def check_element_exists( query )
  if not element_exists( query )
    screenshot_and_raise "No element found for query: #{query}"
  end
end

#check_view_with_mark_exists(expected_mark) ⇒ Object



1309
1310
1311
# File 'lib/calabash-android/operations.rb', line 1309

def check_view_with_mark_exists(expected_mark)
  check_element_exists( "view marked:'#{expected_mark}'" )
end

#classes(query_string, *args) ⇒ Object



281
282
283
# File 'lib/calabash-android/operations.rb', line 281

def classes(query_string, *args)
  query(query_string, :class, *args)
end

#clear_app_dataObject



139
140
141
# File 'lib/calabash-android/operations.rb', line 139

def clear_app_data
  default_device.clear_app_data
end

#clear_preferences(name) ⇒ Object



196
197
198
# File 'lib/calabash-android/operations.rb', line 196

def clear_preferences(name)
  default_device.clear_preferences(name)
end

#client_versionObject



168
169
170
# File 'lib/calabash-android/operations.rb', line 168

def client_version
  default_device.client_version
end

#connect_to_test_serverObject

app life cycle



300
301
302
303
304
# File 'lib/calabash-android/operations.rb', line 300

def connect_to_test_server
  puts "Explicit calls to connect_to_test_server should be removed."
  puts "Please take a look in your hooks file for calls to this methods."
  puts "(Hooks are stored in features/support)"
end

#current_activityObject



53
54
55
# File 'lib/calabash-android/operations.rb', line 53

def current_activity
  `#{default_device.adb_command} shell dumpsys window windows`.force_encoding('UTF-8').each_line.grep(/mFocusedApp.+[\.\/]([^.\s\/\}]+)/){$1}.first
end

#default_deviceObject



69
70
71
# File 'lib/calabash-android/operations.rb', line 69

def default_device
  @@default_device ||= Device.new(self, ENV["ADB_DEVICE_ARG"], ENV["TEST_SERVER_PORT"], ENV["APP_PATH"], ENV["TEST_APP_PATH"])
end

#deprecated_actionsObject



100
101
102
103
104
# File 'lib/calabash-android/operations.rb', line 100

def deprecated_actions
  @deprecated_actions ||= Hash[
      *File.readlines(File.join(File.dirname(__FILE__), 'deprecated_actions.map')).map{|e| e.chomp.split(',', 2)}.flatten
  ]
end

#disconnect_from_test_serverObject



306
307
308
309
310
# File 'lib/calabash-android/operations.rb', line 306

def disconnect_from_test_server
  puts "Explicit calls to disconnect_from_test_server should be removed."
  puts "Please take a look in your hooks file for calls to this methods."
  puts "(Hooks are stored in features/support)"
end

#each_item(opts = {:query => "android.widget.ListView", :post_scroll => 0.2}, &block) ⇒ Object



240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
# File 'lib/calabash-android/operations.rb', line 240

def each_item(opts={:query => "android.widget.ListView", :post_scroll => 0.2}, &block)
  uiquery = opts[:query] || "android.widget.ListView"
  skip_if = opts[:skip_if] || lambda { |i| false }
  stop_when = opts[:stop_when] || lambda { |i| false }
  check_element_exists(uiquery)
  num_items = query(opts[:query], :adapter, :count).first
  num_items.times do |item|
    next if skip_if.call(item)
    break if stop_when.call(item)

    scroll_to_row(opts[:query], item)
    sleep(opts[:post_scroll]) if opts[:post_scroll] and opts[:post_scroll] > 0
    yield(item)
  end
end

#element_does_not_exist(uiquery) ⇒ Object



1285
1286
1287
# File 'lib/calabash-android/operations.rb', line 1285

def element_does_not_exist(uiquery)
  query(uiquery).empty?
end

#element_exists(uiquery) ⇒ Object



1289
1290
1291
# File 'lib/calabash-android/operations.rb', line 1289

def element_exists(uiquery)
  not element_does_not_exist(uiquery)
end

#element_is_not_hidden(uiquery) ⇒ Object

a better name would be element_exists_and_is_not_hidden



1314
1315
1316
# File 'lib/calabash-android/operations.rb', line 1314

def element_is_not_hidden(uiquery)
  ni
end

#ensure_app_installedObject

Ensures that the application and the test-server are installed.

If the application has already been installed, it does nothing. If the test-server has already been installed, it does nothing.



114
115
116
# File 'lib/calabash-android/operations.rb', line 114

def ensure_app_installed
  default_device.ensure_apps_installed
end

#evaluate_javascript(query_string, javascript, opt = {}) ⇒ Object



1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
# File 'lib/calabash-android/operations.rb', line 1339

def evaluate_javascript(query_string, javascript, opt={})
  wait_for_elements_exist(query_string, {timeout: Calabash::Android::Defaults.query_timeout})
  result = JSON.parse(http("/map", {query: query_string, operation: {method_name: 'execute-javascript'}, javascript: javascript}))

  if result['outcome'] != 'SUCCESS' || result['results'].nil?
    parsed_result = result['results'].map {|r| "\"#{r}\","}.join("\n")
    raise "Could not evaluate javascript: \n#{parsed_result}"
  end

  result['results']
end

#execute_uiquery(uiquery) ⇒ Object



990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
# File 'lib/calabash-android/operations.rb', line 990

def execute_uiquery(uiquery)
  if uiquery.instance_of? String
    elements = query(uiquery)

    return elements.first unless elements.empty?
  else
    elements = uiquery

    return elements.first if elements.instance_of?(Array)
    return elements if elements.instance_of?(Hash)
  end

  nil
end

#fail(msg = "Error. Check log for details.", options = {:prefix => nil, :name => nil, :label => nil}) ⇒ Object



176
177
178
# File 'lib/calabash-android/operations.rb', line 176

def fail(msg="Error. Check log for details.", options={:prefix => nil, :name => nil, :label => nil})
  screenshot_and_raise(msg, options)
end

#find_scrollable_view(options = {}) ⇒ Object



1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
# File 'lib/calabash-android/operations.rb', line 1146

def find_scrollable_view(options={})
  timeout = options[:timeout] || 30

  begin
    Timeout.timeout(timeout, WaitError) do
      scroll_view_query_string = "android.widget.ScrollView index:0"
      list_view_query_string = "android.widget.AbsListView index:0"
      web_view_query_string = "android.webkit.WebView index:0"

      loop do
        if element_exists(scroll_view_query_string)
          return scroll_view_query_string
        elsif element_exists(list_view_query_string)
          return list_view_query_string
        elsif element_exists(web_view_query_string)
          return web_view_query_string
        end
      end
    end
  rescue WaitError
    raise WaitError.new('Could not find any scrollable views')
  end
end

#flash(query_string) ⇒ Object



236
237
238
# File 'lib/calabash-android/operations.rb', line 236

def flash(query_string)
  map(query_string, :flash)
end

#get_activity_orientationObject

Note: Android 2.2 will always return either portrait or landscape, not reverse_portrait or reverse_landscape



214
215
216
# File 'lib/calabash-android/operations.rb', line 214

def get_activity_orientation
  perform_action("get_activity_orientation")
end

#get_preferences(name) ⇒ Object



188
189
190
# File 'lib/calabash-android/operations.rb', line 188

def get_preferences(name)
  default_device.get_preferences(name)
end

#hide_soft_keyboardObject



986
987
988
# File 'lib/calabash-android/operations.rb', line 986

def hide_soft_keyboard
  perform_action('hide_soft_keyboard')
end

#html(q) ⇒ Object



1031
1032
1033
# File 'lib/calabash-android/operations.rb', line 1031

def html(q)
  query(q).map {|e| e['html']}
end

#http(path, data = {}, options = {}) ⇒ Object



1009
1010
1011
# File 'lib/calabash-android/operations.rb', line 1009

def http(path, data = {}, options = {})
  default_device.http(path, data, options)
end

#http_put(path, data = {}, options = {}) ⇒ Object



1013
1014
1015
# File 'lib/calabash-android/operations.rb', line 1013

def http_put(path, data = {}, options = {})
  default_device.http_put(path, data, options)
end

#install_app(app_path) ⇒ Object



122
123
124
# File 'lib/calabash-android/operations.rb', line 122

def install_app(app_path)
  default_device.install_app(app_path)
end

#interpolate(recording, options = {}) ⇒ Object



1327
1328
1329
# File 'lib/calabash-android/operations.rb', line 1327

def interpolate(recording, options={})
  ni
end

#label(uiquery) ⇒ Object



973
974
975
# File 'lib/calabash-android/operations.rb', line 973

def label(uiquery)
  ni
end

#load_dylib(file_path, classes = []) ⇒ Object

Parameters:

  • file_path (String)

    Path of the file to load (.apk or .jar)

  • classes (Array<String>) (defaults to: [])

    A list of classes to load from the file



1026
1027
1028
1029
# File 'lib/calabash-android/operations.rb', line 1026

def load_dylib(file_path, classes = [])
  uploaded_file = upload_file(file_path)
  http('/load-dylib', {path: uploaded_file, classes: classes})
end

#load_playback_data(recording, options = {}) ⇒ Object



1319
1320
1321
# File 'lib/calabash-android/operations.rb', line 1319

def load_playback_data(recording,options={})
  ni
end

#log(message) ⇒ Object



57
58
59
# File 'lib/calabash-android/operations.rb', line 57

def log(message)
  $stdout.puts "#{Time.now.strftime("%Y-%m-%d %H:%M:%S")} - #{message}" if (ARGV.include? "-v" or ARGV.include? "--verbose" or ENV["DEBUG"] == "1")
end

#macro(txt) ⇒ Object



61
62
63
64
65
66
67
# File 'lib/calabash-android/operations.rb', line 61

def macro(txt)
  if self.respond_to?(:step)
    step(txt)
  else
    Then(txt)
  end
end

#make_http_request(options) ⇒ Object



1382
1383
1384
# File 'lib/calabash-android/operations.rb', line 1382

def make_http_request(options)
  default_device.make_http_request(options)
end

#map(query, method_name, *method_args) ⇒ Object



1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
# File 'lib/calabash-android/operations.rb', line 1363

def map(query, method_name, *method_args)
  operation_map = {
      :method_name => method_name,
      :arguments => method_args
  }
  res = http("/map",
             {:query => query, :operation => operation_map})
  res = JSON.parse(res)
  if res['outcome'] != 'SUCCESS'
    screenshot_and_raise "map #{query}, #{method_name} failed because: #{res['reason']}\n#{res['details']}"
  end

  res['results']
end

#niObject



285
286
287
# File 'lib/calabash-android/operations.rb', line 285

def ni
  raise "Not yet implemented."
end

#page(clz, *args) ⇒ Object

simple page object helper



293
294
295
# File 'lib/calabash-android/operations.rb', line 293

def page(clz, *args)
  clz.new(self, *args)
end

#perform_action(action, *arguments) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/calabash-android/operations.rb', line 83

def perform_action(action, *arguments)
  if removed_actions.include?(action)
    puts "\e[31mError: The action '#{action}' was removed in calabash-android 0.5\e[0m"
    puts 'Solutions that do not require the removed action can be found on:'
    puts "\e[36mhttps://github.com/calabash/calabash-android/blob/master/migrating_to_calabash_0.5.md\##{action}\e[0m"
  elsif deprecated_actions.has_key?(action)
    puts "\e[31mWarning: The action '#{action}' is deprecated\e[0m"
    puts "\e[32mUse '#{deprecated_actions[action]}' instead\e[0m"
  end

  default_device.perform_action(action, *arguments)
end

#performAction(action, *arguments) ⇒ Object



77
78
79
80
81
# File 'lib/calabash-android/operations.rb', line 77

def performAction(action, *arguments)
  puts "Warning: The method performAction is deprecated. Please use perform_action instead."

  perform_action(action, *arguments)
end

#playback(recording, options = {}) ⇒ Object



1323
1324
1325
# File 'lib/calabash-android/operations.rb', line 1323

def playback(recording, options={})
  ni
end

#press_back_buttonObject



1054
1055
1056
# File 'lib/calabash-android/operations.rb', line 1054

def press_back_button
  press_button('KEYCODE_BACK')
end

#press_button(key) ⇒ Object



1050
1051
1052
# File 'lib/calabash-android/operations.rb', line 1050

def press_button(key)
  perform_action('press_key', key)
end

#press_down_buttonObject



1062
1063
1064
# File 'lib/calabash-android/operations.rb', line 1062

def press_down_button
  press_button('KEYCODE_DPAD_DOWN')
end

#press_enter_buttonObject



1078
1079
1080
# File 'lib/calabash-android/operations.rb', line 1078

def press_enter_button
  press_button('KEYCODE_ENTER')
end

#press_left_buttonObject



1070
1071
1072
# File 'lib/calabash-android/operations.rb', line 1070

def press_left_button
  press_button('KEYCODE_DPAD_LEFT')
end

#press_menu_buttonObject



1058
1059
1060
# File 'lib/calabash-android/operations.rb', line 1058

def press_menu_button
  press_button('KEYCODE_MENU')
end

#press_right_buttonObject



1074
1075
1076
# File 'lib/calabash-android/operations.rb', line 1074

def press_right_button
  press_button('KEYCODE_DPAD_RIGHT')
end

#press_up_buttonObject



1066
1067
1068
# File 'lib/calabash-android/operations.rb', line 1066

def press_up_button
  press_button('KEYCODE_DPAD_UP')
end

#press_user_action_button(action_name = nil) ⇒ Object



1040
1041
1042
1043
1044
1045
1046
1047
1048
# File 'lib/calabash-android/operations.rb', line 1040

def press_user_action_button(action_name=nil)
  wait_for_keyboard

  if action_name.nil?
    perform_action("press_user_action_button")
  else
    perform_action("press_user_action_button", action_name)
  end
end

#pull(remote, local) ⇒ Object



143
144
145
# File 'lib/calabash-android/operations.rb', line 143

def pull(remote, local)
  default_device.pull(remote, local)
end

#push(local, remote) ⇒ Object



147
148
149
# File 'lib/calabash-android/operations.rb', line 147

def push(local, remote)
  default_device.push(local, remote)
end

#query(uiquery, *args) ⇒ Object



218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/calabash-android/operations.rb', line 218

def query(uiquery, *args)
  converted_args = []
  args.each do |arg|
    if arg.is_a?(Hash) and arg.count == 1
      if arg.values.is_a?(Array) && arg.values.count == 1
        values = arg.values.flatten
      else
        values = [arg.values]
      end

      converted_args << {:method_name => arg.keys.first, :arguments => values}
    else
      converted_args << arg
    end
  end
  map(uiquery,:query,*converted_args)
end

#record_beginObject



1331
1332
1333
# File 'lib/calabash-android/operations.rb', line 1331

def record_begin
  ni
end

#record_end(file_name) ⇒ Object



1335
1336
1337
# File 'lib/calabash-android/operations.rb', line 1335

def record_end(file_name)
  ni
end

#reinstall_appsObject



106
107
108
# File 'lib/calabash-android/operations.rb', line 106

def reinstall_apps
  default_device.reinstall_apps
end

#reinstall_test_serverObject



118
119
120
# File 'lib/calabash-android/operations.rb', line 118

def reinstall_test_server
  default_device.reinstall_test_server
end

#removed_actionsObject



96
97
98
# File 'lib/calabash-android/operations.rb', line 96

def removed_actions
  @removed_actions ||= File.readlines(File.join(File.dirname(__FILE__), 'removed_actions.txt')).map(&:chomp)
end

#rotate(dir) ⇒ Object



1277
1278
1279
# File 'lib/calabash-android/operations.rb', line 1277

def rotate(dir)
  ni
end

#screenshot(options = {:prefix => nil, :name => nil}) ⇒ Object



164
165
166
# File 'lib/calabash-android/operations.rb', line 164

def screenshot(options={:prefix => nil, :name => nil})
  default_device.screenshot(options)
end

#screenshot_and_raise(e, options = nil) ⇒ Object



977
978
979
980
981
982
983
984
# File 'lib/calabash-android/operations.rb', line 977

def screenshot_and_raise(e, options = nil)
  if options
    screenshot_embed options
  else
    screenshot_embed
  end
  raise e
end

#screenshot_embed(options = {:prefix => nil, :name => nil, :label => nil}) ⇒ Object



159
160
161
162
# File 'lib/calabash-android/operations.rb', line 159

def screenshot_embed(options={:prefix => nil, :name => nil, :label => nil})
  path = default_device.screenshot(options)
  embed(path, "image/png", options[:label] || File.basename(path))
end

#scroll(query_string, direction) ⇒ Object



1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
# File 'lib/calabash-android/operations.rb', line 1178

def scroll(query_string, direction)
  if direction != :up && direction != :down
    raise 'Only upwards and downwards scrolling is supported for now'
  end

  action = lambda do
    elements = query(query_string)
    raise "No elements found. Query: #{query_string}" if elements.empty?

    if elements.length > 1
      query_string = "#{query_string} index:0"
    end

    element = elements.first

    response = query(query_string, :getFirstVisiblePosition).first

    if response.is_a?(Hash) && response.has_key?("error") # View is not of type android.widget.AbsListView
      scroll_x = 0
      scroll_y = 0
      width = element['rect']['width']
      height = element['rect']['height']

      if direction == :up
        scroll_y = -height/2
      else
        scroll_y = height/2
      end

      query(query_string, {scrollBy: [scroll_x.to_i, scroll_y.to_i]})
    else # View is of type android.widget.AbsListView
      first_position = response.to_i
      last_position = query(query_string, :getLastVisiblePosition).first.to_i

      selection_index = if direction == :up
                          [first_position + [first_position - last_position + 1, -1].min, 0].max
                        elsif direction == :down
                          first_position + [last_position - first_position, 1].max
                        end

      query(query_string, setSelection: selection_index)
    end
  end

  when_element_exists(query_string, action: action)
end

#scroll_down(options = {}) ⇒ Object



1174
1175
1176
# File 'lib/calabash-android/operations.rb', line 1174

def scroll_down(options={})
  scroll(find_scrollable_view(options), :down)
end

#scroll_to(query_string, options = {}) ⇒ Object



1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
# File 'lib/calabash-android/operations.rb', line 1225

def scroll_to(query_string, options={})
  options[:action] ||= lambda {}

  all_query_string = query_string

  unless all_query_string.chomp.downcase.start_with?('all')
    all_query_string = "all #{all_query_string}"
  end

  wait_for_element_exists(all_query_string)

  element = query(all_query_string).first
  raise "No elements found. Query: #{all_query_string}" if element.nil?
  element_y = element['rect']['y']
  element_height = element['rect']['height']
  element_bottom = element_y + element_height

  scroll_view_query_string = options[:container] || if element.has_key?('html')
                                                      "android.webkit.WebView id:'#{element['webView']}'"
                                                    else
                                                      "#{all_query_string} parent android.widget.ScrollView index:0"
                                                    end

  scroll_element = query(scroll_view_query_string).first

  raise "Could not find parent scroll view. Query: '#{escape_quotes(scroll_view_query_string)}'" if scroll_element.nil?

  scroll_element_y = scroll_element['rect']['y']
  scroll_element_height = scroll_element['rect']['height']

  if element_bottom > scroll_element_y + scroll_element_height
    scroll_by_y = element_bottom - (scroll_element_y + scroll_element_height)
  elsif element_y < scroll_element_y
    scroll_by_y = element_y - scroll_element_y
  else
    scroll_by_y = 0
  end

  if scroll_by_y != 0
    result = query(scroll_view_query_string, {scrollBy: [0, scroll_by_y]}).first
    raise 'Could not scroll parent view' if result != '<VOID>'
  end

  visibility_query_string = all_query_string[4..-1]
  when_element_exists(visibility_query_string, options)
end

#scroll_to_row(uiquery, number) ⇒ Object



1272
1273
1274
1275
# File 'lib/calabash-android/operations.rb', line 1272

def scroll_to_row(uiquery,number)
  query(uiquery, {:smoothScrollToPosition => number})
  puts "TODO:detect end of scroll - use sleep for now"
end

#scroll_up(options = {}) ⇒ Object



1170
1171
1172
# File 'lib/calabash-android/operations.rb', line 1170

def scroll_up(options={})
  scroll(find_scrollable_view(options), :up)
end

#select_context_menu_item(view_uiquery, menu_item_query_string) ⇒ Object



1087
1088
1089
1090
1091
1092
1093
1094
1095
# File 'lib/calabash-android/operations.rb', line 1087

def select_context_menu_item(view_uiquery, menu_item_query_string)
  long_press(view_uiquery)

  container_class = 'com.android.internal.view.menu.ListMenuItemView'
  wait_for_element_exists(container_class)

  combined_query_string = "#{container_class} descendant #{menu_item_query_string}"
  touch(combined_query_string)
end

#select_item_from_spinner(item_query_string, options = {}) ⇒ Object



1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
# File 'lib/calabash-android/operations.rb', line 1097

def select_item_from_spinner(item_query_string, options={})
  spinner_query_string = options[:spinner] || "android.widget.AbsSpinner"
  direction = options[:direction] || :down
  count = query(spinner_query_string, :getCount).first
  scroll_view_query_string = options[:scroll_view] || "android.widget.AbsListView index:0"

  unless direction == :up || direction == :down
    raise "Invalid direction '#{direction}'. Only upwards and downwards scrolling is supported"
  end

  touch(spinner_query_string)

  change_direction = false

  wait_for({retry_frequency: 0}.merge(options)) do
    if query(item_query_string).empty?
      scroll(scroll_view_query_string, direction)

      if change_direction
        direction = direction == :up ? :down : :up
        change_direction = false
      else
        # Because getLastVisiblePosition returns the last element even though it is not visible,
        # we have to scroll one more time to make sure we do not change direction before the last
        # element is fully visible
        if direction == :down
          change_direction = true if query(scroll_view_query_string, :getLastVisiblePosition).first+1 == count
        elsif direction == :up
          change_direction = true if query(scroll_view_query_string, :getFirstVisiblePosition).first == 0
        end
      end

      false
    else
      true
    end
  end

  touch(item_query_string)
end

#select_options_menu_item(identifier, options = {}) ⇒ Object



1082
1083
1084
1085
# File 'lib/calabash-android/operations.rb', line 1082

def select_options_menu_item(identifier, options={})
  press_menu_button
  tap_when_element_exists("DropDownListView * marked:'#{identifier}'", options)
end

#server_versionObject



172
173
174
# File 'lib/calabash-android/operations.rb', line 172

def server_version
  default_device.server_version
end

#set_activity_orientation(orientation) ⇒ Object



200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/calabash-android/operations.rb', line 200

def set_activity_orientation(orientation)
  unless orientation.is_a?(Symbol)
    raise ArgumentError, "Orientation is not a symbol"
  end

  unless orientation == :landscape || orientation == :portrait ||
      orientation == :reverse_landscape || orientation == :reverse_portrait
    raise ArgumentError, "Invalid orientation given. Use :landscape, :portrait, :reverse_landscape, or :reverse_portrait"
  end

  perform_action("set_activity_orientation", orientation.to_s)
end

#set_date(query_string, year_or_datestring, month = nil, day = nil) ⇒ Object



256
257
258
259
260
261
262
263
264
265
266
# File 'lib/calabash-android/operations.rb', line 256

def set_date(query_string, year_or_datestring, month=nil, day=nil)
  wait_for_element_exists(query_string)

  if month.nil? && day.nil? && year_or_datestring.is_a?(String)
    date = Date.parse(year_or_datestring)
    set_date(query_string, date.year, date.month, date.day)
  else
    year = year_or_datestring
    query(query_string, updateDate: [year, month-1, day])
  end
end

#set_default_device(device) ⇒ Object



73
74
75
# File 'lib/calabash-android/operations.rb', line 73

def set_default_device(device)
  @@default_device = device
end

#set_gps_coordinates(latitude, longitude) ⇒ Object



184
185
186
# File 'lib/calabash-android/operations.rb', line 184

def set_gps_coordinates(latitude, longitude)
  default_device.set_gps_coordinates(latitude, longitude)
end

#set_gps_coordinates_from_location(location) ⇒ Object



180
181
182
# File 'lib/calabash-android/operations.rb', line 180

def set_gps_coordinates_from_location(location)
  default_device.set_gps_coordinates_from_location(location)
end

#set_preferences(name, hash) ⇒ Object



192
193
194
# File 'lib/calabash-android/operations.rb', line 192

def set_preferences(name, hash)
  default_device.set_preferences(name, hash)
end

#set_text(uiquery, txt) ⇒ Object



1035
1036
1037
1038
# File 'lib/calabash-android/operations.rb', line 1035

def set_text(uiquery, txt)
  puts "set_text is deprecated. Use enter_text instead"
  enter_text(uiquery, txt)
end

#set_time(query_string, hour_or_timestring, minute = nil) ⇒ Object



268
269
270
271
272
273
274
275
276
277
278
279
# File 'lib/calabash-android/operations.rb', line 268

def set_time(query_string, hour_or_timestring, minute=nil)
  wait_for_element_exists(query_string)

  if minute.nil? && hour_or_timestring.is_a?(String)
    time = Time.parse(hour_or_timestring)
    set_time(query_string, time.hour, time.min)
  else
    hour = hour_or_timestring
    query(query_string, setCurrentHour: hour)
    query(query_string, setCurrentMinute: minute)
  end
end

#shutdown_test_serverObject



155
156
157
# File 'lib/calabash-android/operations.rb', line 155

def shutdown_test_server
  default_device.shutdown_test_server
end

#start_test_server_in_background(options = {}, &block) ⇒ Object



151
152
153
# File 'lib/calabash-android/operations.rb', line 151

def start_test_server_in_background(options={}, &block)
  default_device.start_test_server_in_background(options, &block)
end

#step_deprecatedObject



1005
1006
1007
# File 'lib/calabash-android/operations.rb', line 1005

def step_deprecated
  puts 'Warning: This predefined step is deprecated.'
end

#swipe(query_string, options = {}) ⇒ Object



1138
1139
1140
# File 'lib/calabash-android/operations.rb', line 1138

def swipe(query_string, options={})
  raise 'Swipe not implemented. Use flick or pan instead.'
end

#uninstall_appsObject



130
131
132
133
# File 'lib/calabash-android/operations.rb', line 130

def uninstall_apps
  default_device.uninstall_app(package_name(default_device.test_server_path))
  default_device.uninstall_app(package_name(default_device.app_path))
end

#update_app(app_path) ⇒ Object



126
127
128
# File 'lib/calabash-android/operations.rb', line 126

def update_app(app_path)
  default_device.update_app(app_path)
end

#upload_file(file_path) ⇒ String

Returns The path of the uploaded file on the device.

Returns:

  • (String)

    The path of the uploaded file on the device



1018
1019
1020
1021
1022
# File 'lib/calabash-android/operations.rb', line 1018

def upload_file(file_path)
  name = File.basename(file_path)
  device_tmp_path = http_put('/add-file', File.binread(file_path))
  http('/move-cache-file-to-public', {from: device_tmp_path, name: name})
end

#url_for(method) ⇒ Object



1378
1379
1380
# File 'lib/calabash-android/operations.rb', line 1378

def url_for( method )
  default_device.url_for(method)
end

#view_with_mark_exists(expected_mark) ⇒ Object



1293
1294
1295
# File 'lib/calabash-android/operations.rb', line 1293

def view_with_mark_exists(expected_mark)
  element_exists( "android.view.View marked:'#{expected_mark}'" )
end

#wake_upObject



135
136
137
# File 'lib/calabash-android/operations.rb', line 135

def wake_up
  default_device.wake_up()
end