calabash-android 0.4.22.pre4 → 0.5.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/bin/calabash-android +66 -45
  3. data/lib/calabash-android/calabash_steps.rb +0 -8
  4. data/lib/calabash-android/canned_steps.md +2 -30
  5. data/lib/calabash-android/lib/TestServer.apk +0 -0
  6. data/lib/calabash-android/operations.rb +199 -23
  7. data/lib/calabash-android/removed_actions.txt +52 -0
  8. data/lib/calabash-android/steps/assert_steps.rb +9 -24
  9. data/lib/calabash-android/steps/check_box_steps.rb +2 -2
  10. data/lib/calabash-android/steps/context_menu_steps.rb +11 -4
  11. data/lib/calabash-android/steps/date_picker_steps.rb +2 -2
  12. data/lib/calabash-android/steps/enter_text_steps.rb +13 -13
  13. data/lib/calabash-android/steps/l10n_steps.rb +5 -5
  14. data/lib/calabash-android/steps/map_steps.rb +12 -12
  15. data/lib/calabash-android/steps/navigation_steps.rb +12 -12
  16. data/lib/calabash-android/steps/press_button_steps.rb +16 -12
  17. data/lib/calabash-android/steps/progress_steps.rb +19 -22
  18. data/lib/calabash-android/steps/search_steps.rb +2 -2
  19. data/lib/calabash-android/steps/spinner_steps.rb +10 -2
  20. data/lib/calabash-android/steps/time_picker_steps.rb +2 -2
  21. data/lib/calabash-android/version.rb +1 -1
  22. data/lib/calabash-android/wait_helpers.rb +29 -1
  23. data/test-server/instrumentation-backend/antlr/UIQuery.g +11 -11
  24. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/CalabashInstrumentationTestRunner.java +3 -2
  25. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/InstrumentationBackend.java +9 -4
  26. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/Result.java +16 -12
  27. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/application/Backdoor.java +55 -0
  28. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/gestures/LongPressCoordinate.java +19 -2
  29. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/JavaScriptExecuter.java +105 -0
  30. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/QueryHelper.java +27 -30
  31. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ViewMapper.java +27 -18
  32. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/ComparisonOperator.java +7 -1
  33. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryASTPredicate.java +16 -4
  34. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryASTWith.java +13 -6
  35. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryUtils.java +94 -48
  36. metadata +5 -59
  37. data/lib/calabash-android/steps/additions_manual_steps.rb +0 -11
  38. data/lib/calabash-android/steps/app_steps.rb +0 -10
  39. data/lib/calabash-android/steps/list_steps.rb +0 -41
  40. data/lib/calabash-android/steps/rotation_steps.rb +0 -7
  41. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/button/PressButtonNumber.java +0 -22
  42. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/button/PressButtonText.java +0 -27
  43. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/button/PressImageButtonDescription.java +0 -39
  44. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/button/PressImageButtonNumber.java +0 -22
  45. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/button/WaitForButton.java +0 -47
  46. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/checkbox/ToggleCheckboxNumber.java +0 -22
  47. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/contextmenu/LongPressText.java +0 -22
  48. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/contextmenu/LongPressTextAndSelectFromMenuById.java +0 -26
  49. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/contextmenu/LongPressTextAndSelectFromMenuByIndex.java +0 -22
  50. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/contextmenu/LongPressTextAndSelectFromMenuByText.java +0 -26
  51. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/helpers/InspectCurrentDialog.java +0 -76
  52. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/list/GetListData.java +0 -85
  53. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/list/GetListItemProperties.java +0 -194
  54. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/list/GetListItemText.java +0 -136
  55. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/list/LongPressListItems.java +0 -22
  56. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/list/PressListItems.java +0 -22
  57. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/scrolling/ScrollDown.java +0 -22
  58. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/scrolling/ScrollUp.java +0 -22
  59. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/search/EnterQueryByIndex.java +0 -29
  60. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/softkey/SelectFromMenuByText.java +0 -24
  61. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/spinner/GetSelectedSpinnerItemText.java +0 -36
  62. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/spinner/SelectSpinnerItemByContentDescription.java +0 -43
  63. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/text/AssertGridViewContainsNoDuplicates.java +0 -72
  64. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/text/AssertText.java +0 -31
  65. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/text/AssertTextOfSpecificTextViewByContentDescription.java +0 -32
  66. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/text/ClearTextById.java +0 -30
  67. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/text/ClearTextByIndex.java +0 -22
  68. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/text/ClearTextFieldByContentDescription.java +0 -33
  69. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/text/ClickOnText.java +0 -22
  70. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/text/EnterTextByContentDescription.java +0 -32
  71. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/text/EnterTextById.java +0 -33
  72. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/text/EnterTextByIndex.java +0 -22
  73. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/text/GetTextById.java +0 -42
  74. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/view/AssertViewProperty.java +0 -141
  75. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/view/ClickOnViewByDescription.java +0 -46
  76. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/view/ClickOnViewById.java +0 -56
  77. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/view/GetViewProperty.java +0 -101
  78. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/view/HasView.java +0 -31
  79. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/view/IsEnabled.java +0 -30
  80. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/view/LongPressOnViewById.java +0 -34
  81. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/view/Press.java +0 -89
  82. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/view/SelectTab.java +0 -110
  83. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/wait/Wait.java +0 -24
  84. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/wait/WaitForDialogClose.java +0 -21
  85. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/wait/WaitForProgress.java +0 -47
  86. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/wait/WaitForScreen.java +0 -54
  87. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/wait/WaitForTab.java +0 -108
  88. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/wait/WaitForText.java +0 -37
  89. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/wait/WaitForView.java +0 -43
  90. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/wait/WaitForViewById.java +0 -58
  91. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/JavaScriptOperation.java +0 -44
  92. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/PressByCssSelector.java +0 -70
  93. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/SetText.java +0 -64
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b08ffe174ecf3dde1f1f58a609148b6f338b2114
4
- data.tar.gz: f60f07366df805990cca8d49dc4516e9d3ad6c96
3
+ metadata.gz: 7a378465ba71fd03e09901a56b34e16b780d0753
4
+ data.tar.gz: 8e9117755d320057f9cc55e842c448d45db6c726
5
5
  SHA512:
6
- metadata.gz: 846aa7dc192a504a2461c9e8d69f7f8d2c55854a0dd87bdf860d6964fa6d71b7af8aaef2848170c0b6111b8279a69f91bf3bd4269c02b344b50179903db11bc9
7
- data.tar.gz: 41d381af7fb3f41bb805985b85508e4f40f5627dacf5d91f85f8a7bc5722b64807d07cf4fa5e1afddefd4e4d0b51f5e52699c90c40f699d8b36feaac290c3c08
6
+ metadata.gz: 14cbc8db152ca204468d1549cd7a96bc032198897eac5e9702941d6b3cc862025b7fc8792031937b97323046a8b3510543f435705ae0ea515559a8a19ab22ced
7
+ data.tar.gz: 4c2c2504a207311335d62e2680a1b582852278bfe106d1812622dcbb92866f56553ef7771eb20051ff2ede477f1311e602623da3852b86043f9678b3a2be47f9
@@ -51,51 +51,72 @@ def relative_to_full_path(file_path)
51
51
  File.expand_path(file_path)
52
52
  end
53
53
 
54
- if (ARGV.length == 0)
54
+ if ARGV.length == 0
55
55
  print_usage
56
- end
57
- cmd = ARGV.shift
58
- if cmd == 'help'
59
- print_help
60
- elsif cmd == 'build'
61
- Env.exit_if_env_not_set_up
62
- puts "Please specify the app you want to build a test server for" if (ARGV.empty? or not is_apk_file?(ARGV.first))
63
- while not ARGV.empty? and is_apk_file?(ARGV.first)
64
- calabash_build(relative_to_full_path(ARGV.shift))
65
- end
66
- elsif cmd == 'run'
67
- Env.exit_if_env_not_set_up
68
- if ARGV.empty? or not is_apk_file?(ARGV.first)
69
- exit calabash_run()
56
+ else
57
+ cmd = ARGV.shift
58
+
59
+ case cmd
60
+ when 'help'
61
+ print_help
62
+ when 'build'
63
+ Env.exit_if_env_not_set_up
64
+
65
+ if ARGV.empty?
66
+ puts "Please specify the app you want to build a test server for"
67
+ exit 1
68
+ elsif !File.exist?(ARGV.first)
69
+ puts "Could not find file '#{ARGV.first}'"
70
+ exit 1
71
+ elsif !is_apk_file?(ARGV.first)
72
+ puts "'#{ARGV.first}' is not a valid android application"
73
+ exit 1
74
+ else
75
+ while not ARGV.empty? and is_apk_file?(ARGV.first)
76
+ calabash_build(relative_to_full_path(ARGV.shift))
77
+ end
78
+ end
79
+ when 'run'
80
+ Env.exit_if_env_not_set_up
81
+ if ARGV.empty? or not is_apk_file?(ARGV.first)
82
+ puts "The first parameter must be the path to the apk file."
83
+ exit 1
84
+ else
85
+ exit calabash_run(relative_to_full_path(ARGV.shift))
86
+ end
87
+ when 'gen'
88
+ calabash_scaffold
89
+ when 'console'
90
+ Env.exit_if_env_not_set_up
91
+
92
+ if ARGV.empty? or not is_apk_file?(ARGV.first)
93
+ puts "The first parameter must be the path to the apk file."
94
+ exit 1
95
+ else
96
+ calabash_console(relative_to_full_path(ARGV.shift))
97
+ end
98
+ when 'setup'
99
+ Env.exit_if_env_not_set_up
100
+ calabash_setup
101
+ when 'resign'
102
+ Env.exit_if_env_not_set_up
103
+
104
+ if ARGV.empty?
105
+ puts "Please specify the app you want to resign"
106
+ exit 1
107
+ elsif !File.exist?(ARGV.first)
108
+ puts "Could not find file '#{ARGV.first}'"
109
+ exit 1
110
+ elsif !is_apk_file?(ARGV.first)
111
+ puts "'#{ARGV.first}' is not a valid android application"
112
+ exit 1
113
+ else
114
+ resign_apk(File.expand_path(ARGV.first))
115
+ end
116
+ when 'version'
117
+ puts Calabash::Android::VERSION
70
118
  else
71
- exit calabash_run(relative_to_full_path(ARGV.shift))
72
- end
73
- elsif cmd == 'gen'
74
- calabash_scaffold
75
- elsif cmd == 'console'
76
- Env.exit_if_env_not_set_up
77
- if ARGV.empty?
78
- puts "Please specify an app"
79
- exit 1
119
+ puts "Invalid command '#{cmd}'"
120
+ print_usage
80
121
  end
81
- unless File.exist? ARGV.first
82
- puts "No such file #{ARGV.first}"
83
- exit 1
84
- end
85
- calabash_console(relative_to_full_path(ARGV.shift))
86
- elsif cmd == 'setup'
87
- Env.exit_if_env_not_set_up
88
- calabash_setup
89
- elsif cmd == 'resign'
90
- Env.exit_if_env_not_set_up
91
- unless File.exist?(File.expand_path(ARGV.first))
92
- puts "No such file #{ARGV.first}"
93
- exit 1
94
- end
95
- resign_apk(File.expand_path(ARGV.first))
96
-
97
- elsif cmd == 'version'
98
- puts Calabash::Android::VERSION
99
- else
100
- print_usage
101
- end
122
+ end
@@ -1,9 +1,3 @@
1
-
2
- WAIT_TIMEOUT = (ENV['WAIT_TIMEOUT'] || 30).to_f
3
- STEP_PAUSE = (ENV['STEP_PAUSE'] || 0.5).to_f
4
-
5
- require 'calabash-android/steps/additions_manual_steps'
6
- require 'calabash-android/steps/app_steps'
7
1
  require 'calabash-android/steps/assert_steps'
8
2
  require 'calabash-android/steps/check_box_steps'
9
3
  require 'calabash-android/steps/context_menu_steps'
@@ -13,10 +7,8 @@ require 'calabash-android/steps/location_steps'
13
7
  require 'calabash-android/steps/navigation_steps'
14
8
  require 'calabash-android/steps/press_button_steps'
15
9
  require 'calabash-android/steps/progress_steps'
16
- require 'calabash-android/steps/rotation_steps'
17
10
  require 'calabash-android/steps/screenshot_steps'
18
11
  require 'calabash-android/steps/search_steps'
19
12
  require 'calabash-android/steps/spinner_steps'
20
13
  require 'calabash-android/steps/time_picker_steps'
21
- require 'calabash-android/steps/list_steps'
22
14
 
@@ -23,7 +23,7 @@ To assert that specified text cannot be found use any of the following steps.
23
23
  Input steps
24
24
  -----------
25
25
 
26
- Then /^I toggle checkbox number (\d+)$/ do |checkboxNumber|
26
+ Then /^I toggle checkbox number (\d+)$/ do |checkbox_number|
27
27
  Toggles checkout with the specified index.
28
28
 
29
29
  Then /^I long press "([^\"]*)"$/ do |text_to_press|
@@ -246,7 +246,7 @@ Waits until the text of the translated l10nkey is displayed.
246
246
 
247
247
  Note: you can assert or press interface elements using [Android's String resources](http://developer.android.com/reference/android/R.string.html) by passing a package in a custom step:
248
248
 
249
- performAction('press_l10n_element', 'ok', nil, 'android')
249
+ perform_action('press_l10n_element', 'ok', nil, 'android')
250
250
 
251
251
  Rotation
252
252
  --------
@@ -257,31 +257,3 @@ If you run the test on [LessPainful](https://www.lesspainful.com) they will actu
257
257
  Then /^I rotate the device to landscape$/
258
258
  Then /^I rotate the device to portrait$/
259
259
 
260
- Manual Steps
261
- ------------
262
-
263
- These steps are useful for allowing mixed manual and automated tests and to be documented
264
- and kept together. These steps do nothing when the tests are run automatically but are still
265
- documented in Cucumber output formatters such as the HTML report. This allows a
266
- manual tester to perform the same test case but with extra manual steps such as manual image verification.
267
-
268
- To manually request a manual tester to compare the screen with a reference image
269
-
270
- Then /^I compare the current screen with the reference image "([^\"]*) manually"$/ do |name|
271
-
272
- For example:
273
-
274
- Then I compare the current screen with the reference image "features/ref1.png" manually
275
-
276
- To manually perform a custom step
277
-
278
- Then /^I manually (.*)$/ do |action|
279
-
280
- For example:
281
-
282
- Then I manually check that the list scrolls smoothly
283
-
284
-
285
-
286
-
287
-
@@ -49,6 +49,20 @@ module Operations
49
49
  end
50
50
 
51
51
  def performAction(action, *arguments)
52
+ puts "Warning: The method performAction is deprecated. Please use perform_action instead."
53
+
54
+ perform_action(action, *arguments)
55
+ end
56
+
57
+ def perform_action(action, *arguments)
58
+ @removed_actions = File.readlines(File.join(File.dirname(__FILE__), 'removed_actions.txt')) unless @removed_actions
59
+ @removed_actions.map! &:chomp
60
+
61
+ if @removed_actions.include?(action)
62
+ puts "Error: The action '#{action}' was removed in calabash-android x.x.x"
63
+ puts 'For more information visit: https://github.com/calabash-android/foo/bar'
64
+ end
65
+
52
66
  default_device.perform_action(action, *arguments)
53
67
  end
54
68
 
@@ -134,7 +148,13 @@ module Operations
134
148
  converted_args = []
135
149
  args.each do |arg|
136
150
  if arg.is_a?(Hash) and arg.count == 1
137
- converted_args << {:method_name => arg.keys.first, :arguments => [ arg.values.first ]}
151
+ if arg.values.is_a?(Array) && arg.values.count == 1
152
+ values = arg.values.flatten
153
+ else
154
+ values = [arg.values]
155
+ end
156
+
157
+ converted_args << {:method_name => arg.keys.first, :arguments => values}
138
158
  else
139
159
  converted_args << arg
140
160
  end
@@ -393,7 +413,7 @@ module Operations
393
413
  f.write res
394
414
  end
395
415
  else
396
- screenshot_cmd = "java -jar #{File.join(File.dirname(__FILE__), 'lib', 'screenshotTaker.jar')} #{serial} #{path}"
416
+ screenshot_cmd = "java -jar #{File.join(File.dirname(__FILE__), 'lib', 'screenshotTaker.jar')} #{serial} \"#{path}\""
397
417
  log screenshot_cmd
398
418
  raise "Could not take screenshot" unless system(screenshot_cmd)
399
419
  end
@@ -704,50 +724,90 @@ module Operations
704
724
  raise(msg)
705
725
  end
706
726
 
727
+ def has_text?(text)
728
+ !query("* {text CONTAINS[c] '#{text}'}").empty?
729
+ end
730
+
731
+ def assert_text(text, should_find = true)
732
+ raise "Text \"#{text}\" was #{should_find ? 'not ' : ''}found." if has_text?(text) ^ should_find
733
+
734
+ true
735
+ end
736
+
707
737
  def double_tap(uiquery, options = {})
708
738
  center_x, center_y = find_coordinate(uiquery)
709
739
 
710
- performAction("double_tap_coordinate", center_x, center_y)
740
+ perform_action("double_tap_coordinate", center_x, center_y)
711
741
  end
712
742
 
743
+ # Performs a "long press" operation on a selected view
744
+ # Params:
745
+ # +uiquery+: a uiquery identifying one view
746
+ # +options[:length]+: the length of the long press in milliseconds (optional)
747
+ #
748
+ # Examples:
749
+ # - long_press("* id:'my_id'")
750
+ # - long_press("* id:'my_id'", {:length=>5000})
713
751
  def long_press(uiquery, options = {})
714
752
  center_x, center_y = find_coordinate(uiquery)
715
-
716
- performAction("long_press_coordinate", center_x, center_y)
753
+ length = options[:length]
754
+ perform_action("long_press_coordinate", center_x, center_y, *(length unless length.nil?))
717
755
  end
718
756
 
719
757
  def touch(uiquery, options = {})
720
758
  center_x, center_y = find_coordinate(uiquery)
721
759
 
722
- performAction("touch_coordinate", center_x, center_y)
760
+ perform_action("touch_coordinate", center_x, center_y)
723
761
  end
724
762
 
725
763
  def keyboard_enter_text(text, options = {})
726
- performAction('keyboard_enter_text', text)
764
+ perform_action('keyboard_enter_text', text)
727
765
  end
728
766
 
729
767
  def enter_text(uiquery, text, options = {})
730
- touch(uiquery, options)
768
+ tap_when_element_exists(uiquery, options)
731
769
  sleep 0.5
732
770
  keyboard_enter_text(text, options)
733
771
  end
734
772
 
773
+ def clear_text(query_string, options={})
774
+ result = query(query_string, setText: '')
775
+
776
+ raise "No elements found. Query: #{query_string}" if result.empty?
777
+
778
+ true
779
+ end
780
+
735
781
  def find_coordinate(uiquery)
736
782
  raise "Cannot find nil" unless uiquery
737
783
 
784
+ element = execute_uiquery(uiquery)
785
+
786
+ raise "No elements found. Query: #{uiquery}" if element.nil?
787
+
788
+ center_x = element["rect"]["center_x"]
789
+ center_y = element["rect"]["center_y"]
790
+
791
+ [center_x, center_y]
792
+ end
793
+
794
+ def execute_uiquery(uiquery)
738
795
  if uiquery.instance_of? String
739
796
  elements = query(uiquery)
740
- raise "No elements found. Query: #{uiquery}" if elements.empty?
741
- element = elements.first
797
+
798
+ return elements.first unless elements.empty?
742
799
  else
743
- element = uiquery
744
- element = element.first if element.instance_of?(Array)
800
+ elements = uiquery
801
+
802
+ return elements.first if elements.instance_of?(Array)
803
+ return elements if elements.instance_of?(Hash)
745
804
  end
746
805
 
747
- center_x = element["rect"]["center_x"]
748
- center_y = element["rect"]["center_y"]
806
+ nil
807
+ end
749
808
 
750
- [center_x, center_y]
809
+ def step_deprecated
810
+ puts 'Warning: This predefined step is deprecated.'
751
811
  end
752
812
 
753
813
  def http(path, data = {}, options = {})
@@ -759,16 +819,52 @@ module Operations
759
819
  end
760
820
 
761
821
  def set_text(uiquery, txt)
762
- view,arguments = uiquery.split(" ",2)
763
- raise "Currently queries are only supported for webviews" unless view.downcase == "webview"
822
+ puts "set_text is deprecated. Use enter_text instead"
823
+ enter_text(uiquery, txt)
824
+ end
825
+
826
+ def press_back_button
827
+ perform_action('go_back')
828
+ end
829
+
830
+ def press_menu_button
831
+ perform_action('press_menu')
832
+ end
833
+
834
+ def select_options_menu_item(text, options={})
835
+ press_menu_button
836
+ tap_when_element_exists("DropDownListView * marked:'#{text}'", options)
837
+ end
838
+
839
+ def select_context_menu_item(view_uiquery, menu_item_query_string)
840
+ long_press(view_uiquery)
841
+
842
+ container_class = 'com.android.internal.view.menu.ListMenuItemView'
843
+ wait_for_element_exists(container_class)
844
+
845
+ combined_query_string = "#{container_class} descendant #{menu_item_query_string}"
846
+ touch(combined_query_string)
847
+ end
848
+
849
+ def tap_when_element_exists(query_string, options={})
850
+ options.merge!({action: lambda {|q| touch(q)}})
764
851
 
765
- if arguments =~ /(css|xpath):\s*(.*)/
766
- r = performAction("set_text", $1, $2, txt)
852
+ if options[:scroll] == true
853
+ scroll_to(query_string, options)
767
854
  else
768
- raise "Invalid query #{arguments}"
855
+ when_element_exists(query_string, options)
769
856
  end
770
857
  end
771
858
 
859
+ def long_press_when_element_exists(query_string, options={})
860
+ options.merge!({action: lambda {|q| long_press(q)}})
861
+
862
+ if options[:scroll] == true
863
+ scroll_to(query_string, options)
864
+ else
865
+ when_element_exists(query_string, options)
866
+ end
867
+ end
772
868
 
773
869
  def swipe(dir,options={})
774
870
  ni
@@ -782,8 +878,82 @@ module Operations
782
878
  ni
783
879
  end
784
880
 
785
- def scroll(uiquery,direction)
786
- ni
881
+ def scroll_up
882
+ scroll("android.widget.ScrollView", :up)
883
+ end
884
+
885
+ def scroll_down
886
+ scroll("android.widget.ScrollView", :down)
887
+ end
888
+
889
+ def scroll(query_string, direction)
890
+ if direction != :up && direction != :down
891
+ raise 'Only upwards and downwards scrolling is supported for now'
892
+ end
893
+
894
+ scroll_x = 0
895
+ scroll_y = 0
896
+
897
+ action = lambda do
898
+ element = query(query_string).first
899
+ raise "No elements found. Query: #{query_string}" if element.nil?
900
+
901
+ width = element['rect']['width']
902
+ height = element['rect']['height']
903
+
904
+ if direction == :up
905
+ scroll_y = -height/2
906
+ else
907
+ scroll_y = height/2
908
+ end
909
+
910
+ query(query_string, {scrollBy: [scroll_x.to_i, scroll_y.to_i]})
911
+ end
912
+
913
+ when_element_exists(query_string, action: action)
914
+ end
915
+
916
+ def scroll_to(query_string, options={})
917
+ options[:action] ||= lambda {}
918
+
919
+ all_query_string = query_string
920
+
921
+ unless all_query_string.chomp.downcase.start_with?('all')
922
+ all_query_string = "all #{all_query_string}"
923
+ end
924
+
925
+ wait_for_element_exists(all_query_string)
926
+
927
+ visibility_query_string = all_query_string[4..-1]
928
+
929
+ unless query(visibility_query_string).empty?
930
+ when_element_exists(visibility_query_string, options)
931
+ return
932
+ end
933
+
934
+ element = query(all_query_string).first
935
+ raise "No elements found. Query: #{all_query_string}" if element.nil?
936
+ element_center_y = element['rect']['center_y']
937
+
938
+ scroll_view_query_string = "#{all_query_string} parent android.widget.ScrollView index:0"
939
+ scroll_element = query(scroll_view_query_string).first
940
+
941
+ raise "Could not find parent scroll view. Query: #{scroll_view_query_string}" if element.nil?
942
+
943
+ scroll_element_y = scroll_element['rect']['y']
944
+ scroll_element_height = scroll_element['rect']['height']
945
+
946
+ if element_center_y > scroll_element_y + scroll_element_height
947
+ scroll_by_y = element_center_y - (scroll_element_y + scroll_element_height) + 2
948
+ else
949
+ scroll_by_y = element_center_y - scroll_element_y - 2
950
+ end
951
+
952
+ result = query(scroll_view_query_string, {scrollBy: [0, scroll_by_y.to_i]}).first
953
+ raise 'Could not scroll parent view' if result != '<VOID>'
954
+
955
+ visibility_query_string = all_query_string[4..-1]
956
+ when_element_exists(visibility_query_string, options)
787
957
  end
788
958
 
789
959
  def scroll_to_row(uiquery,number)
@@ -858,7 +1028,13 @@ module Operations
858
1028
  end
859
1029
 
860
1030
  def backdoor(sel, arg)
861
- ni
1031
+ result = perform_action("backdoor", sel, arg)
1032
+ if !result["success"]
1033
+ screenshot_and_raise(result["message"])
1034
+ end
1035
+
1036
+ # for android results are returned in bonusInformation
1037
+ result["bonusInformation"].first
862
1038
  end
863
1039
 
864
1040
  def map(query, method_name, *method_args)