lib/calabash-android/operations.rb in calabash-android-0.4.22.pre4 vs lib/calabash-android/operations.rb in calabash-android-0.5.0.pre1
- old
+ new
@@ -47,10 +47,24 @@
def set_default_device(device)
@default_device = device
end
def performAction(action, *arguments)
+ puts "Warning: The method performAction is deprecated. Please use perform_action instead."
+
+ perform_action(action, *arguments)
+ end
+
+ def perform_action(action, *arguments)
+ @removed_actions = File.readlines(File.join(File.dirname(__FILE__), 'removed_actions.txt')) unless @removed_actions
+ @removed_actions.map! &:chomp
+
+ if @removed_actions.include?(action)
+ puts "Error: The action '#{action}' was removed in calabash-android x.x.x"
+ puts 'For more information visit: https://github.com/calabash-android/foo/bar'
+ end
+
default_device.perform_action(action, *arguments)
end
def reinstall_apps
default_device.reinstall_apps
@@ -132,11 +146,17 @@
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 ]}
+ 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)
@@ -391,11 +411,11 @@
end
File.open(path, 'wb') do |f|
f.write res
end
else
- screenshot_cmd = "java -jar #{File.join(File.dirname(__FILE__), 'lib', 'screenshotTaker.jar')} #{serial} #{path}"
+ screenshot_cmd = "java -jar #{File.join(File.dirname(__FILE__), 'lib', 'screenshotTaker.jar')} #{serial} \"#{path}\""
log screenshot_cmd
raise "Could not take screenshot" unless system(screenshot_cmd)
end
@@screenshot_count += 1
@@ -702,54 +722,94 @@
screenshot_embed
end
raise(msg)
end
+ def has_text?(text)
+ !query("* {text CONTAINS[c] '#{text}'}").empty?
+ end
+
+ def assert_text(text, should_find = true)
+ raise "Text \"#{text}\" was #{should_find ? 'not ' : ''}found." if has_text?(text) ^ should_find
+
+ true
+ end
+
def double_tap(uiquery, options = {})
center_x, center_y = find_coordinate(uiquery)
- performAction("double_tap_coordinate", center_x, center_y)
+ perform_action("double_tap_coordinate", center_x, center_y)
end
+ # Performs a "long press" operation on a selected view
+ # Params:
+ # +uiquery+: a uiquery identifying one view
+ # +options[:length]+: the length of the long press in milliseconds (optional)
+ #
+ # Examples:
+ # - long_press("* id:'my_id'")
+ # - long_press("* id:'my_id'", {:length=>5000})
def long_press(uiquery, options = {})
center_x, center_y = find_coordinate(uiquery)
-
- performAction("long_press_coordinate", center_x, center_y)
+ length = options[:length]
+ perform_action("long_press_coordinate", center_x, center_y, *(length unless length.nil?))
end
def touch(uiquery, options = {})
center_x, center_y = find_coordinate(uiquery)
- performAction("touch_coordinate", center_x, center_y)
+ perform_action("touch_coordinate", center_x, center_y)
end
def keyboard_enter_text(text, options = {})
- performAction('keyboard_enter_text', text)
+ perform_action('keyboard_enter_text', text)
end
def enter_text(uiquery, text, options = {})
- touch(uiquery, options)
+ tap_when_element_exists(uiquery, options)
sleep 0.5
keyboard_enter_text(text, options)
end
+ def clear_text(query_string, options={})
+ result = query(query_string, setText: '')
+
+ raise "No elements found. Query: #{query_string}" if result.empty?
+
+ true
+ end
+
def find_coordinate(uiquery)
raise "Cannot find nil" unless uiquery
+ element = execute_uiquery(uiquery)
+
+ raise "No elements found. Query: #{uiquery}" if element.nil?
+
+ center_x = element["rect"]["center_x"]
+ center_y = element["rect"]["center_y"]
+
+ [center_x, center_y]
+ end
+
+ def execute_uiquery(uiquery)
if uiquery.instance_of? String
elements = query(uiquery)
- raise "No elements found. Query: #{uiquery}" if elements.empty?
- element = elements.first
+
+ return elements.first unless elements.empty?
else
- element = uiquery
- element = element.first if element.instance_of?(Array)
+ elements = uiquery
+
+ return elements.first if elements.instance_of?(Array)
+ return elements if elements.instance_of?(Hash)
end
- center_x = element["rect"]["center_x"]
- center_y = element["rect"]["center_y"]
+ nil
+ end
- [center_x, center_y]
+ def step_deprecated
+ puts 'Warning: This predefined step is deprecated.'
end
def http(path, data = {}, options = {})
default_device.http(path, data, options)
end
@@ -757,21 +817,57 @@
def html(q)
query(q).map {|e| e['html']}
end
def set_text(uiquery, txt)
- view,arguments = uiquery.split(" ",2)
- raise "Currently queries are only supported for webviews" unless view.downcase == "webview"
+ puts "set_text is deprecated. Use enter_text instead"
+ enter_text(uiquery, txt)
+ end
- if arguments =~ /(css|xpath):\s*(.*)/
- r = performAction("set_text", $1, $2, txt)
+ def press_back_button
+ perform_action('go_back')
+ end
+
+ def press_menu_button
+ perform_action('press_menu')
+ end
+
+ def select_options_menu_item(text, options={})
+ press_menu_button
+ tap_when_element_exists("DropDownListView * marked:'#{text}'", options)
+ end
+
+ 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
+
+ def tap_when_element_exists(query_string, options={})
+ options.merge!({action: lambda {|q| touch(q)}})
+
+ if options[:scroll] == true
+ scroll_to(query_string, options)
else
- raise "Invalid query #{arguments}"
+ when_element_exists(query_string, options)
end
end
+ def long_press_when_element_exists(query_string, options={})
+ options.merge!({action: lambda {|q| long_press(q)}})
+ if options[:scroll] == true
+ scroll_to(query_string, options)
+ else
+ when_element_exists(query_string, options)
+ end
+ end
+
def swipe(dir,options={})
ni
end
def cell_swipe(options={})
@@ -780,14 +876,88 @@
def done
ni
end
- def scroll(uiquery,direction)
- ni
+ def scroll_up
+ scroll("android.widget.ScrollView", :up)
end
+ def scroll_down
+ scroll("android.widget.ScrollView", :down)
+ end
+
+ def scroll(query_string, direction)
+ if direction != :up && direction != :down
+ raise 'Only upwards and downwards scrolling is supported for now'
+ end
+
+ scroll_x = 0
+ scroll_y = 0
+
+ action = lambda do
+ element = query(query_string).first
+ raise "No elements found. Query: #{query_string}" if element.nil?
+
+ 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]})
+ end
+
+ when_element_exists(query_string, action: action)
+ end
+
+ 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)
+
+ visibility_query_string = all_query_string[4..-1]
+
+ unless query(visibility_query_string).empty?
+ when_element_exists(visibility_query_string, options)
+ return
+ end
+
+ element = query(all_query_string).first
+ raise "No elements found. Query: #{all_query_string}" if element.nil?
+ element_center_y = element['rect']['center_y']
+
+ scroll_view_query_string = "#{all_query_string} parent android.widget.ScrollView index:0"
+ scroll_element = query(scroll_view_query_string).first
+
+ raise "Could not find parent scroll view. Query: #{scroll_view_query_string}" if element.nil?
+
+ scroll_element_y = scroll_element['rect']['y']
+ scroll_element_height = scroll_element['rect']['height']
+
+ if element_center_y > scroll_element_y + scroll_element_height
+ scroll_by_y = element_center_y - (scroll_element_y + scroll_element_height) + 2
+ else
+ scroll_by_y = element_center_y - scroll_element_y - 2
+ end
+
+ result = query(scroll_view_query_string, {scrollBy: [0, scroll_by_y.to_i]}).first
+ raise 'Could not scroll parent view' if result != '<VOID>'
+
+ visibility_query_string = all_query_string[4..-1]
+ when_element_exists(visibility_query_string, options)
+ end
+
def scroll_to_row(uiquery,number)
query(uiquery, {:smoothScrollToPosition => number})
puts "TODO:detect end of scroll - use sleep for now"
end
@@ -856,10 +1026,16 @@
def record_end(file_name)
ni
end
def backdoor(sel, arg)
- ni
+ result = perform_action("backdoor", sel, arg)
+ if !result["success"]
+ screenshot_and_raise(result["message"])
+ end
+
+ # for android results are returned in bonusInformation
+ result["bonusInformation"].first
end
def map(query, method_name, *method_args)
operation_map = {
:method_name => method_name,