calabash-cucumber 0.10.0.pre1 → 0.10.0.pre2

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 (184) hide show
  1. checksums.yaml +4 -4
  2. data/features/step_definitions/calabash_steps.rb +1 -1
  3. data/lib/calabash-cucumber/actions/instruments_actions.rb +15 -4
  4. data/lib/calabash-cucumber/actions/playback_actions.rb +12 -3
  5. data/lib/calabash-cucumber/connection.rb +3 -0
  6. data/lib/calabash-cucumber/connection_helpers.rb +4 -0
  7. data/lib/calabash-cucumber/core.rb +637 -83
  8. data/lib/calabash-cucumber/date_picker.rb +148 -29
  9. data/lib/calabash-cucumber/device.rb +160 -3
  10. data/lib/calabash-cucumber/environment_helpers.rb +91 -46
  11. data/lib/calabash-cucumber/failure_helpers.rb +40 -0
  12. data/lib/calabash-cucumber/http_helpers.rb +9 -2
  13. data/lib/calabash-cucumber/ibase.rb +136 -17
  14. data/lib/calabash-cucumber/ios7_operations.rb +13 -9
  15. data/lib/calabash-cucumber/ipad_1x_2x.rb +103 -48
  16. data/lib/calabash-cucumber/keyboard_helpers.rb +253 -144
  17. data/lib/calabash-cucumber/keychain_helpers.rb +46 -32
  18. data/lib/calabash-cucumber/launch/simulator_helper.rb +13 -12
  19. data/lib/calabash-cucumber/launch/simulator_launcher.rb +111 -78
  20. data/lib/calabash-cucumber/launcher.rb +265 -25
  21. data/lib/calabash-cucumber/map.rb +24 -22
  22. data/lib/calabash-cucumber/operations.rb +4 -160
  23. data/lib/calabash-cucumber/playback_helpers.rb +26 -0
  24. data/lib/calabash-cucumber/query_helpers.rb +12 -0
  25. data/lib/calabash-cucumber/rotation_helpers.rb +64 -8
  26. data/lib/calabash-cucumber/status_bar_helpers.rb +40 -3
  27. data/lib/calabash-cucumber/tests_helpers.rb +43 -14
  28. data/lib/calabash-cucumber/uia.rb +93 -9
  29. data/lib/calabash-cucumber/utils/logging.rb +30 -16
  30. data/lib/calabash-cucumber/utils/plist_buddy.rb +18 -19
  31. data/lib/calabash-cucumber/utils/simulator_accessibility.rb +41 -30
  32. data/lib/calabash-cucumber/utils/xctools.rb +31 -21
  33. data/lib/calabash-cucumber/version.rb +98 -2
  34. data/lib/calabash-cucumber/wait_helpers.rb +257 -77
  35. data/staticlib/calabash.framework.zip +0 -0
  36. metadata +64 -231
  37. data/.gitignore +0 -17
  38. data/CHANGES.txt +0 -1
  39. data/Gemfile +0 -4
  40. data/Rakefile +0 -72
  41. data/calabash-cucumber.gemspec +0 -36
  42. data/epl-v10.html +0 -261
  43. data/lib/calabash-cucumber/resources/cell_swipe_ios4_ipad.base64 +0 -51
  44. data/lib/calabash-cucumber/resources/cell_swipe_ios4_iphone.base64 +0 -51
  45. data/lib/calabash-cucumber/resources/cell_swipe_ios5_ipad.base64 +0 -74
  46. data/lib/calabash-cucumber/resources/cell_swipe_ios5_iphone.base64 +0 -74
  47. data/lib/calabash-cucumber/resources/double_tap_ios5_ipad.base64 +0 -15
  48. data/lib/calabash-cucumber/resources/double_tap_ios5_iphone.base64 +0 -15
  49. data/lib/calabash-cucumber/resources/double_tap_ios6_ipad.base64 +0 -22
  50. data/lib/calabash-cucumber/resources/double_tap_ios6_iphone.base64 +0 -22
  51. data/lib/calabash-cucumber/resources/pan_ios5_ipad.base64 +0 -199
  52. data/lib/calabash-cucumber/resources/pan_ios5_iphone.base64 +0 -199
  53. data/lib/calabash-cucumber/resources/pan_ios6_ipad.base64 +0 -206
  54. data/lib/calabash-cucumber/resources/pan_ios6_iphone.base64 +0 -206
  55. data/lib/calabash-cucumber/resources/pinch_in_ios4_ipad.base64 +0 -104
  56. data/lib/calabash-cucumber/resources/pinch_in_ios4_iphone.base64 +0 -104
  57. data/lib/calabash-cucumber/resources/pinch_in_ios5_ipad.base64 +0 -144
  58. data/lib/calabash-cucumber/resources/pinch_in_ios5_iphone.base64 +0 -144
  59. data/lib/calabash-cucumber/resources/pinch_in_ios6_ipad.base64 +0 -70
  60. data/lib/calabash-cucumber/resources/pinch_in_ios6_iphone.base64 +0 -70
  61. data/lib/calabash-cucumber/resources/pinch_out_ios5_ipad.base64 +0 -207
  62. data/lib/calabash-cucumber/resources/pinch_out_ios5_iphone.base64 +0 -207
  63. data/lib/calabash-cucumber/resources/pinch_out_ios6_ipad.base64 +0 -96
  64. data/lib/calabash-cucumber/resources/pinch_out_ios6_iphone.base64 +0 -96
  65. data/lib/calabash-cucumber/resources/rotate_left_home_down_ios4_ipad.base64 +0 -2
  66. data/lib/calabash-cucumber/resources/rotate_left_home_down_ios4_iphone.base64 +0 -2
  67. data/lib/calabash-cucumber/resources/rotate_left_home_down_ios5_ipad.base64 +0 -2
  68. data/lib/calabash-cucumber/resources/rotate_left_home_down_ios5_iphone.base64 +0 -2
  69. data/lib/calabash-cucumber/resources/rotate_left_home_left_ios4_ipad.base64 +0 -2
  70. data/lib/calabash-cucumber/resources/rotate_left_home_left_ios4_iphone.base64 +0 -2
  71. data/lib/calabash-cucumber/resources/rotate_left_home_left_ios5_ipad.base64 +0 -2
  72. data/lib/calabash-cucumber/resources/rotate_left_home_left_ios5_iphone.base64 +0 -2
  73. data/lib/calabash-cucumber/resources/rotate_left_home_right_ios4_ipad.base64 +0 -2
  74. data/lib/calabash-cucumber/resources/rotate_left_home_right_ios4_iphone.base64 +0 -2
  75. data/lib/calabash-cucumber/resources/rotate_left_home_right_ios5_ipad.base64 +0 -2
  76. data/lib/calabash-cucumber/resources/rotate_left_home_right_ios5_iphone.base64 +0 -2
  77. data/lib/calabash-cucumber/resources/rotate_left_home_up_ios4_ipad.base64 +0 -2
  78. data/lib/calabash-cucumber/resources/rotate_left_home_up_ios4_iphone.base64 +0 -2
  79. data/lib/calabash-cucumber/resources/rotate_left_home_up_ios5_ipad.base64 +0 -2
  80. data/lib/calabash-cucumber/resources/rotate_left_home_up_ios5_iphone.base64 +0 -2
  81. data/lib/calabash-cucumber/resources/rotate_right_home_down_ios4_ipad.base64 +0 -2
  82. data/lib/calabash-cucumber/resources/rotate_right_home_down_ios4_iphone.base64 +0 -2
  83. data/lib/calabash-cucumber/resources/rotate_right_home_down_ios5_ipad.base64 +0 -2
  84. data/lib/calabash-cucumber/resources/rotate_right_home_down_ios5_iphone.base64 +0 -2
  85. data/lib/calabash-cucumber/resources/rotate_right_home_left_ios4_ipad.base64 +0 -2
  86. data/lib/calabash-cucumber/resources/rotate_right_home_left_ios4_iphone.base64 +0 -2
  87. data/lib/calabash-cucumber/resources/rotate_right_home_left_ios5_ipad.base64 +0 -2
  88. data/lib/calabash-cucumber/resources/rotate_right_home_left_ios5_iphone.base64 +0 -2
  89. data/lib/calabash-cucumber/resources/rotate_right_home_right_ios4_ipad.base64 +0 -2
  90. data/lib/calabash-cucumber/resources/rotate_right_home_right_ios4_iphone.base64 +0 -2
  91. data/lib/calabash-cucumber/resources/rotate_right_home_right_ios5_ipad.base64 +0 -2
  92. data/lib/calabash-cucumber/resources/rotate_right_home_right_ios5_iphone.base64 +0 -2
  93. data/lib/calabash-cucumber/resources/rotate_right_home_up_ios4_ipad.base64 +0 -2
  94. data/lib/calabash-cucumber/resources/rotate_right_home_up_ios4_iphone.base64 +0 -2
  95. data/lib/calabash-cucumber/resources/rotate_right_home_up_ios5_ipad.base64 +0 -2
  96. data/lib/calabash-cucumber/resources/rotate_right_home_up_ios5_iphone.base64 +0 -2
  97. data/lib/calabash-cucumber/resources/swipe_down_ios5_ipad.base64 +0 -18
  98. data/lib/calabash-cucumber/resources/swipe_down_ios5_iphone.base64 +0 -31
  99. data/lib/calabash-cucumber/resources/swipe_down_ios6_ipad.base64 +0 -25
  100. data/lib/calabash-cucumber/resources/swipe_down_ios6_iphone.base64 +0 -25
  101. data/lib/calabash-cucumber/resources/swipe_left_hard_ios4_ipad.base64 +0 -15
  102. data/lib/calabash-cucumber/resources/swipe_left_hard_ios4_iphone.base64 +0 -15
  103. data/lib/calabash-cucumber/resources/swipe_left_ios4_ipad.base64 +0 -18
  104. data/lib/calabash-cucumber/resources/swipe_left_ios4_iphone.base64 +0 -18
  105. data/lib/calabash-cucumber/resources/swipe_left_ios5_ipad.base64 +0 -17
  106. data/lib/calabash-cucumber/resources/swipe_left_ios5_iphone.base64 +0 -34
  107. data/lib/calabash-cucumber/resources/swipe_left_ios6_ipad.base64 +0 -28
  108. data/lib/calabash-cucumber/resources/swipe_left_ios6_iphone.base64 +0 -28
  109. data/lib/calabash-cucumber/resources/swipe_right_hard_ios4_ipad.base64 +0 -17
  110. data/lib/calabash-cucumber/resources/swipe_right_hard_ios4_iphone.base64 +0 -17
  111. data/lib/calabash-cucumber/resources/swipe_right_ios4_ipad.base64 +0 -13
  112. data/lib/calabash-cucumber/resources/swipe_right_ios4_iphone.base64 +0 -13
  113. data/lib/calabash-cucumber/resources/swipe_right_ios5_ipad.base64 +0 -17
  114. data/lib/calabash-cucumber/resources/swipe_right_ios5_iphone.base64 +0 -17
  115. data/lib/calabash-cucumber/resources/swipe_right_ios6_ipad.base64 +0 -25
  116. data/lib/calabash-cucumber/resources/swipe_right_ios6_iphone.base64 +0 -25
  117. data/lib/calabash-cucumber/resources/swipe_up_ios5_ipad.base64 +0 -34
  118. data/lib/calabash-cucumber/resources/swipe_up_ios5_iphone.base64 +0 -28
  119. data/lib/calabash-cucumber/resources/swipe_up_ios6_ipad.base64 +0 -25
  120. data/lib/calabash-cucumber/resources/swipe_up_ios6_iphone.base64 +0 -25
  121. data/lib/calabash-cucumber/resources/touch_done_ios4_ipad.base64 +0 -7
  122. data/lib/calabash-cucumber/resources/touch_done_ios4_iphone.base64 +0 -9
  123. data/lib/calabash-cucumber/resources/touch_done_ios5_ipad.base64 +0 -7
  124. data/lib/calabash-cucumber/resources/touch_done_ios5_iphone.base64 +0 -9
  125. data/lib/calabash-cucumber/resources/touch_hold_ios5_ipad.base64 +0 -9
  126. data/lib/calabash-cucumber/resources/touch_hold_ios5_iphone.base64 +0 -9
  127. data/lib/calabash-cucumber/resources/touch_hold_ios6_ipad.base64 +0 -9
  128. data/lib/calabash-cucumber/resources/touch_hold_ios6_iphone.base64 +0 -9
  129. data/lib/calabash-cucumber/resources/touch_ios4_ipad.base64 +0 -9
  130. data/lib/calabash-cucumber/resources/touch_ios4_iphone.base64 +0 -9
  131. data/lib/calabash-cucumber/resources/touch_ios5_ipad.base64 +0 -9
  132. data/lib/calabash-cucumber/resources/touch_ios5_iphone.base64 +0 -9
  133. data/lib/calabash-cucumber/resources/touch_ios7_ipad.base64 +0 -9
  134. data/lib/calabash-cucumber/resources/touch_ios7_iphone.base64 +0 -9
  135. data/lib/calabash-cucumber/resources/wheel_down_ios4_ipad.base64 +0 -159
  136. data/lib/calabash-cucumber/resources/wheel_down_ios4_iphone.base64 +0 -159
  137. data/lib/calabash-cucumber/resources/wheel_down_ios5_ipad.base64 +0 -156
  138. data/lib/calabash-cucumber/resources/wheel_down_ios5_iphone.base64 +0 -156
  139. data/lib/calabash-cucumber/resources/wheel_up_ios4_ipad.base64 +0 -166
  140. data/lib/calabash-cucumber/resources/wheel_up_ios4_iphone.base64 +0 -166
  141. data/lib/calabash-cucumber/resources/wheel_up_ios5_ipad.base64 +0 -156
  142. data/lib/calabash-cucumber/resources/wheel_up_ios5_iphone.base64 +0 -156
  143. data/scripts/EmptyAppHack.app/Default-568h@2x.png +0 -0
  144. data/scripts/EmptyAppHack.app/Default.png +0 -0
  145. data/scripts/EmptyAppHack.app/Default@2x.png +0 -0
  146. data/scripts/EmptyAppHack.app/EmptyAppHack +0 -0
  147. data/scripts/EmptyAppHack.app/Info.plist +0 -0
  148. data/scripts/EmptyAppHack.app/PkgInfo +0 -1
  149. data/scripts/EmptyAppHack.app/en.lproj/InfoPlist.strings +0 -0
  150. data/scripts/com.example.plist +0 -0
  151. data/scripts/data/.GlobalPreferences.plist +0 -0
  152. data/scripts/reset_simulator.scpt +0 -0
  153. data/spec/bin/calabash_ios_sim_spec.rb +0 -24
  154. data/spec/launcher_spec.rb +0 -166
  155. data/spec/logging_spec.rb +0 -38
  156. data/spec/plist_buddy_spec.rb +0 -99
  157. data/spec/resources/enable-accessibility/6.1/.gitkeep +0 -0
  158. data/spec/resources/enable-accessibility/7.0.3-64/.gitkeep +0 -0
  159. data/spec/resources/enable-accessibility/7.0.3/.gitkeep +0 -0
  160. data/spec/resources/enable-accessibility/7.1-64/.gitkeep +0 -0
  161. data/spec/resources/enable-accessibility/7.1/.gitkeep +0 -0
  162. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/Default-568h@2x.png +0 -0
  163. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/Info.plist +0 -0
  164. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/LPSimpleExample-cal +0 -0
  165. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/PkgInfo +0 -1
  166. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/InfoPlist.strings +0 -0
  167. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPFirstViewController.nib +0 -0
  168. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPFirstViewController~ipad.nib +0 -0
  169. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPFourthViewController.nib +0 -0
  170. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPFourthViewController~ipad.nib +0 -0
  171. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPSecondViewController.nib +0 -0
  172. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPSecondViewController~ipad.nib +0 -0
  173. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPThirdViewController.nib +0 -0
  174. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPThirdViewController~ipad.nib +0 -0
  175. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/first.png +0 -0
  176. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/first@2x.png +0 -0
  177. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/second.png +0 -0
  178. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/second@2x.png +0 -0
  179. data/spec/resources/plist_buddy/com.example.plist +0 -0
  180. data/spec/resources/plist_buddy/com.testing.plist +0 -18
  181. data/spec/simulator_accessibility_spec.rb +0 -206
  182. data/spec/spec_helper.rb +0 -31
  183. data/spec/version_spec.rb +0 -13
  184. data/spec/xctools_spec.rb +0 -58
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4e7927ef644a1b54f7448642b9d06207c30d2781
4
- data.tar.gz: 46d85fece887a5df72522a76597503d5ae1c46da
3
+ metadata.gz: 58c9160b3ab46994846c1a6ba017d7ad33a552d3
4
+ data.tar.gz: bb4bf0b81e4d8b6723ba8827fad48384202b2394
5
5
  SHA512:
6
- metadata.gz: fcf04088f7b3eb9150167371e768f45531c72ff3d5f459be76f3f57a07c18590d83d82adc1b6f274b20d2324bb92797f1c1c761bc991356ba4fb977e9d4c8d96
7
- data.tar.gz: 51225cb4a75b0dbeb6f23f56dc579b1ea55a77c36ccbbb1c050d3296eedfb185dae4db587978c13cf7c1d0f55fc1639c212d0d81f1a1e591a6b6585c5b82d7c6
6
+ metadata.gz: b3d7061cf22b4bdef135a9abc4cf7f69a2356616893940e7d03e6064c7f1ea6f4e83ee2ff73d80a7fdf9103dc76780631069ae178ffad9676400dbe8e4647e22
7
+ data.tar.gz: a0b47ef74ffed7850725ae2047c9e0f2189a75e538a1064759035b7e045401844141b7dd8994d1c4fce22df72e118ddb5fa3419f7f2b7aa2c19469357acacbff
@@ -17,7 +17,7 @@ Then /^I (?:press|touch) "([^\"]*)"$/ do |name|
17
17
  sleep(STEP_PAUSE)
18
18
  end
19
19
 
20
- Then /^I (?:press|touch) (\d+)% right and (\d+)% down from "([^\"]*)" $/ do |x,y,name|
20
+ Then /^I (?:press|touch) (\d+)% right and (\d+)% down from "([^\"]*)"$/ do |x,y,name|
21
21
  raise "This step is not yet implemented on iOS"
22
22
  end
23
23
 
@@ -3,28 +3,34 @@ require 'calabash-cucumber/connection_helpers'
3
3
  require 'calabash-cucumber/query_helpers'
4
4
  require 'calabash-cucumber/map'
5
5
 
6
+ # @!visibility private
6
7
  class Calabash::Cucumber::InstrumentsActions
7
8
  include Calabash::Cucumber::UIA
8
9
  include Calabash::Cucumber::ConnectionHelpers
9
10
  include Calabash::Cucumber::QueryHelpers
10
11
  include Calabash::Cucumber::Map
11
12
 
13
+ # @!visibility private
12
14
  def touch(options)
13
15
  query_action(options, :uia_tap_offset)
14
16
  end
15
17
 
18
+ # @!visibility private
16
19
  def wait_tap(options)
17
20
  uia_wait_tap(options[:query], options)
18
21
  end
19
22
 
23
+ # @!visibility private
20
24
  def double_tap(options)
21
25
  query_action(options, :uia_double_tap_offset)
22
26
  end
23
27
 
28
+ # @!visibility private
24
29
  def two_finger_tap(options)
25
30
  query_action(options, :uia_two_finger_tap_offset)
26
31
  end
27
32
 
33
+ # @!visibility private
28
34
  def flick(options)
29
35
  query_action(options) do |offset|
30
36
  delta = {:offset => options[:delta] || {}}
@@ -32,28 +38,30 @@ class Calabash::Cucumber::InstrumentsActions
32
38
  end
33
39
  end
34
40
 
35
-
41
+ # @!visibility private
36
42
  def touch_hold(options)
37
43
  query_action(options) do |offset|
38
- duration = options[:duration] || 4
44
+ duration = options[:duration] || 3
39
45
  uia_touch_hold_offset(duration, offset)
40
46
  end
41
47
  end
42
48
 
49
+ # @!visibility private
43
50
  def swipe(dir, options={})
44
51
  options = options.merge(:direction => dir)
45
52
  query_action(options, :uia_swipe_offset, options)
46
53
  end
47
54
 
55
+ # @!visibility private
48
56
  def pan(from, to, options={})
49
57
  query_action(:query => from) do |from_offset|
50
58
  query_action(:query => to) do |to_offset|
51
59
  uia_pan_offset(from_offset, to_offset, options)
52
60
  end
53
61
  end
54
-
55
62
  end
56
63
 
64
+ # @!visibility private
57
65
  def pinch(in_out, options)
58
66
  query_action(options) do |offset|
59
67
  options[:duration] = options[:duration] || 0.5
@@ -61,12 +69,14 @@ class Calabash::Cucumber::InstrumentsActions
61
69
  end
62
70
  end
63
71
 
72
+ # @!visibility private
64
73
  def send_app_to_background(secs)
65
74
  uia_send_app_to_background(secs)
66
75
  end
67
76
 
68
77
  private
69
78
 
79
+ # @!visibility private
70
80
  # Data interface
71
81
  # options[:query] or options[:offset]
72
82
  def query_action(options, action=nil, *args, &block)
@@ -93,6 +103,7 @@ class Calabash::Cucumber::InstrumentsActions
93
103
  end
94
104
  end
95
105
 
106
+ # @!visibility private
96
107
  def find_and_normalize(ui_query)
97
108
  raw_result = raw_map(ui_query, :query)
98
109
  orientation = raw_result['status_bar_orientation']
@@ -106,6 +117,7 @@ class Calabash::Cucumber::InstrumentsActions
106
117
  res
107
118
  end
108
119
 
120
+ # @!visibility private
109
121
  def normalize_rect_for_orientation!(orientation, rect)
110
122
  orientation = orientation.to_sym
111
123
  launcher = Calabash::Cucumber::Launcher.launcher
@@ -129,5 +141,4 @@ class Calabash::Cucumber::InstrumentsActions
129
141
  end
130
142
  end
131
143
 
132
-
133
144
  end
@@ -2,37 +2,43 @@ require 'calabash-cucumber/playback_helpers'
2
2
  require 'calabash-cucumber/connection_helpers'
3
3
  require 'calabash-cucumber/query_helpers'
4
4
 
5
-
5
+ # @!visibility private
6
6
  class Calabash::Cucumber::PlaybackActions
7
7
  include Calabash::Cucumber::PlaybackHelpers
8
8
  include Calabash::Cucumber::ConnectionHelpers
9
9
  include Calabash::Cucumber::QueryHelpers
10
10
 
11
-
11
+ # @!visibility private
12
12
  def touch(options)
13
13
  playback('touch', options)
14
14
  end
15
15
 
16
+ # @!visibility private
16
17
  def wait_tap(options)
17
18
  touch(options)
18
19
  end
19
20
 
21
+ # @!visibility private
20
22
  def double_tap(options)
21
23
  playback('double_tap', options)
22
24
  end
23
25
 
26
+ # @!visibility private
24
27
  def two_finger_tap(*args)
25
28
  raise error_message('two_finger_tap')
26
29
  end
27
30
 
31
+ # @!visibility private
28
32
  def flick(*args)
29
33
  raise error_message('flick')
30
34
  end
31
35
 
36
+ # @!visibility private
32
37
  def touch_hold(options)
33
38
  playback('touch_hold', options)
34
39
  end
35
40
 
41
+ # @!visibility private
36
42
  def swipe(dir, options={})
37
43
  current_orientation = options[:status_bar_orientation].to_sym
38
44
  if current_orientation == :left
@@ -81,10 +87,12 @@ class Calabash::Cucumber::PlaybackActions
81
87
 
82
88
  end
83
89
 
90
+ # @!visibility private
84
91
  def pan(from,to,options={})
85
92
  interpolate 'pan', options.merge(:start => from, :end => to)
86
93
  end
87
94
 
95
+ # @!visibility private
88
96
  def pinch(in_out,options)
89
97
  file = "pinch_in"
90
98
  if in_out==:out
@@ -93,12 +101,13 @@ class Calabash::Cucumber::PlaybackActions
93
101
  playback(file, options)
94
102
  end
95
103
 
104
+ # @!visibility private
96
105
  def send_app_to_background(secs)
97
106
  raise 'Not implemented when running without instruments / UIA'
98
107
  end
99
108
 
100
-
101
109
  private
110
+ # @!visibility private
102
111
  def error_message(gesture)
103
112
  "Gesture: '#{gesture}' not supported unless running with instruments."
104
113
  end
@@ -3,10 +3,13 @@ require 'calabash-cucumber/http_helpers'
3
3
 
4
4
  module Calabash
5
5
  module Cucumber
6
+
7
+ # @!visibility private
6
8
  class Connection
7
9
  include Singleton
8
10
  include HTTPHelpers
9
11
 
12
+ # @!visibility private
10
13
  def client
11
14
  @http
12
15
  end
@@ -2,12 +2,16 @@ require 'calabash-cucumber/connection'
2
2
 
3
3
  module Calabash
4
4
  module Cucumber
5
+
6
+ # @!visibility private
5
7
  module ConnectionHelpers
6
8
 
9
+ # @!visibility private
7
10
  def http(*args)
8
11
  connection.http(*args)
9
12
  end
10
13
 
14
+ # @!visibility private
11
15
  def connection
12
16
  Calabash::Cucumber::Connection.instance
13
17
  end
@@ -21,6 +21,8 @@ require 'calabash-cucumber/launch/simulator_helper'
21
21
 
22
22
  module Calabash
23
23
  module Cucumber
24
+
25
+ # A collection of methods that provide the core calabash behaviors.
24
26
  module Core
25
27
 
26
28
  include Calabash::Cucumber::Logging
@@ -34,6 +36,10 @@ module Calabash
34
36
  include Calabash::Cucumber::RotationHelpers
35
37
  include Calabash::Cucumber::PlaybackHelpers
36
38
 
39
+ # @!visibility private
40
+ # @deprecated Use Cucumber's step method (avoid this: using step is not considered best practice).
41
+ # Used in older cucumber versions that didn't have the `step` method.
42
+ # Shouldn't be used anymore.
37
43
  def macro(txt)
38
44
  if self.respond_to? :step
39
45
  step(txt)
@@ -42,37 +48,106 @@ module Calabash
42
48
  end
43
49
  end
44
50
 
51
+ # The core method for querying into the current visible view
52
+ # of the app under test. The query method takes as first parameter
53
+ # a String `:uiquery`. This string must follow the query syntax
54
+ # described in:
55
+ # {http://developer.xamarin.com/guides/testcloud/calabash/calabash-query-syntax/ Query Syntax}.
56
+ #
57
+ # Optionally `query` takes a variable number of "invocation" arguments
58
+ # (`args` below). # If called with an empty list of `*args`, `query`
59
+ # will find the views specified by `uiquery` and return a serialized view
60
+ # (see Examples below).
61
+ #
62
+ # If `*args` are given, then they should describe a valid selector invocation
63
+ # on the queried views. For example `query('UILabel', :text)` would perform
64
+ # the `:text` selector on all visible `UILabel` objects and return those as
65
+ # an Array of Strings.
66
+ #
67
+ # The `query` method provide a powerful mechanism for `querying` app view state
68
+ # and can be used to reflectively call arbitrary methods on objects reachable
69
+ # from the view. For a full specification of `*args` see
70
+ # {http://developer.xamarin.com/guides/testcloud/calabash/calabash-query-syntax/ Query Syntax}.
71
+ #
72
+ # @example Basic view query
73
+ # irb(main):009:0> query("UITabBarButton index:0")
74
+ # [
75
+ # [0] {
76
+ # "class" => "UITabBarButton",
77
+ # "id" => nil,
78
+ # "rect" => {
79
+ # "center_x" => 40,
80
+ # "y" => 520,
81
+ # "width" => 76,
82
+ # "x" => 2,
83
+ # "center_y" => 544,
84
+ # "height" => 48
85
+ # },
86
+ # "frame" => {
87
+ # "y" => 1,
88
+ # "width" => 76,
89
+ # "x" => 2,
90
+ # "height" => 48
91
+ # },
92
+ # "label" => "Reader",
93
+ # "description" => "<UITabBarButton: 0xdabb510; frame = (2 1; 76 48); opaque = NO; layer = <CALayer: 0xdabd8e0>>"
94
+ # }
95
+ # ]
96
+ # @example Simple selector
97
+ # irb(main):010:0> query("UILabel", :text)
98
+ # [
99
+ # [0] "The Ugly Volvo",
100
+ # [1] "Why Having a Baby Reminds me of Garfield Minus Garfield",
101
+ # [2] "I love the site Garfield Minus Garfield. If you don’t know the site Garfield minus Garfield  it’s a website run by a guy named Dan Walsh who takes Garfield comic strips and digitally erases Garfield from them. more",
102
+ # [3] "Freshly Pressed",
103
+ # [4] "Reader",
104
+ # [5] "Notifications",
105
+ # [6] "Me"
106
+ # ]
107
+ # @param [String] uiquery the query to perform. Must follow the query syntax:
108
+ # {http://developer.xamarin.com/guides/testcloud/calabash/calabash-query-syntax/ Query Syntax}.
109
+ # @param [Array] args optional var-args list describing a chain of method selectors.
110
+ # Full details {http://developer.xamarin.com/guides/testcloud/calabash/calabash-query-syntax/ Query Syntax}.
45
111
  def query(uiquery, *args)
46
112
  map(uiquery, :query, *args)
47
113
  end
48
114
 
115
+ # Shorthand alias for `query`.
116
+ # @see #query
117
+ # @!visibility private
49
118
  def q(uiquery, *args)
50
119
  query(uiquery, *args)
51
120
  end
52
121
 
53
- # causes all views matched by the +query+ to briefly change colors making
122
+ # Causes all views matched by the `uiquery` to briefly change colors making
54
123
  # them visually identifiable.
55
124
  #
56
- # returns <tt>[]</tt> if no views are matched
57
- #
58
- # if there are matching views, returns an array of that contains the
59
- # result of calling the objc selector +description+ on each matching view.
125
+ # @param [String] uiquery a query specifying which objects to flash
126
+ # @param [Array] args argument is ignored and should be deprecated
127
+ # @return [Array] an array of that contains the result of calling the
128
+ # objc selector `description` on each matching view.
60
129
  #
61
- # NB: the +args+ argument is ignored and should be deprecated
62
130
  def flash(uiquery, *args)
63
131
  # todo deprecate the *args argument in the flash method
64
132
  # todo :flash operation should return views as JSON objects
65
133
  map(uiquery, :flash, *args).compact
66
134
  end
67
135
 
136
+ # Returns the version of the running calabash server.
137
+ # @return [String] version of the running calabash server.
68
138
  def server_version
69
139
  JSON.parse(http(:path => 'version'))
70
140
  end
71
141
 
142
+ # Returns the version of the loaded Calabash library.
143
+ # @see Calabash::Cucumber::VERSION
144
+ # @return [String] the version of the loaded Calabash library.
72
145
  def client_version
73
146
  Calabash::Cucumber::VERSION
74
147
  end
75
148
 
149
+ # Queries all views in view hierarchy, even if not visible.
150
+ # @deprecated use the 'all' or 'visible' modifier in query syntax
76
151
  def query_all(uiquery, *args)
77
152
  msg0 = "use the 'all' or 'visible' query language feature"
78
153
  msg1 = 'see: https://github.com/calabash/calabash-ios/wiki/05-Query-syntax'
@@ -81,28 +156,124 @@ module Calabash
81
156
  map("all #{uiquery}", :query, *args)
82
157
  end
83
158
 
159
+ # Performs the `tap` gesture on the (first) view that matches
160
+ # query `uiquery`. Note that `touch` assumes the view is visible and not animating.
161
+ # If the view is not visible `touch` will fail. If the view is animating
162
+ # `touch` will *silently* fail.
163
+ # By default, taps the center of the view.
164
+ # @see #wait_tap
165
+ # @see Calabash::Cucumber::Operations#tap_mark
166
+ # @see #tap_point
167
+ # @param {String} uiquery query describing view to tap. Note `nil` is allowed and is interpreted as
168
+ # `tap_point(options[:offset][:x],options[:offset][:y])`
169
+ # @param {Hash} options option for modifying the details of the touch
170
+ # @option options {Hash} :offset (nil) optional offset to touch point. Offset supports an `:x` and `:y` key
171
+ # and causes the touch to be offset with `(x,y)` relative to the center (`center + (offset[:x], offset[:y])`).
172
+ # @return {Array<Hash>} array containing the serialized version of the tapped view.
84
173
  def touch(uiquery, options={})
85
174
  query_action_with_options(:touch, uiquery, options)
86
175
  end
87
176
 
177
+ # Performs the `tap` gesture on an absolute coordinate.
178
+ # @see #wait_tap
179
+ # @see Calabash::Cucumber::Operations#tap_mark
180
+ # @see #touch
181
+ # @param {Numeric} x x-coordinate to tap
182
+ # @param {Numeric} y y-coordinate to tap
183
+ # @return {Boolean} `true`
184
+ def tap_point(x,y)
185
+ touch(nil, offset: {x:x, y:y})
186
+ end
187
+
188
+ # Performs the `tap` gesture on the (first) view that matches query `uiquery`.
189
+ #
190
+ # As opposed to `touch`, `wait_tap` is a high-level method that combines:
191
+ #
192
+ # 1. waiting for the view to appear,
193
+ # 2. waiting for animations to complete on the view (and it's parents) and
194
+ # 3. actually tapping the view.
195
+ #
196
+ # This removes the common boiler-plate trio: `wait_for_element_exists`,
197
+ # `wait_for_none_animating`, `touch`.
198
+ #
199
+ # By default, taps the center of the view.
200
+ # @see #touch
201
+ # @see #tap_point
202
+ # @param {String} uiquery query describing view to tap. Note `nil` is not allowed.
203
+ # @param {Hash} options option for modifying the details of the touch
204
+ # @option options {Hash} :offset (nil) optional offset to tap point. Offset has an `:x` and `:y` key
205
+ # the tap will be performed on the center of the view plus the offset.
206
+ # @option options {Hash} :timeout (30) maximum number of seconds to wait for the view to appear
207
+ # @option options {Hash} :frequency (0.2) polling frequency to for checking if the view is present (>= 0.1)
208
+ # @return {Array<Hash>} serialized version of the tapped view
88
209
  def wait_tap(uiquery, options={})
210
+ # noinspection RubyUnusedLocalVariable
89
211
  _uiquery, options = extract_query_and_options(uiquery, options)
90
212
  launcher.actions.wait_tap(options)
91
213
  end
92
214
 
93
- def t(uiquery, options={})
94
- wait_tap(uiquery, options)
95
- end
96
-
97
-
215
+ # Performs the "double tap" gesture on the (first) view that matches query `uiquery`.
216
+ #
217
+ # @note This assumes the view is visible and not animating.
218
+ #
219
+ # If the view is not visible it will fail with an error. If the view is animating
220
+ # it will *silently* fail.
221
+ #
222
+ # By default, taps the center of the view.
223
+ # @example
224
+ # double_tap "view marked:'Third'", offset:{x:100}
225
+ # @param {String} uiquery query describing view to touch.
226
+ # @param {Hash} options option for modifying the details of the touch
227
+ # @option options {Hash} :offset (nil) optional offset to touch point. Offset supports an `:x` and `:y` key
228
+ # and causes the touch to be offset with `(x,y)` relative to the center (`center + (offset[:x], offset[:y])`).
229
+ # @return {Array<Hash>} array containing the serialized version of the tapped view.
98
230
  def double_tap(uiquery, options={})
99
231
  query_action_with_options(:double_tap, uiquery, options)
100
232
  end
101
233
 
234
+ # Performs the "two-finger tap" gesture on the (first) view that matches
235
+ # query `uiquery`.
236
+ #
237
+ # @note This assumes the view is visible and not animating.
238
+ #
239
+ # If the view is not visible it will fail with an error. If the view is animating
240
+ # it will *silently* fail.
241
+ #
242
+ # By default, taps the center of the view.
243
+ #
244
+ # @example
245
+ # two_finger_tap "view marked:'Third'", offset:{x:100}
246
+ # @param {String} uiquery query describing view to touch.
247
+ # @param {Hash} options option for modifying the details of the touch.
248
+ # @option options {Hash} :offset (nil) optional offset to touch point. Offset supports an `:x` and `:y` key
249
+ # and causes the touch to be offset with `(x,y)` relative to the center (`center + (offset[:x], offset[:y])`).
250
+ # @return {Array<Hash>} array containing the serialized version of the tapped view.
102
251
  def two_finger_tap(uiquery,options={})
103
252
  query_action_with_options(:two_finger_tap, uiquery, options)
104
253
  end
105
254
 
255
+ # Performs the "flick" gesture on the (first) view that matches
256
+ # query `uiquery`.
257
+ #
258
+ # @note This assumes the view is visible and not animating.
259
+ #
260
+ # If the view is not visible it will fail with an error. If the view is animating
261
+ # it will *silently* fail.
262
+ #
263
+ # By default, the gesture starts at the center of the view and "flicks" according to `delta`.
264
+ #
265
+ # A flick is similar to a swipe.
266
+ #
267
+ # @example
268
+ # flick("MKMapView", {x:100,y:50})
269
+ # @param {String} uiquery query describing view to touch.
270
+ # @param {Hash} delta coordinate describing the direction to flick
271
+ # @param {Hash} options option for modifying the details of the touch.
272
+ # @option options {Hash} :offset (nil) optional offset to touch point. Offset supports an `:x` and `:y` key
273
+ # and causes the touch to be offset with `(x,y)` relative to the center (`center + (offset[:x], offset[:y])`).
274
+ # @option delta {Numeric} :x (0) optional. The force and direction of the flick on the `x`-axis
275
+ # @option delta {Numeric} :y (0) optional. The force and direction of the flick on the `y`-axis
276
+ # @return {Array<Hash>} array containing the serialized version of the touched view.
106
277
  def flick(uiquery, delta, options={})
107
278
  uiquery, options = extract_query_and_options(uiquery, options)
108
279
  options[:delta] = delta
@@ -113,10 +284,48 @@ module Calabash
113
284
  views_touched
114
285
  end
115
286
 
287
+ # Performs the "long press" or "touch and hold" gesture on the (first) view that matches
288
+ # query `uiquery`.
289
+ #
290
+ # @note This assumes the view is visible and not animating.
291
+ #
292
+ # If the view is not visible it will fail with an error. If the view is animating
293
+ # it will *silently* fail.
294
+ #
295
+ # By default, the gesture starts at the center of the view.
296
+ #
297
+ # @example
298
+ # touch_hold "webView css:'input'", duration:10, offset:{x: -40}
299
+ # @param {String} uiquery query describing view to touch.
300
+ # @param {Hash} options option for modifying the details of the touch.
301
+ # @option options {Hash} :offset (nil) optional offset to touch point. Offset supports an `:x` and `:y` key
302
+ # and causes the touch to be offset with `(x,y)` relative to the center (`center + (offset[:x], offset[:y])`).
303
+ # @option options {Numeric} :duration (3) duration of the 'hold'.
304
+ # @return {Array<Hash>} array containing the serialized version of the touched view.
116
305
  def touch_hold(uiquery, options={})
117
306
  query_action_with_options(:touch_hold, uiquery, options)
118
307
  end
119
308
 
309
+ # Performs a "swipe" gesture.
310
+ # By default, the gesture starts at the center of the screen.
311
+ #
312
+ # @todo `swipe` is an old style API which doesn't take a query as its
313
+ # first argument. We should migrate this.
314
+ #
315
+ # @note Due to a bug in Apple's UIAutomation, swipe is broken on certain
316
+ # views in the iOS Simulator. Swiping works on devices.
317
+ # {https://github.com/calabash/calabash-ios/issues/253}
318
+ #
319
+ # @example
320
+ # swipe :left
321
+ # @example
322
+ # swipe :down, offset:{x:10,y:50}, query:"MKMapView"
323
+ # @param {String} dir the direction to swipe (symbols can also be used).
324
+ # @param {Hash} options option for modifying the details of the touch.
325
+ # @option options {Hash} :offset (nil) optional offset to touch point. Offset supports an `:x` and `:y` key
326
+ # and causes the touch to be offset with `(x,y)` relative to the center (`center + (offset[:x], offset[:y])`).
327
+ # @option options {String} :query (nil) if specified, the swipe will be made relative to this query.
328
+ # @return {Array<Hash>,String} array containing the serialized version of the touched view if `options[:query]` is given.
120
329
  def swipe(dir, options={})
121
330
  unless uia_available?
122
331
  options = options.merge(:status_bar_orientation => status_bar_orientation)
@@ -124,14 +333,42 @@ module Calabash
124
333
  launcher.actions.swipe(dir.to_sym, options)
125
334
  end
126
335
 
336
+
337
+ # Performs the "pan" or "drag-n-drop" gesture on from the `from` parameter
338
+ # to the `to` parameter (both are queries).
339
+ # @example
340
+ # q1="* marked:'Cell 3' parent tableViewCell descendant tableViewCellReorderControl"
341
+ # q2="* marked:'Cell 6' parent tableViewCell descendant tableViewCellReorderControl"
342
+ # pan q1, q2, duration:4
343
+ # @param {String} from query describing view to start the gesture
344
+ # @param {String} to query describing view to end the gesture
345
+ # @option options {Hash} :offset (nil) optional offset to touch point. Offset supports an `:x` and `:y` key
346
+ # and causes the touch to be offset with `(x,y)` relative to the center (`center + (offset[:x], offset[:y])`).
347
+ # @option options {Numeric} :duration (1) duration of the 'pan'.
348
+ # @return {Array<Hash>} array containing the serialized version of the touched view.
127
349
  def pan(from, to, options={})
128
350
  launcher.actions.pan(from, to, options)
129
351
  end
130
352
 
353
+ # Performs a "pinch" gesture.
354
+ # By default, the gesture starts at the center of the screen.
355
+ # @todo `pinch` is an old style API which doesn't take a query as its first argument. We should migrate this.
356
+ # @example
357
+ # pinch :out
358
+ # @example
359
+ # pinch :in, query:"MKMapView", offset:{x:42}
360
+ # @param {String} in_out the direction to pinch ('in' or 'out') (symbols can also be used).
361
+ # @param {Hash} options option for modifying the details of the touch.
362
+ # @option options {Hash} :offset (nil) optional offset to touch point. Offset supports an `:x` and `:y` key
363
+ # and causes the touch to be offset with `(x,y)` relative to the center (`center + (offset[:x], offset[:y])`).
364
+ # @option options {String} :query (nil) if specified, the pinch will be made relative to this query.
365
+ # @return {Array<Hash>,String} array containing the serialized version of the touched view if `options[:query]` is given.
131
366
  def pinch(in_out, options={})
132
367
  launcher.actions.pinch(in_out.to_sym,options)
133
368
  end
134
369
 
370
+ # @!visibility private
371
+ # @deprecated
135
372
  def cell_swipe(options={})
136
373
  if uia_available?
137
374
  raise 'cell_swipe not supported with instruments, simply use swipe with a query that matches the cell'
@@ -139,6 +376,12 @@ module Calabash
139
376
  playback('cell_swipe', options)
140
377
  end
141
378
 
379
+ # Scroll a scroll view in a direction. By default scrolls half the frame size.
380
+ # @example
381
+ # scroll("UITableView", :down)
382
+ # @note this is implemented by calling the Obj-C `setContentOffset:animated:` method and can do things users cant.
383
+ #
384
+ # @param {String} uiquery query describing view scroll (should be UIScrollView or a web view).
142
385
  def scroll(uiquery, direction)
143
386
  views_touched=map(uiquery, :scroll, direction)
144
387
  msg = "could not find view to scroll: '#{uiquery}', args: #{direction}"
@@ -146,6 +389,14 @@ module Calabash
146
389
  views_touched
147
390
  end
148
391
 
392
+ # Scroll a table view to a row. Table view should have only one section.
393
+ # @see #scroll_to_cell
394
+ # @example
395
+ # scroll_to_row "UITableView", 2
396
+ # @note this is implemented by calling the Obj-C `scrollToRowAtIndexPath:atScrollPosition:animated:` method
397
+ # and can do things users cant.
398
+ #
399
+ # @param {String} uiquery query describing view scroll (should be UIScrollView or a web view).
149
400
  def scroll_to_row(uiquery, number)
150
401
  views_touched=map(uiquery, :scrollToRow, number)
151
402
  msg = "unable to scroll: '#{uiquery}' to: #{number}"
@@ -153,7 +404,22 @@ module Calabash
153
404
  views_touched
154
405
  end
155
406
 
156
- # todo for 1.0 version - scroll_to_cell should expose required arguments +section+ and +row+
407
+ # Scroll a table view to a section and row. Table view can have multiple sections.
408
+ #
409
+ # @todo should expose a non-option first argument query and required parameters `section`, `row`
410
+ #
411
+ # @see #scroll_to_row
412
+ # @example
413
+ # scroll_to_cell query:"UITableView", row:4, section:0, animate: false
414
+ # @note this is implemented by calling the Obj-C `scrollToRowAtIndexPath:atScrollPosition:animated:` method
415
+ # and can do things users cant.
416
+ #
417
+ # @param {Hash} options specifies details of the scroll
418
+ # @option options {String} :query ('tableView') query specifying which table view to scroll
419
+ # @option options {Fixnum} :section section to scroll to
420
+ # @option options {Fixnum} :row row to scroll to
421
+ # @option options {String} :scroll_position position to scroll to
422
+ # @option options {Boolean} :animated (true) animate or not
157
423
  def scroll_to_cell(options={:query => 'tableView',
158
424
  :row => 0,
159
425
  :section => 0,
@@ -181,34 +447,33 @@ module Calabash
181
447
  views_touched
182
448
  end
183
449
 
184
- # scrolls to +mark+ in a UITableView
185
- #
186
- # calls the +:scrollToRowWithMark+ server route
450
+ # Scrolls to a mark in a UITableView.
187
451
  #
188
- # scroll_to_row_with_mark(mark, {:scroll_position => :top}) #=> scroll to the top of the item with the given +mark+
189
- # scroll_to_row_with_mark(mark, {:scroll_position => :bottom}) #=> scroll to the bottom of the item with the given +mark+
452
+ # @example Scroll to the top of the item with the given mark.
453
+ # scroll_to_row_with_mark('settings', {:scroll_position => :top})
190
454
  #
191
- # allowed options
192
- # :query => a query string
193
- # default => 'tableView'
194
- # example => "tableView marked:'hit songs'"
455
+ # @example Scroll to the bottom of the item with the given mark.
456
+ # scroll_to_row_with_mark('about', {:scroll_position => :bottom})
195
457
  #
196
- # :scroll_position => the position to scroll to
197
- # default => :middle
198
- # allowed => {:top | :middle | :bottom}
458
+ # @param [String] mark an accessibility `{label | identifier}` or text in
459
+ # or on the row
460
+ # @param [Hash] options controls the query and and scroll behavior
199
461
  #
200
- # :animate => animate the scrolling
201
- # default => true
202
- # allowed => {true | false}
462
+ # @option options [String] :query ('tableView')
463
+ # the query that should be used to location the table
464
+ # @option options [Symbol] :scroll_position (:middle)
465
+ # the table position to scroll the row to - allowed values
466
+ # `{:middle | :top | :bottom}`
467
+ # @option options [Boolean] :animate (true)
468
+ # should the scrolling be animated
203
469
  #
204
- # raises an exception if the scroll cannot be performed.
205
- # * the +mark+ is nil
206
- # * the +:query+ finds no table view
207
- # * table view does not contain a cell with the given +mark+
208
- # * +:scroll_position+ is invalid
470
+ # @raise [RuntimeError] if the scroll cannot be performed
471
+ # @raise [RuntimeError] if the mark is nil
472
+ # @raise [RuntimeError] if the table query finds no table view
473
+ # @raise [RuntimeError] if the scroll position is invalid
209
474
  def scroll_to_row_with_mark(mark, options={:query => 'tableView',
210
- :scroll_position => :middle,
211
- :animate => true})
475
+ :scroll_position => :middle,
476
+ :animate => true})
212
477
  if mark.nil?
213
478
  screenshot_and_raise 'mark argument cannot be nil'
214
479
  end
@@ -231,36 +496,41 @@ module Calabash
231
496
  views_touched
232
497
  end
233
498
 
234
- # scrolls to +item+ in +section+ in a UICollectionView
499
+ # Scrolls to an item in a section of a UICollectionView.
500
+ #
501
+ # @note item and section are zero-indexed
235
502
  #
236
- # calls the +:collectionViewScroll+ server route
503
+ # @example Scroll to item 0 in section 2 to top.
504
+ # scroll_to_collection_view_item(0, 2, {:scroll_position => :top})
237
505
  #
238
- # +item+ and +section+ are zero-indexed
506
+ # @example Scroll to item 5 in section 0 to bottom.
507
+ # scroll_to_collection_view_item(5, 0, {:scroll_position => :bottom})
239
508
  #
240
- # scroll_to_collection_view_item(0, 2, {:scroll_position => :top}) #=> scroll to item 0 in section 2 to top
241
- # scroll_to_collection_view_item(5, 0, {:scroll_position => :bottom}) #=> scroll to item 5 in section 0 to bottom
509
+ # @example The following are the allowed :scroll_position values.
510
+ # {:top | :center_vertical | :bottom | :left | :center_horizontal | :right}
242
511
  #
243
- # allowed options
244
- # :query => a query string
245
- # default => 'collectionView'
246
- # example => "collectionView marked:'hit songs'"
512
+ # @param [Integer] item the index of the item to scroll to
513
+ # @param [Integer] section the section of the item to scroll to
514
+ # @param [Hash] opts options for controlling the collection view query
515
+ # and scroll behavior
247
516
  #
248
- # :scroll_position => the position to scroll to
249
- # default => :top
250
- # allowed => {:top | :center_vertical | :bottom | :left | :center_horizontal | :right}
517
+ # @option opts [String] :query ('collectionView')
518
+ # the query that is used to identify which collection view to scroll
251
519
  #
252
- # :animate => animate the scrolling
253
- # default => true
254
- # allowed => {true | false}
520
+ # @option opts [Symbol] :scroll_position (top)
521
+ # the position in the collection view to scroll the item to
255
522
  #
256
- # :failed_message => the message to display on failure
257
- # default => nil - will display a default failure message
258
- # allowed => any string
523
+ # @option opts [Boolean] :animate (true)
524
+ # should the scrolling be animated
259
525
  #
260
- # raises an exception if the scroll cannot be performed.
261
- # * the +:query+ finds no collection view
262
- # * collection view does not contain a cell at +item+/+section+
263
- # * +:scroll_position+ is invalid
526
+ # @option opts [String] :failed_message (nil)
527
+ # a custom error message to display if the scrolling fails - if not
528
+ # specified, a generic failure will be displayed
529
+ #
530
+ # @raise [RuntimeException] if the scroll cannot be performed
531
+ # @raise [RuntimeException] :query finds no collection view
532
+ # @raise [RuntimeException] the collection view does not contain a cell at item/section
533
+ # @raise [RuntimeException] :scroll_position is invalid
264
534
  def scroll_to_collection_view_item(item, section, opts={})
265
535
  default_options = {:query => 'collectionView',
266
536
  :scroll_position => :top,
@@ -289,35 +559,38 @@ module Calabash
289
559
  views_touched
290
560
  end
291
561
 
292
- # scrolls to +mark+ in a UICollectionView
293
- #
294
- # calls the +:collectionViewScrollToItemWithMark+ server route
562
+ # Scrolls to mark in a UICollectionView.
295
563
  #
296
- # scroll_to_collection_view_item_with_mark(mark, {:scroll_position => :top}) #=> scroll to the top of the item with the given +mark+
297
- # scroll_to_collection_view_item_with_mark(mark, {:scroll_position => :bottom}) #=> scroll to the bottom of the item with the given +mark+
564
+ # @example Scroll to the top of the item with the given mark.
565
+ # scroll_to_collection_view_item_with_mark('cat', {:scroll_position => :top})
298
566
  #
299
- # allowed options
300
- # :query => a query string
301
- # default => 'collectionView'
302
- # example => "collectionView marked:'hit songs'"
567
+ # @example Scroll to the bottom of the item with the given mark.
568
+ # scroll_to_collection_view_item_with_mark('dog', {:scroll_position => :bottom})
303
569
  #
304
- # :scroll_position => the position to scroll to
305
- # default => :top
306
- # allowed => {:top | :center_vertical | :bottom | :left | :center_horizontal | :right}
570
+ # @example The following are the allowed :scroll_position values.
571
+ # {:top | :center_vertical | :bottom | :left | :center_horizontal | :right}
307
572
  #
308
- # :animate => animate the scrolling
309
- # default => true
310
- # allowed => {true | false}
573
+ # @param [String] mark an accessibility `{label | identifier}` or text in
574
+ # or on the item
575
+ # @param [Hash] opts options for controlling the collection view query
576
+ # and scroll behavior
311
577
  #
312
- # :failed_message => the message to display on failure
313
- # default => nil - will display a default failure message
314
- # allowed => any string
578
+ # @option opts [String] :query ('collectionView')
579
+ # the query that is used to identify which collection view to scroll
580
+ # @option opts [Symbol] :scroll_position (:top)
581
+ # the position in the collection view to scroll the item to
582
+ # @option opts [Boolean] :animate (true) should the scroll
583
+ # be animated
584
+ # @option opts [String] :failed_message (nil)
585
+ # a custom error message to display if the scrolling fails - if not
586
+ # specified, a generic failure will be displayed
315
587
  #
316
- # raises an exception if the scroll cannot be performed.
317
- # * the +mark+ is nil
318
- # * the +:query+ finds no collection view
319
- # * collection view does not contain a cell with the given +mark+
320
- # * +:scroll_position+ is invalid
588
+ # @raise [RuntimeException] if the scroll cannot be performed
589
+ # @raise [RuntimeException] if the mark is nil
590
+ # @raise [RuntimeException] :query finds no collection view
591
+ # @raise [RuntimeException] the collection view does not contain a cell
592
+ # with the mark
593
+ # @raise [RuntimeException] :scroll_position is invalid
321
594
  def scroll_to_collection_view_item_with_mark(mark, opts={})
322
595
  default_options = {:query => 'collectionView',
323
596
  :scroll_position => :top,
@@ -346,10 +619,21 @@ module Calabash
346
619
  views_touched
347
620
  end
348
621
 
622
+ # Sends app to background. Simulates pressing the home button.
623
+ # @param {Fixnum} secs number of seconds to be in the background
624
+ # `should not be more than 60 secs`
349
625
  def send_app_to_background(secs)
350
626
  launcher.actions.send_app_to_background(secs)
351
627
  end
352
628
 
629
+ # Simulates gps location of the device/simulator.
630
+ # @note Seems UIAutomation is broken here on physical devices on iOS 7.1
631
+ # @example
632
+ # set_location place:'Tower of London'
633
+ # @param {Hash} options specifies which location to simulate
634
+ # @option options {String} :place a description of a place (resolved via Google maps api), e.g. "Tower of London"
635
+ # @option options {Numeric} :latitude latitude of a gps coordinate (same coordinate system as Google maps)
636
+ # @option options {Numeric} :longitude longitude of a gps coordinate (same coordinate system as Google maps)
353
637
  def set_location(options)
354
638
  if uia_available?
355
639
  uia_set_location(options)
@@ -377,16 +661,21 @@ module Calabash
377
661
  end
378
662
  end
379
663
 
664
+ # Returns a geo-location search result (via Google). Requires internet.
665
+ # @param {String} place a description of the place to search for
666
+ # @return {Geocoder::Result::Google} result of the search - see {http://www.rubygeocoder.com/}.
380
667
  def location_for_place(place)
381
668
  search_results = locations_for_place(place)
382
669
  raise "Got no results for #{place}" if search_results.empty?
383
670
  search_results.first
384
671
  end
385
672
 
673
+ # @!visibility private
386
674
  def locations_for_place(place)
387
675
  Geocoder.search(place)
388
676
  end
389
677
 
678
+ # @!visibility private
390
679
  def move_wheel(opts={})
391
680
  q = opts[:query] || 'pickerView'
392
681
  wheel = opts[:wheel] || 0
@@ -405,6 +694,7 @@ module Calabash
405
694
 
406
695
  end
407
696
 
697
+ # @!visibility private
408
698
  def picker(opts={:query => 'pickerView', :action => :texts})
409
699
  raise 'Not implemented' unless opts[:action] == :texts
410
700
 
@@ -438,6 +728,26 @@ module Calabash
438
728
  texts
439
729
  end
440
730
 
731
+ # Calls a method on the app's AppDelegate object.
732
+ #
733
+ # This is an escape hatch for calling an arbitrary hook inside
734
+ # (the test build) of your app. Commonly used to "go around" the UI for
735
+ # speed purposes or reset the app to a good known state.
736
+ #
737
+ # You must create a method on you app delegate of the form:
738
+ #
739
+ # - (NSString *) calabashBackdoor:(NSString *)aIgnorable;
740
+ #
741
+ # or if you want to pass parameters
742
+ #
743
+ # - (NSString *) calabashBackdoor:(NSDictionary *)params;
744
+ # @example
745
+ # backdoor("calabashBackdoor:", '')
746
+ # @example
747
+ # backdoor("calabashBackdoor:", {example:'param'})
748
+ # @param {String} sel the selector to perform on the app delegate
749
+ # @param {Object} arg the argument to pass to the selector
750
+ # @return {Object} the result of performing the selector with the argument (serialized)
441
751
  def backdoor(sel, arg)
442
752
  json = {
443
753
  :selector => sel,
@@ -451,6 +761,7 @@ module Calabash
451
761
  res['result']
452
762
  end
453
763
 
764
+ # Kills the app.
454
765
  def calabash_exit
455
766
  # Exiting the app shuts down the HTTP connection and generates ECONNREFUSED,
456
767
  # or HTTPClient::KeepAliveDisconnected
@@ -462,14 +773,19 @@ module Calabash
462
773
  end
463
774
  end
464
775
 
465
- def server_debug_level
776
+ # Get the Calabash server log level.
777
+ # @return {String} the current log level
778
+ def server_log_level
466
779
  _debug_level_response(http(:method => :get, :path => 'debug'))
467
780
  end
468
781
 
469
- def set_server_debug_level(level)
782
+ # Set the Calabash server log level.
783
+ # @param {String} level the log level to set (debug, info, warn, error)
784
+ def set_server_log_level(level)
470
785
  _debug_level_response(http({:method => :post, :path => 'debug'}, {:level => level}))
471
786
  end
472
787
 
788
+ # @!visibility private
473
789
  def _debug_level_response(json)
474
790
  res = JSON.parse(json)
475
791
  if res['outcome'] != 'SUCCESS'
@@ -477,8 +793,12 @@ module Calabash
477
793
  end
478
794
  res['results'].first
479
795
  end
480
- ## args :app for device bundle id, for sim path to app
481
- ##
796
+
797
+ # Starts the app and Calabash test server in the console.
798
+ # @note It is not recommended to call this method outside of the
799
+ # calabash console. Call `Calabash::Cucumber::Launcher#relaunch instead.
800
+ # @see Calabash::Cucumber::Launcher#relaunch
801
+ # @return {Calabash::Cucumber::Launcher} the launcher object in use
482
802
  def start_test_server_in_background(args={})
483
803
  stop_test_server
484
804
  @calabash_launcher = Calabash::Cucumber::Launcher.new()
@@ -486,26 +806,251 @@ module Calabash
486
806
  @calabash_launcher
487
807
  end
488
808
 
809
+ # Helper method to easily create page object instances from a cucumber execution context.
810
+ # The advantage of using `page` to instantiate a page object class is that it
811
+ # will automatically store a reference to the current Cucumber world
812
+ # which is needed in the page object methods to call Cucumber-specific methods
813
+ # like puts or embed.
814
+ # @example Instantiating a `LoginPage` from a step definition
815
+ # Given(/^I am about to login to a self-hosted site$/) do
816
+ # @current_page = page(LoginPage).await(timeout: 30)
817
+ # @current_page.self_hosted_site
818
+ # end
819
+ #
820
+ # @see Calabash::IBase
821
+ # @param {Class} clz the page object class to instantiate (passing the cucumber world and `args`)
822
+ # @param {Array} args optional additional arguments to pass to the page object constructor
823
+ # @return {Object} a fresh instance of `Class clz` which has been passed a reference to the cucumber World object.
824
+ def page(clz,*args)
825
+ clz.new(self,*args)
826
+ end
827
+
828
+ # Instantiates a page using `page` and calls the page's `await` method.
829
+ # @see #page
830
+ # @see Calabash::IBase#await
831
+ # @example Instantiating and waiting a `LoginPage` from a step definition
832
+ # Given(/^I am about to login to a self-hosted site$/) do
833
+ # @current_page = await_page(LoginPage)
834
+ # @current_page.self_hosted_site
835
+ # end
836
+ #
837
+ # @see Calabash::IBase
838
+ # @param {Class} clz the page object class to instantiate (passing the cucumber world and `args`)
839
+ # @param {Array} args optional additional arguments to pass to the page object constructor
840
+ # @return {Object} a fresh instance of `Class clz` which has been passed a reference to the cucumber World object.
841
+ # Calls await on the page object.
842
+ def await_page(clz,*args)
843
+ clz.new(self,*args).await
844
+ end
845
+
846
+ # @!visibility private
847
+ def home_direction
848
+ status_bar_orientation.to_sym
849
+ end
850
+
851
+ # Returns all accessibilityLabels of objects matching `uiquery`.
852
+ # @param {String} uiquery query to match
853
+ # @return {Array<String>} Returns all accessibilityLabels of objects matching `uiquery`.
854
+ def label(uiquery)
855
+ query(uiquery, :accessibilityLabel)
856
+ end
857
+
858
+ # Returns all accessibilityIdentifiers of objects matching `uiquery`.
859
+ # @param {String} uiquery query to match
860
+ # @return {Array<String>} Returns all accessibilityIdentifiers of objects matching `uiquery`.
861
+ def identifier(uiquery)
862
+ query(uiquery, :accessibilityIdentifier)
863
+ end
864
+
865
+ # @!visibility private
866
+ # @deprecated use `tap_mark`
867
+ def simple_touch(label, *args)
868
+ tap_mark(label, *args)
869
+ end
870
+
871
+ # taps a view with mark `hash_or_string`
872
+ # @deprecated In later Calabash versions we will change the semantics of `tap` to take a general query
873
+ # (instead of a 'mark' now). We're deprecating this now to prepare people for a breaking change.
874
+ # @param {String} hash_or_string mark to pass to call `tap_mark(hash_or_string)`.
875
+ # @return {Array<Hash>} array containing the serialized version of the tapped view.
876
+ def tap(hash_or_string, *args)
877
+ deprecation_msg = 'Use tap_mark instead. In later Calabash versions we will change the semantics of `tap` to take a general query.'
878
+ _deprecated('0.10.0', deprecation_msg, :warn)
879
+ if hash_or_string.is_a?(String)
880
+ tap_mark(hash_or_string, *args)
881
+ elsif hash_or_string.respond_to?(:[])
882
+ wait_tap(hash_or_string[:query], hash_or_string)
883
+ else
884
+ raise(ArgumentError, "first parameter to tap must be a string or a hash. Was: #{hash_or_string.class}, #{hash_or_string}")
885
+ end
886
+ end
887
+
888
+ # taps a view with mark `label`. Equivalent to `touch("* marked:'#{label}'")`
889
+ # @param {String} label the mark of the view to tap
890
+ # @param {Array} args optional additional arguments to pass to `touch`.
891
+ # @return {Array<Hash>} array containing the serialized version of the tapped view.
892
+ def tap_mark(label, *args)
893
+ touch("view marked:'#{label}'", *args)
894
+ end
895
+
896
+ # returns the 'html' property of all objects matching the query `q`
897
+ # @param {String} q the query to execute (should be a webView query)
898
+ # @return {Array<String>} array containing html of all elements matching the query
899
+ def html(q)
900
+ query(q).map { |e| e['html'] }
901
+ end
902
+
903
+ # sets the text value of the views matched by +uiquery+ to +txt+
904
+ #
905
+ # @deprecated since 0.9.145
906
+ #
907
+ # we have stopped testing this method. you have been warned.
908
+ #
909
+ # * to enter text using the native keyboard use 'keyboard_enter_text'
910
+ # * to delete text use 'keyboard_enter_text('Delete')"
911
+ # * to clear a text field or text view:
912
+ # - RECOMMENDED: use queries and touches to replicate what the user would do
913
+ # - for text fields, implement a clear text button and touch it
914
+ # - for text views, use touches to reveal text editing popup
915
+ # see https://github.com/calabash/calabash-ios/issues/151
916
+ # - use 'clear_text'
917
+ # https://github.com/calabash/calabash-ios/wiki/03.5-Calabash-iOS-Ruby-API
918
+ #
919
+ # raises an error if the +uiquery+ finds no matching queries or finds
920
+ # a view that does not respond to the objc selector 'setText'
921
+ def set_text(uiquery, txt)
922
+ msgs = ["'set_text' is deprecated and its behavior is now unpredictable",
923
+ "* to enter text using the native keyboard use 'keyboard_enter_text'",
924
+ "* to delete text use 'keyboard_enter_text('Delete')",
925
+ '* to clear a text field or text view:',
926
+ ' - RECOMMENDED: use queries and touches to replicate what the user would do',
927
+ ' * for text fields, implement a clear text button and touch it',
928
+ ' * for text views, use touches to reveal text editing popup',
929
+ ' see https://github.com/calabash/calabash-ios/issues/151',
930
+ " - use 'clear_text'",
931
+ 'https://github.com/calabash/calabash-ios/wiki/03.5-Calabash-iOS-Ruby-API']
932
+ msg = msgs.join("\n")
933
+ _deprecated('0.9.145', msg, :warn)
934
+
935
+ text_fields_modified = map(uiquery, :setText, txt)
936
+
937
+ msg = "query '#{uiquery}' returned no matching views that respond to 'setText'"
938
+ assert_map_results(text_fields_modified, msg)
939
+ text_fields_modified
940
+ end
941
+
942
+ # sets the text value of the views matched by +uiquery+ to <tt>''</tt>
943
+ # (the empty string)
944
+ #
945
+ # using this sparingly and with caution
946
+ #
947
+ #
948
+ # it is recommended that you instead do some combination of the following
949
+ #
950
+ # * use queries and touches to replicate with the user would
951
+ # - for text fields, implement a clear text button and touch it
952
+ # - for text views, use touches to reveal text editing popup
953
+ # see https://github.com/calabash/calabash-ios/issues/151
954
+ #
955
+ # https://github.com/calabash/calabash-ios/wiki/03.5-Calabash-iOS-Ruby-API
956
+ #
957
+ # raises an error if the +uiquery+ finds no matching queries or finds
958
+ # a _single_ view that does not respond to the objc selector 'setText'
959
+ #
960
+ # IMPORTANT
961
+ # calling:
962
+ #
963
+ # > clear_text("view")
964
+ #
965
+ # will clear the text on _all_ visible views that respond to 'setText'
966
+ def clear_text(uiquery)
967
+ views_modified = map(uiquery, :setText, '')
968
+ msg = "query '#{uiquery}' returned no matching views that respond to 'setText'"
969
+ assert_map_results(views_modified, msg)
970
+ views_modified
971
+ end
972
+
973
+
974
+ # Sets user preference (NSUserDefaults) value of key `key` to `val`.
975
+ # @example
976
+ # set_user_pref 'foo', {lastname: "Krukow"}
977
+ # # returns
978
+ # [
979
+ # {
980
+ # "lastname" => "Krukow"
981
+ # },
982
+ # {
983
+ # "firstname" => "Karl"
984
+ # }
985
+ # ]
986
+ #
987
+ # @param {String} key the set to set
988
+ # @param {Object} val the (JSON_ serializable) value to set
989
+ # @return {Object} the current user preferences
990
+ def set_user_pref(key, val)
991
+ res = http({:method => :post, :path => 'userprefs'},
992
+ {:key=> key, :value => val})
993
+ res = JSON.parse(res)
994
+ if res['outcome'] != 'SUCCESS'
995
+ screenshot_and_raise "set_user_pref #{key} = #{val} failed because: #{res['reason']}\n#{res['details']}"
996
+ end
997
+
998
+ res['results']
999
+ end
1000
+
1001
+ # Gets the user preference (NSUserDefaults) value for a key.
1002
+ # @param {String} key the read
1003
+ # @return {Object} the current user preferences value for `key`
1004
+ def user_pref(key)
1005
+ res = http({:method => :get, :raw => true, :path => 'userprefs'},
1006
+ {:key=> key})
1007
+ res = JSON.parse(res)
1008
+ if res['outcome'] != 'SUCCESS'
1009
+ screenshot_and_raise "get user_pref #{key} failed because: #{res['reason']}\n#{res['details']}"
1010
+ end
1011
+
1012
+ res['results'].first
1013
+ end
1014
+
1015
+ # @!visibility private
1016
+ # @todo broken currently
489
1017
  def stop_test_server
490
1018
  l = @calabash_launcher || Calabash::Cucumber::Launcher.launcher_if_used
491
1019
  l.stop if l
492
1020
  end
493
1021
 
1022
+ # @!visibility private
1023
+ # @todo broken currently
494
1024
  def shutdown_test_server
495
1025
  # Compat with Calabash Android
496
1026
  stop_test_server
497
1027
  end
498
1028
 
1029
+ # Attach the current calabash launcher to a console.
1030
+ # @example
1031
+ # You have encountered a failing cucumber Scenario.
1032
+ # You open the console and want to start investigating the cause of the failure.
1033
+ #
1034
+ # Use
1035
+ #
1036
+ # > console_attach
1037
+ #
1038
+ # to connect to the current launcher
1039
+ #
1040
+ # @return [Calabash::Cucumber::Launcher,nil] the currently active
1041
+ # calabash launcher
499
1042
  def console_attach
500
1043
  # setting the @calabash_launcher here for backward compatibility
501
1044
  @calabash_launcher = launcher.attach
502
1045
  end
503
1046
 
1047
+ # @!visibility private
504
1048
  def launcher
505
1049
  # setting the @calabash_launcher here for backward compatibility
506
1050
  @calabash_launcher = Calabash::Cucumber::Launcher.launcher
507
1051
  end
508
1052
 
1053
+ # @!visibility private
509
1054
  def query_action_with_options(action, uiquery, options)
510
1055
  uiquery, options = extract_query_and_options(uiquery, options)
511
1056
  views_touched = launcher.actions.send(action, options)
@@ -516,11 +1061,20 @@ module Calabash
516
1061
  views_touched
517
1062
  end
518
1063
 
1064
+ # @!visibility private
519
1065
  def extract_query_and_options(uiquery, options)
520
1066
  options = prepare_query_options(uiquery, options)
521
1067
  return options[:query], options
522
1068
  end
523
1069
 
1070
+ # @!visibility private
1071
+ def assert_home_direction(expected)
1072
+ unless expected.to_sym == home_direction
1073
+ screenshot_and_raise "Expected home button to have direction #{expected} but had #{home_direction}"
1074
+ end
1075
+ end
1076
+
1077
+ # @!visibility private
524
1078
  def prepare_query_options(uiquery, options)
525
1079
  opts = options.dup
526
1080
  if uiquery.is_a?(Array)