calabash-android 0.4.22.pre4 → 0.5.0.pre1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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)