calabash 1.9.9.pre2 → 1.9.9.pre3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +19 -0
  3. data/lib/calabash.rb +4 -2
  4. data/lib/calabash/android/build/java_keystore.rb +1 -0
  5. data/lib/calabash/android/console_helpers.rb +1 -0
  6. data/lib/calabash/android/defaults.rb +23 -13
  7. data/lib/calabash/android/device.rb +84 -19
  8. data/lib/calabash/android/environment.rb +2 -0
  9. data/lib/calabash/android/gestures.rb +4 -3
  10. data/lib/calabash/android/interactions.rb +1 -0
  11. data/lib/calabash/android/lib/.irbrc +61 -48
  12. data/lib/calabash/android/lib/TestServer.apk +0 -0
  13. data/lib/calabash/android/life_cycle.rb +3 -2
  14. data/lib/calabash/android/orientation.rb +1 -0
  15. data/lib/calabash/android/physical_buttons.rb +3 -1
  16. data/lib/calabash/android/screenshot.rb +0 -1
  17. data/lib/calabash/android/text.rb +1 -0
  18. data/lib/calabash/application.rb +20 -1
  19. data/lib/calabash/cli/generate.rb +10 -2
  20. data/lib/calabash/console_helpers.rb +101 -13
  21. data/lib/calabash/defaults.rb +36 -3
  22. data/lib/calabash/device.rb +28 -3
  23. data/lib/calabash/gestures.rb +12 -12
  24. data/lib/calabash/http/request.rb +1 -0
  25. data/lib/calabash/http/retriable_client.rb +1 -0
  26. data/lib/calabash/interactions.rb +2 -1
  27. data/lib/calabash/ios.rb +2 -0
  28. data/lib/calabash/ios/conditions.rb +1 -0
  29. data/lib/calabash/ios/console_helpers.rb +1 -0
  30. data/lib/calabash/ios/defaults.rb +32 -17
  31. data/lib/calabash/ios/device/device_implementation.rb +5 -1
  32. data/lib/calabash/ios/device/gestures_mixin.rb +27 -7
  33. data/lib/calabash/ios/device/rotation_mixin.rb +2 -2
  34. data/lib/calabash/ios/device/routes/error.rb +1 -0
  35. data/lib/calabash/ios/device/routes/playback_route_mixin.rb +1 -1
  36. data/lib/calabash/ios/device/routes/uia_route_mixin.rb +1 -1
  37. data/lib/calabash/ios/device/uia_mixin.rb +1 -1
  38. data/lib/calabash/ios/gestures.rb +107 -0
  39. data/lib/calabash/ios/interactions.rb +1 -0
  40. data/lib/calabash/ios/lib/.irbrc +61 -47
  41. data/lib/calabash/ios/orientation.rb +1 -0
  42. data/lib/calabash/ios/runtime.rb +1 -0
  43. data/lib/calabash/ios/scroll.rb +7 -7
  44. data/lib/calabash/ios/text.rb +3 -0
  45. data/lib/calabash/ios/uia.rb +1 -0
  46. data/lib/calabash/lib/skeleton/.gitignore +19 -0
  47. data/lib/calabash/lib/skeleton/Gemfile +5 -0
  48. data/lib/calabash/life_cycle.rb +3 -2
  49. data/lib/calabash/location.rb +5 -6
  50. data/lib/calabash/logger.rb +1 -0
  51. data/lib/calabash/orientation.rb +1 -0
  52. data/lib/calabash/page.rb +1 -0
  53. data/lib/calabash/screenshot.rb +1 -0
  54. data/lib/calabash/server.rb +1 -0
  55. data/lib/calabash/text.rb +3 -2
  56. data/lib/calabash/utility.rb +2 -1
  57. data/lib/calabash/version.rb +1 -1
  58. data/lib/calabash/wait.rb +1 -0
  59. metadata +114 -114
  60. data/lib/calabash/android/cucumber.rb +0 -3
  61. data/lib/calabash/android/scroll.rb +0 -5
  62. data/lib/calabash/patch/run_loop.rb +0 -90
@@ -113,9 +113,9 @@ module Calabash
113
113
  # @see Calabash::IOS::Scroll#scroll_to_item_with_mark
114
114
  #
115
115
  # @param [String] query A query describing the view to pan inside.
116
- # @param [Hash] from ({:x, :y}) The point at which the gesture
116
+ # @param [Hash] from `({:x, :y})` The point at which the gesture
117
117
  # originates from.
118
- # @param [Hash] to ({:x, :y}) The point at which the gesture
118
+ # @param [Hash] to `({:x, :y})` The point at which the gesture
119
119
  # ends.
120
120
  #
121
121
  # @param [Hash] options Options for modifying the details of the pan.
@@ -239,13 +239,13 @@ module Calabash
239
239
  #
240
240
  # @param [String,Hash,Query] query A query describing the view to flick
241
241
  # inside of.
242
- # @param [Hash] from ({:x, :y}) The point at which the gesture
242
+ # @param [Hash] from `({:x, :y})` The point at which the gesture
243
243
  # originates from.
244
- # @param [Hash] to ({:x, :y}) The point at which the gesture
244
+ # @param [Hash] to `({:x, :y})` The point at which the gesture
245
245
  # ends.
246
246
  #
247
247
  # @param [Hash] options Options for controlling the flick.
248
- # @options options [Numeric] :duration The duration of the flick. On iOS,
248
+ # @option options [Numeric] :duration The duration of the flick. On iOS,
249
249
  # the duration must be between 0.5 and 60.
250
250
  #
251
251
  # @raise [ViewNotFoundError] If the `query` returns no results.
@@ -346,37 +346,37 @@ module Calabash
346
346
  _pinch_screen_to_zoom(:out, options)
347
347
  end
348
348
 
349
- # !@visibility private
349
+ # @!visibility private
350
350
  def _pan_screen_up(options={})
351
351
  abstract_method!
352
352
  end
353
353
 
354
- # !@visibility private
354
+ # @!visibility private
355
355
  def _pan_screen_down(options={})
356
356
  abstract_method!
357
357
  end
358
358
 
359
- # !@visibility private
359
+ # @!visibility private
360
360
  def _flick_screen_up(options={})
361
361
  abstract_method!
362
362
  end
363
363
 
364
- # !@visibility private
364
+ # @!visibility private
365
365
  def _flick_screen_down(options={})
366
366
  abstract_method!
367
367
  end
368
368
 
369
- # !@visibility private
369
+ # @!visibility private
370
370
  def _pinch_screen(direction, options={})
371
371
  abstract_method!
372
372
  end
373
373
 
374
- # !@visibility private
374
+ # @!visibility private
375
375
  def _pinch_to_zoom(direction, query, options={})
376
376
  abstract_method!
377
377
  end
378
378
 
379
- # !@visibility private
379
+ # @!visibility private
380
380
  def _pinch_screen_to_zoom(direction, options={})
381
381
  abstract_method!
382
382
  end
@@ -3,6 +3,7 @@ module Calabash
3
3
 
4
4
  # A representation of an HTTP request that can be passed passed to the HTTP
5
5
  # client as an argument for `get` or `post`.
6
+ # @!visibility private
6
7
  class Request
7
8
  attr_reader :route, :params
8
9
 
@@ -4,6 +4,7 @@ module Calabash
4
4
  module HTTP
5
5
 
6
6
  # An HTTP client that retries its connection on errors and can time out.
7
+ # @!visibility private
7
8
  class RetriableClient
8
9
  attr_reader :client
9
10
 
@@ -1,4 +1,5 @@
1
1
  module Calabash
2
+ # @!visibility private
2
3
  module Interactions
3
4
  # @todo Needs docs!
4
5
  def query(query, *args)
@@ -89,7 +90,7 @@ module Calabash
89
90
  # backdoor('calabashBackdoor', 'first argument', 2)
90
91
  #
91
92
  # @param [String] name The selector/method name.
92
- # @param [Object] *arguments A comma separated list of arguments to be
93
+ # @param [Object] arguments A comma separated list of arguments to be
93
94
  # passed to the backdoor selector/method.
94
95
  # @return [Object] the result of performing the selector/method with the
95
96
  # arguments (serialized)
data/lib/calabash/ios.rb CHANGED
@@ -29,6 +29,7 @@ module Calabash
29
29
  require 'calabash/ios/uia'
30
30
  require 'calabash/ios/scroll'
31
31
  require 'calabash/ios/runtime'
32
+ require 'calabash/ios/gestures'
32
33
 
33
34
  include Calabash::IOS::Conditions
34
35
  include Calabash::IOS::Orientation
@@ -37,6 +38,7 @@ module Calabash
37
38
  include Calabash::IOS::UIA
38
39
  include Calabash::IOS::Scroll
39
40
  include Calabash::IOS::Runtime
41
+ include Calabash::IOS::Gestures
40
42
 
41
43
  end
42
44
  end
@@ -1,5 +1,6 @@
1
1
  module Calabash
2
2
  module IOS
3
+ # @!visibility private
3
4
  module Conditions
4
5
 
5
6
  # Waits for all elements to stop animating.
@@ -1,4 +1,5 @@
1
1
  module Calabash
2
+ # @!visibility private
2
3
  module ConsoleHelpers
3
4
  def self.render(data, indentation)
4
5
  if visible?(data)
@@ -1,27 +1,42 @@
1
1
  module Calabash
2
2
  module IOS
3
- def self.setup_defaults!
4
- setup_default_application!
5
- setup_default_device!
6
- end
7
-
8
- def self.setup_default_device!
9
- if Calabash.default_application.nil?
10
- raise 'Cannot setup default device for iOS, as no default Application has been set'
3
+ module Defaults
4
+ # Sets up the default application based on the
5
+ # environment, and the default device based on the default application
6
+ # and the environment.
7
+ #
8
+ # @see Calabash::IOS::Defaults#setup_default_application!
9
+ # @see Calabash::IOS::Defaults#setup_default_device!
10
+ # @see Calabash::Environment
11
+ def setup_defaults!
12
+ setup_default_application!
13
+ setup_default_device!
11
14
  end
12
15
 
13
- # Setup the default device
14
- identifier =
15
- Device.default_identifier_for_application(Calabash.default_application)
16
+ # Sets up the default device based on the default application and the
17
+ # environment.
18
+ #
19
+ # @raise [RuntimeError] Raises an error if the default application has
20
+ # not been set.
21
+ def setup_default_device!
22
+ if Calabash.default_application.nil?
23
+ raise 'Cannot setup default device for iOS, as no default Application has been set'
24
+ end
16
25
 
17
- server = Server.default
26
+ # Setup the default device
27
+ identifier =
28
+ Device.default_identifier_for_application(Calabash.default_application)
18
29
 
19
- Calabash.default_device = Device.new(identifier, server)
20
- end
30
+ server = Server.default
21
31
 
22
- def self.setup_default_application!
23
- # Setup the default application
24
- Calabash.default_application = Application.default_from_environment
32
+ Calabash.default_device = Device.new(identifier, server)
33
+ end
34
+
35
+ # Sets up the default application based on the environment.
36
+ def setup_default_application!
37
+ # Setup the default application
38
+ Calabash.default_application = Application.default_from_environment
39
+ end
25
40
  end
26
41
  end
27
42
  end
@@ -2,6 +2,7 @@ module Calabash
2
2
  module IOS
3
3
 
4
4
  # An iOS Device is an iOS Simulator or physical device.
5
+ # @!visibility private
5
6
  class Device < ::Calabash::Device
6
7
 
7
8
  include Calabash::IOS::PhysicalDeviceMixin
@@ -467,7 +468,10 @@ module Calabash
467
468
  if installed_app.same_sha1_as?(application)
468
469
  true
469
470
  else
470
- @logger.log("The sha1 checksum has changed (#{installed_app.sha1} != #{application.sha1}.", :info)
471
+ @logger.log("The installed app and the target app are different.", :info)
472
+ @logger.log(" The target app has SHA: #{application.sha1}", :info)
473
+ @logger.log("The installed app has SHA: #{installed_app.sha1}", :info)
474
+ @logger.log("Installing the target app.", :info)
471
475
  install_app_on_simulator(application, @run_loop_device, bridge)
472
476
  end
473
477
  else
@@ -88,22 +88,25 @@ module Calabash
88
88
  begin
89
89
  _expect_valid_duration(options)
90
90
  rescue ArgumentError => e
91
- raise ArgumentError e
91
+ raise ArgumentError, e
92
92
  end
93
93
 
94
94
  gesture_waiter = _gesture_waiter
95
95
  view_to_pan = gesture_waiter.wait_for_view(query, options)
96
96
 
97
- if Device.default.simulator?
98
-
97
+ # * will never match a UIScrollView or subclass.
98
+ if Device.default.simulator? && query.to_s != '*'
99
99
  should_raise = false
100
100
 
101
101
  content_offset = gesture_waiter.query(query, :contentOffset).first
102
-
103
102
  if content_offset != '*****'
104
103
  # Panning on anything with a content offset is broken.
105
104
  should_raise = true
105
+ elsif view_to_pan['class'][/TableViewCell/, 0]
106
+ should_raise = true
106
107
  else
108
+ new_query = "#{query} parent UITableViewCell"
109
+ should_raise = !gesture_waiter.query(new_query).empty?
107
110
  # TODO: Identify other conditions
108
111
  # TODO: Can we detect UITableViewCells?
109
112
  # The gist is that if the view is a UIScrollView or in a UIScrollView
@@ -112,9 +115,20 @@ module Calabash
112
115
 
113
116
  if should_raise
114
117
  message = [
118
+ '',
115
119
  "Apple's public UIAutomation API `dragInsideWithOptions` is broken for iOS Simulators >= 7",
116
- 'Try using the scroll_* methods or test on a device.'
117
- ].join("\n")
120
+ '',
121
+ 'If you are trying to swipe-to-delete on a simulator, it will only work on a device.',
122
+ '',
123
+ 'If you are trying to manipulate a table, collection or scroll view, try using the Scroll API.',
124
+ ' * scroll # Scroll in a direction.',
125
+ ' * scroll_to_row # Scroll to a row with row / section indexes.',
126
+ ' * scroll_to_row_with_mark # Scroll to table row with a mark.',
127
+ ' * scroll_to_item # Scroll to collection item with item / section indexes.',
128
+ ' * scroll_to_item_with_mark # Scroll to collection item with a mark.',
129
+ '',
130
+ 'All gestures work on physical devices.'
131
+ ].map { |msg| Color.red(msg) }.join("\n")
118
132
  raise message
119
133
  end
120
134
  end
@@ -134,9 +148,15 @@ module Calabash
134
148
  Calabash::QueryResult.create([view_to_pan], query)
135
149
  end
136
150
 
151
+ def pan_screen(view_to_pan, from_offset, to_offset, options)
152
+ uia_serialize_and_call(:panOffset, from_offset, to_offset, options)
153
+
154
+ Calabash::QueryResult.create([view_to_pan], '*')
155
+ end
156
+
137
157
  private
138
158
 
139
- # !@visibility private
159
+ # @!visibility private
140
160
  #
141
161
  # Unlike the Calabash Android server, the iOS server does not wait
142
162
  # before gestures, so the client must do the waiting. The _gesture_waiter
@@ -1,7 +1,7 @@
1
1
  module Calabash
2
2
  module IOS
3
3
 
4
- # !@visibility private
4
+ # @!visibility private
5
5
  module RotationMixin
6
6
 
7
7
  def rotate(direction)
@@ -58,7 +58,7 @@ module Calabash
58
58
  playback_route(recording_name, form_factor)
59
59
  end
60
60
 
61
- # !@visibility private
61
+ # @!visibility private
62
62
  # Caller must pass position one of these positions down, left, right, up
63
63
  def rotate_home_button_to(position)
64
64
 
@@ -1,6 +1,7 @@
1
1
  module Calabash
2
2
  module IOS
3
3
 
4
+ # @!visibility private
4
5
  # Raised when there is a problem handling an HTTP route.
5
6
  class RouteError < StandardError; end
6
7
 
@@ -2,7 +2,7 @@ module Calabash
2
2
  module IOS
3
3
  module Routes
4
4
 
5
- # !@visibility private
5
+ # @!visibility private
6
6
  module PlaybackRouteMixin
7
7
 
8
8
  # This is a Legacy API and is only used to support rotations.
@@ -25,7 +25,7 @@ module Calabash
25
25
  logger.log('', :info)
26
26
  logger.log(Color.cyan('> console_attach # Attaches with the default strategy.'),
27
27
  :info)
28
- logger.log(Color.cyan('> console_attach(uia_strategy) # Attaches with a specific strategy.'),
28
+ logger.log(Color.cyan('> console_attach(uia_strategy) # Attaches with a specific strategy.'),
29
29
  :info)
30
30
  logger.log('', :info)
31
31
  logger.log('', :info)
@@ -1,7 +1,7 @@
1
1
  module Calabash
2
2
  module IOS
3
3
 
4
- # !@visibility private
4
+ # @!visibility private
5
5
  module UIAMixin
6
6
 
7
7
  def evaluate_uia(script)
@@ -0,0 +1,107 @@
1
+ module Calabash
2
+ module IOS
3
+
4
+ # @!visibility private
5
+ module Gestures
6
+
7
+ # Concrete implementation of pan_screen_up gesture.
8
+ def _pan_screen_up(options={})
9
+
10
+ gesture_options = options.dup
11
+ gesture_options[:duration] ||= 0.5
12
+ gesture_options[:timeout] ||= Calabash::Gestures::DEFAULT_GESTURE_WAIT_TIMEOUT
13
+
14
+ points_from_top = pan_points_from_top
15
+ points_from_bottom = pan_points_from_bottom
16
+
17
+ top_view = query('*').first
18
+
19
+ height = top_view['frame']['height'].to_f
20
+ width = top_view['frame']['width'].to_f
21
+
22
+ start_y = height - points_from_bottom
23
+ end_y = points_from_top
24
+ x = width/2.0
25
+
26
+ from_offset = coordinate(x, start_y)
27
+ to_offset = coordinate(x, end_y)
28
+
29
+ Device.default.pan_screen(top_view, from_offset, to_offset, gesture_options)
30
+ end
31
+
32
+ # Concrete implementation of pan_screen_down gesture.
33
+ def _pan_screen_down(options={})
34
+
35
+ gesture_options = options.dup
36
+ gesture_options[:duration] ||= 0.5
37
+ gesture_options[:timeout] ||= Calabash::Gestures::DEFAULT_GESTURE_WAIT_TIMEOUT
38
+
39
+ points_from_top = pan_points_from_top
40
+ points_from_bottom = pan_points_from_bottom
41
+
42
+ top_view = query('*').first
43
+
44
+ height = top_view['frame']['height'].to_f
45
+ width = top_view['frame']['width'].to_f
46
+
47
+ start_y = points_from_top
48
+ end_y = height - points_from_bottom
49
+ x = width/2.0
50
+
51
+ from_offset = coordinate(x, start_y)
52
+ to_offset = coordinate(x, end_y)
53
+
54
+ Device.default.pan_screen(top_view, from_offset, to_offset, gesture_options)
55
+ end
56
+
57
+ private
58
+
59
+ # Number of points from the top to start a full-screen vertical pan.
60
+ def pan_points_from_top
61
+ # 20 pixels for status bar in portrait; status bar is usually missing
62
+ # in landscape @todo route for status bar height
63
+
64
+ # Swiping from top will pull down the notification center.
65
+ # Touching the status bar can cause table views to scroll to the top.
66
+ orientation = status_bar_orientation
67
+ if orientation == 'down' || orientation == 'up'
68
+ points_from_top = 20
69
+ else
70
+ points_from_top = 10
71
+ end
72
+
73
+ # Navigation bar will intercept touches.
74
+ result = query('UINavigationBar')
75
+ if !result.empty?
76
+ navbar = result.first
77
+ points_from_top = points_from_top + navbar['frame']['height'] + 10
78
+ end
79
+ points_from_top
80
+ end
81
+
82
+ # Number of points from the bottom to start a full-screen vertical pan.
83
+ def pan_points_from_bottom
84
+ # Dragging from the bottom will lift the transport controls.
85
+ points_from_bottom = 10
86
+
87
+ # Tab bar will intercept touches _and_ its hit box is larger than its
88
+ # visible rect!
89
+ result = query('UITabBar')
90
+ if !result.empty?
91
+ tabbar = result.first
92
+ points_from_bottom = points_from_bottom + tabbar['frame']['height']
93
+ end
94
+
95
+ # @todo toolbars might not be anchored to the bottom of the screen
96
+
97
+ # Toolbars will intercept touches.
98
+ result = query('UIToolBar')
99
+ if !result.empty?
100
+ toolbar = result.first
101
+ points_from_bottom = points_from_bottom + toolbar['frame']['height']
102
+ end
103
+ points_from_bottom
104
+ end
105
+ end
106
+ end
107
+ end