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.
- checksums.yaml +4 -4
- data/README.md +19 -0
- data/lib/calabash.rb +4 -2
- data/lib/calabash/android/build/java_keystore.rb +1 -0
- data/lib/calabash/android/console_helpers.rb +1 -0
- data/lib/calabash/android/defaults.rb +23 -13
- data/lib/calabash/android/device.rb +84 -19
- data/lib/calabash/android/environment.rb +2 -0
- data/lib/calabash/android/gestures.rb +4 -3
- data/lib/calabash/android/interactions.rb +1 -0
- data/lib/calabash/android/lib/.irbrc +61 -48
- data/lib/calabash/android/lib/TestServer.apk +0 -0
- data/lib/calabash/android/life_cycle.rb +3 -2
- data/lib/calabash/android/orientation.rb +1 -0
- data/lib/calabash/android/physical_buttons.rb +3 -1
- data/lib/calabash/android/screenshot.rb +0 -1
- data/lib/calabash/android/text.rb +1 -0
- data/lib/calabash/application.rb +20 -1
- data/lib/calabash/cli/generate.rb +10 -2
- data/lib/calabash/console_helpers.rb +101 -13
- data/lib/calabash/defaults.rb +36 -3
- data/lib/calabash/device.rb +28 -3
- data/lib/calabash/gestures.rb +12 -12
- data/lib/calabash/http/request.rb +1 -0
- data/lib/calabash/http/retriable_client.rb +1 -0
- data/lib/calabash/interactions.rb +2 -1
- data/lib/calabash/ios.rb +2 -0
- data/lib/calabash/ios/conditions.rb +1 -0
- data/lib/calabash/ios/console_helpers.rb +1 -0
- data/lib/calabash/ios/defaults.rb +32 -17
- data/lib/calabash/ios/device/device_implementation.rb +5 -1
- data/lib/calabash/ios/device/gestures_mixin.rb +27 -7
- data/lib/calabash/ios/device/rotation_mixin.rb +2 -2
- data/lib/calabash/ios/device/routes/error.rb +1 -0
- data/lib/calabash/ios/device/routes/playback_route_mixin.rb +1 -1
- data/lib/calabash/ios/device/routes/uia_route_mixin.rb +1 -1
- data/lib/calabash/ios/device/uia_mixin.rb +1 -1
- data/lib/calabash/ios/gestures.rb +107 -0
- data/lib/calabash/ios/interactions.rb +1 -0
- data/lib/calabash/ios/lib/.irbrc +61 -47
- data/lib/calabash/ios/orientation.rb +1 -0
- data/lib/calabash/ios/runtime.rb +1 -0
- data/lib/calabash/ios/scroll.rb +7 -7
- data/lib/calabash/ios/text.rb +3 -0
- data/lib/calabash/ios/uia.rb +1 -0
- data/lib/calabash/lib/skeleton/.gitignore +19 -0
- data/lib/calabash/lib/skeleton/Gemfile +5 -0
- data/lib/calabash/life_cycle.rb +3 -2
- data/lib/calabash/location.rb +5 -6
- data/lib/calabash/logger.rb +1 -0
- data/lib/calabash/orientation.rb +1 -0
- data/lib/calabash/page.rb +1 -0
- data/lib/calabash/screenshot.rb +1 -0
- data/lib/calabash/server.rb +1 -0
- data/lib/calabash/text.rb +3 -2
- data/lib/calabash/utility.rb +2 -1
- data/lib/calabash/version.rb +1 -1
- data/lib/calabash/wait.rb +1 -0
- metadata +114 -114
- data/lib/calabash/android/cucumber.rb +0 -3
- data/lib/calabash/android/scroll.rb +0 -5
- data/lib/calabash/patch/run_loop.rb +0 -90
data/lib/calabash/gestures.rb
CHANGED
@@ -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
|
-
# @
|
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
|
-
#
|
349
|
+
# @!visibility private
|
350
350
|
def _pan_screen_up(options={})
|
351
351
|
abstract_method!
|
352
352
|
end
|
353
353
|
|
354
|
-
#
|
354
|
+
# @!visibility private
|
355
355
|
def _pan_screen_down(options={})
|
356
356
|
abstract_method!
|
357
357
|
end
|
358
358
|
|
359
|
-
#
|
359
|
+
# @!visibility private
|
360
360
|
def _flick_screen_up(options={})
|
361
361
|
abstract_method!
|
362
362
|
end
|
363
363
|
|
364
|
-
#
|
364
|
+
# @!visibility private
|
365
365
|
def _flick_screen_down(options={})
|
366
366
|
abstract_method!
|
367
367
|
end
|
368
368
|
|
369
|
-
#
|
369
|
+
# @!visibility private
|
370
370
|
def _pinch_screen(direction, options={})
|
371
371
|
abstract_method!
|
372
372
|
end
|
373
373
|
|
374
|
-
#
|
374
|
+
# @!visibility private
|
375
375
|
def _pinch_to_zoom(direction, query, options={})
|
376
376
|
abstract_method!
|
377
377
|
end
|
378
378
|
|
379
|
-
#
|
379
|
+
# @!visibility private
|
380
380
|
def _pinch_screen_to_zoom(direction, options={})
|
381
381
|
abstract_method!
|
382
382
|
end
|
@@ -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]
|
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,27 +1,42 @@
|
|
1
1
|
module Calabash
|
2
2
|
module IOS
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
-
#
|
14
|
-
|
15
|
-
|
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
|
-
|
26
|
+
# Setup the default device
|
27
|
+
identifier =
|
28
|
+
Device.default_identifier_for_application(Calabash.default_application)
|
18
29
|
|
19
|
-
|
20
|
-
end
|
30
|
+
server = Server.default
|
21
31
|
|
22
|
-
|
23
|
-
|
24
|
-
|
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
|
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
|
-
|
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
|
-
'
|
117
|
-
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
|
@@ -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)
|
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)
|
@@ -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
|