calabash 2.0.0.pre11 → 2.0.0.prelegacy
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +17 -5
- data/bin/calabash +4 -3
- data/lib/calabash/android/adb.rb +37 -34
- data/lib/calabash/android/application.rb +1 -1
- data/lib/calabash/android/build/builder.rb +1 -1
- data/lib/calabash/android/build/java_keystore.rb +1 -1
- data/lib/calabash/android/build/resigner.rb +1 -1
- data/lib/calabash/android/device.rb +46 -204
- data/lib/calabash/android/environment.rb +1 -14
- data/lib/calabash/android/gestures.rb +22 -6
- data/lib/calabash/android/interactions.rb +17 -14
- data/lib/calabash/android/legacy.rb +141 -4
- data/lib/calabash/android/lib/.irbrc +1 -9
- data/lib/calabash/android/lib/AndroidManifest.xml +2 -23
- data/lib/calabash/android/lib/TestServer.apk +0 -0
- data/lib/calabash/android/life_cycle.rb +3 -3
- data/lib/calabash/android/orientation.rb +8 -8
- data/lib/calabash/android/physical_buttons.rb +16 -19
- data/lib/calabash/android/server.rb +1 -6
- data/lib/calabash/android/text.rb +12 -12
- data/lib/calabash/android.rb +26 -92
- data/lib/calabash/application.rb +0 -3
- data/lib/calabash/cli/generate.rb +18 -8
- data/lib/calabash/cli/helpers.rb +9 -4
- data/lib/calabash/cli/run.rb +1 -1
- data/lib/calabash/console_helpers.rb +11 -179
- data/lib/calabash/device.rb +19 -4
- data/lib/calabash/gestures.rb +198 -292
- data/lib/calabash/http/retriable_client.rb +3 -18
- data/lib/calabash/http.rb +0 -1
- data/lib/calabash/interactions.rb +40 -3
- data/lib/calabash/ios/conditions.rb +1 -1
- data/lib/calabash/ios/console_helpers.rb +2 -2
- data/lib/calabash/ios/date_picker.rb +8 -10
- data/lib/calabash/ios/device/device_implementation.rb +21 -9
- data/lib/calabash/ios/device/gestures_mixin.rb +55 -53
- data/lib/calabash/ios/device/keyboard_mixin.rb +0 -21
- data/lib/calabash/ios/device/rotation_mixin.rb +65 -3
- data/lib/calabash/ios/device/text_mixin.rb +21 -0
- data/lib/calabash/ios/device.rb +1 -0
- data/lib/calabash/ios/gestures.rb +90 -24
- data/lib/calabash/ios/interactions.rb +6 -1
- data/lib/calabash/ios/lib/.irbrc +2 -9
- data/lib/calabash/ios/orientation.rb +8 -8
- data/lib/calabash/ios/runtime.rb +14 -14
- data/lib/calabash/ios/scroll.rb +17 -25
- data/lib/calabash/ios/slider.rb +18 -11
- data/lib/calabash/ios/text.rb +74 -20
- data/lib/calabash/ios/uia.rb +1 -1
- data/lib/calabash/ios.rb +16 -77
- data/lib/calabash/legacy.rb +6 -9
- data/lib/calabash/lib/skeleton/{Gemfile.skeleton → Gemfile} +0 -0
- data/lib/calabash/lib/skeleton/config/{cucumber.yml.skeleton → cucumber.yml} +0 -0
- data/lib/calabash/lib/skeleton/features/{sample.feature.skeleton → sample.feature} +0 -0
- data/lib/calabash/lib/skeleton/features/step_definitions/{sample_steps.rb.skeleton → calabash_steps.rb} +8 -8
- data/lib/calabash/lib/skeleton/features/support/{dry_run.rb.skeleton → dry_run.rb} +5 -2
- data/lib/calabash/lib/skeleton/features/support/{env.rb.skeleton → env.rb} +8 -2
- data/lib/calabash/lib/skeleton/features/support/hooks.rb +83 -0
- data/lib/calabash/life_cycle.rb +8 -16
- data/lib/calabash/location.rb +15 -14
- data/lib/calabash/orientation.rb +8 -8
- data/lib/calabash/page.rb +4 -1
- data/lib/calabash/screenshot.rb +3 -3
- data/lib/calabash/text.rb +19 -31
- data/lib/calabash/utility.rb +8 -41
- data/lib/calabash/version.rb +1 -1
- data/lib/calabash/wait.rb +192 -177
- data/lib/calabash.rb +10 -53
- metadata +32 -43
- data/lib/calabash/android/device/helper_application.rb +0 -95
- data/lib/calabash/android/lib/HelperApplication.apk +0 -0
- data/lib/calabash/android/lib/HelperApplicationTestServer.apk +0 -0
- data/lib/calabash/android/web.rb +0 -12
- data/lib/calabash/http/forwarding_client.rb +0 -23
- data/lib/calabash/internal.rb +0 -48
- data/lib/calabash/ios/automator/automator.rb +0 -217
- data/lib/calabash/ios/automator/coordinates.rb +0 -37
- data/lib/calabash/ios/automator/device_agent.rb +0 -379
- data/lib/calabash/ios/automator.rb +0 -9
- data/lib/calabash/ios/legacy.rb +0 -6
- data/lib/calabash/ios/web.rb +0 -10
- data/lib/calabash/lib/skeleton/features/support/hooks.rb.skeleton +0 -34
- data/lib/calabash/retry.rb +0 -33
- data/lib/calabash/stubs.rb +0 -21
- data/lib/calabash/web.rb +0 -44
@@ -1,217 +0,0 @@
|
|
1
|
-
module Calabash
|
2
|
-
module IOS
|
3
|
-
# @!visibility private
|
4
|
-
module Automator
|
5
|
-
# @!visibility private
|
6
|
-
class Automator
|
7
|
-
include Utility
|
8
|
-
|
9
|
-
# @!visibility private
|
10
|
-
def initialize(*args)
|
11
|
-
abstract_method!
|
12
|
-
end
|
13
|
-
|
14
|
-
# @!visibility private
|
15
|
-
def name
|
16
|
-
abstract_method!
|
17
|
-
end
|
18
|
-
|
19
|
-
# @!visibility private
|
20
|
-
def stop
|
21
|
-
abstract_method!
|
22
|
-
end
|
23
|
-
|
24
|
-
# @!visibility private
|
25
|
-
def running?
|
26
|
-
abstract_method!
|
27
|
-
end
|
28
|
-
|
29
|
-
# @!visibility private
|
30
|
-
def client
|
31
|
-
abstract_method!
|
32
|
-
end
|
33
|
-
|
34
|
-
# @!visibility private
|
35
|
-
def touch(options)
|
36
|
-
abstract_method!
|
37
|
-
end
|
38
|
-
|
39
|
-
# @!visibility private
|
40
|
-
def double_tap(options)
|
41
|
-
abstract_method!
|
42
|
-
end
|
43
|
-
|
44
|
-
# @!visibility private
|
45
|
-
def two_finger_tap(options)
|
46
|
-
abstract_method!
|
47
|
-
end
|
48
|
-
|
49
|
-
# @!visibility private
|
50
|
-
def touch_hold(options)
|
51
|
-
abstract_method!
|
52
|
-
end
|
53
|
-
|
54
|
-
# @!visibility private
|
55
|
-
def flick(options)
|
56
|
-
abstract_method!
|
57
|
-
end
|
58
|
-
|
59
|
-
# @!visibility private
|
60
|
-
def pan(options={})
|
61
|
-
abstract_method!
|
62
|
-
end
|
63
|
-
|
64
|
-
# @!visibility private
|
65
|
-
#
|
66
|
-
# Callers must validate the options.
|
67
|
-
def pan_coordinates(from_point, to_point, options={})
|
68
|
-
abstract_method!
|
69
|
-
end
|
70
|
-
|
71
|
-
# @!visibility private
|
72
|
-
#
|
73
|
-
# Callers must validate the options.
|
74
|
-
def pinch(in_or_out, options)
|
75
|
-
abstract_method!
|
76
|
-
end
|
77
|
-
|
78
|
-
# @!visibility private
|
79
|
-
def send_app_to_background(seconds)
|
80
|
-
abstract_method!
|
81
|
-
end
|
82
|
-
|
83
|
-
# @!visibility private
|
84
|
-
#
|
85
|
-
# It is the caller's responsibility to:
|
86
|
-
# 1. expect the keyboard is visible
|
87
|
-
# 2. escape the existing text
|
88
|
-
def enter_text_with_keyboard(string, options={})
|
89
|
-
abstract_method!
|
90
|
-
end
|
91
|
-
|
92
|
-
# @!visibility private
|
93
|
-
#
|
94
|
-
# Respond to keys like 'Delete' or 'Return'.
|
95
|
-
def char_for_keyboard_action(action_key)
|
96
|
-
abstract_method!
|
97
|
-
end
|
98
|
-
|
99
|
-
# @!visibility private
|
100
|
-
# It is the caller's responsibility to ensure the keyboard is visible.
|
101
|
-
def enter_char_with_keyboard(char)
|
102
|
-
abstract_method!
|
103
|
-
end
|
104
|
-
|
105
|
-
# @!visibility private
|
106
|
-
# It is the caller's responsibility to ensure the keyboard is visible.
|
107
|
-
def tap_keyboard_action_key(return_key_type_of_first_responder)
|
108
|
-
abstract_method!
|
109
|
-
end
|
110
|
-
|
111
|
-
# @!visibility private
|
112
|
-
# It is the caller's responsibility to ensure the keyboard is visible.
|
113
|
-
def tap_keyboard_delete_key
|
114
|
-
abstract_method!
|
115
|
-
end
|
116
|
-
|
117
|
-
# @!visibility private
|
118
|
-
#
|
119
|
-
# Legacy API - can we remove this method?
|
120
|
-
#
|
121
|
-
# It is the caller's responsibility to ensure the keyboard is visible.
|
122
|
-
def fast_enter_text(text)
|
123
|
-
abstract_method!
|
124
|
-
end
|
125
|
-
|
126
|
-
# @!visibility private
|
127
|
-
#
|
128
|
-
# Caller is responsible for limiting calls to iPads and waiting for the
|
129
|
-
# keyboard to disappear.
|
130
|
-
def dismiss_ipad_keyboard
|
131
|
-
abstract_method!
|
132
|
-
end
|
133
|
-
|
134
|
-
# @!visibility private
|
135
|
-
#
|
136
|
-
# Caller is responsible for providing a valid direction.
|
137
|
-
def rotate(direction, status_bar_orientation)
|
138
|
-
abstract_method!
|
139
|
-
end
|
140
|
-
|
141
|
-
# @!visibility private
|
142
|
-
#
|
143
|
-
# Caller is responsible for normalizing and validating the position.
|
144
|
-
def rotate_home_button_to(position, status_bar_orientation)
|
145
|
-
abstract_method!
|
146
|
-
end
|
147
|
-
|
148
|
-
# @! visibility private
|
149
|
-
#
|
150
|
-
# It is important to remember that the current orientation is the
|
151
|
-
# position of the home button:
|
152
|
-
#
|
153
|
-
# :up => home button on the top => upside_down
|
154
|
-
# :bottom => home button on the bottom => portrait
|
155
|
-
# :left => home button on the left => landscape_right
|
156
|
-
# :right => home button on the right => landscape_left
|
157
|
-
#
|
158
|
-
# Notice how :left and :right are mapped.
|
159
|
-
def self.orientation_key(direction, current_orientation)
|
160
|
-
key = nil
|
161
|
-
case direction
|
162
|
-
when :left then
|
163
|
-
if current_orientation == :down
|
164
|
-
key = :landscape_left
|
165
|
-
elsif current_orientation == :right
|
166
|
-
key = :upside_down
|
167
|
-
elsif current_orientation == :left
|
168
|
-
key = :portrait
|
169
|
-
elsif current_orientation == :up
|
170
|
-
key = :landscape_right
|
171
|
-
end
|
172
|
-
when :right then
|
173
|
-
if current_orientation == :down
|
174
|
-
key = :landscape_right
|
175
|
-
elsif current_orientation == :right
|
176
|
-
key = :portrait
|
177
|
-
elsif current_orientation == :left
|
178
|
-
key = :upside_down
|
179
|
-
elsif current_orientation == :up
|
180
|
-
key = :landscape_left
|
181
|
-
end
|
182
|
-
else
|
183
|
-
raise ArgumentError,
|
184
|
-
"Expected '#{direction}' to be :left or :right"
|
185
|
-
end
|
186
|
-
|
187
|
-
key
|
188
|
-
end
|
189
|
-
|
190
|
-
# @!visibility private
|
191
|
-
def self.orientation_for_key(key)
|
192
|
-
DEVICE_ORIENTATION[key]
|
193
|
-
end
|
194
|
-
|
195
|
-
# @! visibility private
|
196
|
-
#
|
197
|
-
# It is important to remember that the current orientation is the
|
198
|
-
# position of the home button:
|
199
|
-
#
|
200
|
-
# :up => home button on the top => upside_down
|
201
|
-
# :bottom => home button on the bottom => portrait
|
202
|
-
# :left => home button on the left => landscape_right
|
203
|
-
# :right => home button on the right => landscape_left
|
204
|
-
#
|
205
|
-
# Notice how :left and :right are mapped to their logical opposite.
|
206
|
-
# @!visibility private
|
207
|
-
# @! visibility private
|
208
|
-
DEVICE_ORIENTATION = {
|
209
|
-
:portrait => 1,
|
210
|
-
:upside_down => 2,
|
211
|
-
:landscape_left => 3, # Home button on the right
|
212
|
-
:landscape_right => 4 # Home button on the left
|
213
|
-
}.freeze
|
214
|
-
end
|
215
|
-
end
|
216
|
-
end
|
217
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
module Calabash
|
2
|
-
module IOS
|
3
|
-
# @!visibility private
|
4
|
-
module Automator
|
5
|
-
# @!visibility private
|
6
|
-
class Coordinates
|
7
|
-
# @!visibility private
|
8
|
-
def self.end_point_for_swipe(dir, element)
|
9
|
-
case dir
|
10
|
-
when :left
|
11
|
-
degrees = 0
|
12
|
-
when :up
|
13
|
-
degrees = 90
|
14
|
-
when :right
|
15
|
-
degrees = 180
|
16
|
-
when :down
|
17
|
-
degrees = 270
|
18
|
-
end
|
19
|
-
radians = degrees * Math::PI / 180.0
|
20
|
-
|
21
|
-
element_width = element["rect"]["width"]
|
22
|
-
element_height = element["rect"]["height"]
|
23
|
-
x_center = element["rect"]["center_x"]
|
24
|
-
y_center = element["rect"]["center_y"]
|
25
|
-
radius = ([element_width, element_height].min) * 0.33
|
26
|
-
to_x = x_center - (radius * Math.cos(radians))
|
27
|
-
to_y = y_center - (radius * Math.sin(radians))
|
28
|
-
{:x => to_x, :y => to_y}
|
29
|
-
end
|
30
|
-
|
31
|
-
def self.distance(from, to)
|
32
|
-
Math.sqrt((from[:x] - to[:x]) ** 2 + (from[:y] - to[:y]) ** 2)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
@@ -1,379 +0,0 @@
|
|
1
|
-
require "run_loop"
|
2
|
-
|
3
|
-
module Calabash
|
4
|
-
module IOS
|
5
|
-
# @!visibility private
|
6
|
-
module Automator
|
7
|
-
# @!visibility private
|
8
|
-
class DeviceAgent < Calabash::IOS::Automator::Automator
|
9
|
-
|
10
|
-
# @!visibility private
|
11
|
-
def self.expect_valid_args(args)
|
12
|
-
if args.nil?
|
13
|
-
raise ArgumentError, "Expected args to be a non-nil Array"
|
14
|
-
end
|
15
|
-
|
16
|
-
if !args.is_a?(Array)
|
17
|
-
raise ArgumentError, %Q[Expected args to be an Array, found:
|
18
|
-
|
19
|
-
args = #{args}
|
20
|
-
|
21
|
-
]
|
22
|
-
end
|
23
|
-
|
24
|
-
if args.count != 1
|
25
|
-
raise(ArgumentError,
|
26
|
-
%Q[Expected args to be an Array with one element, found:
|
27
|
-
|
28
|
-
args = #{args}
|
29
|
-
|
30
|
-
])
|
31
|
-
end
|
32
|
-
|
33
|
-
if !args[0].is_a?(RunLoop::DeviceAgent::Client)
|
34
|
-
raise(ArgumentError, %Q[
|
35
|
-
Expected first element of args to be a RunLoop::DeviceAgent::Client instance, found:
|
36
|
-
args[0] = #{args[0]}])
|
37
|
-
end
|
38
|
-
|
39
|
-
true
|
40
|
-
end
|
41
|
-
|
42
|
-
attr_reader :client
|
43
|
-
|
44
|
-
# @!visibility private
|
45
|
-
def initialize(*args)
|
46
|
-
DeviceAgent.expect_valid_args(args)
|
47
|
-
@client = args[0]
|
48
|
-
end
|
49
|
-
|
50
|
-
# @!visibility private
|
51
|
-
def name
|
52
|
-
:device_agent
|
53
|
-
end
|
54
|
-
|
55
|
-
# @!visibility private
|
56
|
-
def stop
|
57
|
-
client.send(:shutdown)
|
58
|
-
end
|
59
|
-
|
60
|
-
# @!visibility private
|
61
|
-
def running?
|
62
|
-
client.send(:running?)
|
63
|
-
end
|
64
|
-
|
65
|
-
# @!visibility private
|
66
|
-
def session_delete
|
67
|
-
client.send(:session_delete)
|
68
|
-
end
|
69
|
-
|
70
|
-
# @!visibility private
|
71
|
-
def touch(options)
|
72
|
-
client.perform_coordinate_gesture("touch",
|
73
|
-
options[:coordinates][:x],
|
74
|
-
options[:coordinates][:y])
|
75
|
-
end
|
76
|
-
|
77
|
-
# @!visibility private
|
78
|
-
def double_tap(options)
|
79
|
-
client.perform_coordinate_gesture("double_tap",
|
80
|
-
options[:coordinates][:x],
|
81
|
-
options[:coordinates][:y])
|
82
|
-
end
|
83
|
-
|
84
|
-
# @!visibility private
|
85
|
-
def two_finger_tap(options)
|
86
|
-
client.perform_coordinate_gesture("two_finger_tap",
|
87
|
-
options[:coordinates][:x],
|
88
|
-
options[:coordinates][:y])
|
89
|
-
end
|
90
|
-
|
91
|
-
# @!visibility private
|
92
|
-
def touch_hold(options)
|
93
|
-
client.perform_coordinate_gesture("touch",
|
94
|
-
options[:coordinates][:x],
|
95
|
-
options[:coordinates][:y],
|
96
|
-
{:duration => options[:duration]})
|
97
|
-
end
|
98
|
-
|
99
|
-
# @!visibility private
|
100
|
-
def pinch(in_out, options)
|
101
|
-
dupped_options = options.dup
|
102
|
-
|
103
|
-
if dupped_options[:query].nil?
|
104
|
-
element = element_for_device_screen
|
105
|
-
coordinates = point_from(element, options)
|
106
|
-
else
|
107
|
-
hash = query_for_coordinates(dupped_options)
|
108
|
-
element = hash[:view]
|
109
|
-
coordinates = hash[:coordinates]
|
110
|
-
end
|
111
|
-
|
112
|
-
in_out = in_out.to_s
|
113
|
-
duration = dupped_options[:duration]
|
114
|
-
amount = dupped_options[:amount]
|
115
|
-
|
116
|
-
gesture_options = {
|
117
|
-
:pinch_direction => in_out,
|
118
|
-
:amount => amount,
|
119
|
-
:duration => duration
|
120
|
-
}
|
121
|
-
|
122
|
-
client.perform_coordinate_gesture("pinch",
|
123
|
-
coordinates[:x],
|
124
|
-
coordinates[:y],
|
125
|
-
gesture_options)
|
126
|
-
|
127
|
-
[element]
|
128
|
-
end
|
129
|
-
|
130
|
-
MIN_SECONDS_PR_PIXEL_FOR_PAN = 0.006
|
131
|
-
|
132
|
-
# @!visibility private
|
133
|
-
def pan(options)
|
134
|
-
# A pan seems to require 0.005 seconds pr. pixel.
|
135
|
-
# Therefore we require that the duration is at least
|
136
|
-
# 0.005 seconds pr pixel.
|
137
|
-
|
138
|
-
duration = [
|
139
|
-
options[:duration],
|
140
|
-
MIN_SECONDS_PR_PIXEL_FOR_PAN *
|
141
|
-
Coordinates.distance(options[:coordinates][:from], options[:coordinates][:to])
|
142
|
-
].max
|
143
|
-
|
144
|
-
client.pan_between_coordinates(options[:coordinates][:from],
|
145
|
-
options[:coordinates][:to],
|
146
|
-
{:duration => duration})
|
147
|
-
end
|
148
|
-
|
149
|
-
# @!visibility private
|
150
|
-
def flick(options)
|
151
|
-
gesture_options = {
|
152
|
-
duration: 0.2
|
153
|
-
}
|
154
|
-
|
155
|
-
delta = options[:delta]
|
156
|
-
|
157
|
-
# The UIA deltas are too small.
|
158
|
-
scaled_delta = {
|
159
|
-
:x => delta[:x] * 2.0,
|
160
|
-
:y => delta[:y] * 2.0
|
161
|
-
}
|
162
|
-
|
163
|
-
hash = query_for_coordinates(options)
|
164
|
-
view = hash[:view]
|
165
|
-
|
166
|
-
start_point = point_from(view)
|
167
|
-
end_point = point_from(view, {:offset => scaled_delta})
|
168
|
-
|
169
|
-
client.pan_between_coordinates(start_point,
|
170
|
-
end_point,
|
171
|
-
gesture_options)
|
172
|
-
[view]
|
173
|
-
end
|
174
|
-
|
175
|
-
# @!visibility private
|
176
|
-
def enter_text_with_keyboard(string, options={})
|
177
|
-
client.enter_text(string)
|
178
|
-
end
|
179
|
-
|
180
|
-
# @!visibility private
|
181
|
-
def enter_char_with_keyboard(char)
|
182
|
-
client.enter_text(char)
|
183
|
-
end
|
184
|
-
|
185
|
-
# @!visibility private
|
186
|
-
def char_for_keyboard_action(action_key)
|
187
|
-
SPECIAL_ACTION_CHARS[action_key]
|
188
|
-
end
|
189
|
-
|
190
|
-
# @!visibility private
|
191
|
-
def tap_keyboard_action_key(return_key_type_of_first_responder)
|
192
|
-
mark = mark_for_return_key_of_first_responder(return_key_type_of_first_responder)
|
193
|
-
if mark
|
194
|
-
begin
|
195
|
-
# The underlying query for coordinates always expects results.
|
196
|
-
value = client.touch({marked: mark})
|
197
|
-
return value
|
198
|
-
rescue RuntimeError => _
|
199
|
-
RunLoop.log_debug("Cannot find mark '#{mark}' with query; will send a newline")
|
200
|
-
end
|
201
|
-
else
|
202
|
-
RunLoop.log_debug("Cannot find keyboard return key type; sending a newline")
|
203
|
-
end
|
204
|
-
|
205
|
-
code = char_for_keyboard_action("Return")
|
206
|
-
client.enter_text(code)
|
207
|
-
end
|
208
|
-
|
209
|
-
# @!visibility private
|
210
|
-
def tap_keyboard_delete_key
|
211
|
-
client.touch({marked: "delete"})
|
212
|
-
end
|
213
|
-
|
214
|
-
# @!visibility private
|
215
|
-
def fast_enter_text(text)
|
216
|
-
client.enter_text(text)
|
217
|
-
end
|
218
|
-
|
219
|
-
# @!visibility private
|
220
|
-
#
|
221
|
-
# Stable across different keyboard languages.
|
222
|
-
def dismiss_ipad_keyboard
|
223
|
-
client.touch({marked: "Hide keyboard"})
|
224
|
-
end
|
225
|
-
|
226
|
-
# @!visibility private
|
227
|
-
def rotate(direction, status_bar_orientation)
|
228
|
-
# Caller is responsible for normalizing and verifying direction.
|
229
|
-
current_orientation = status_bar_orientation.to_sym
|
230
|
-
key = Automator.orientation_key(direction, current_orientation)
|
231
|
-
position = Automator.orientation_for_key(key)
|
232
|
-
rotate_home_button_to(position, status_bar_orientation)
|
233
|
-
end
|
234
|
-
|
235
|
-
# @!visibility private
|
236
|
-
def rotate_home_button_to(position, status_bar_orientation)
|
237
|
-
# Caller is responsible for normalizing and verifying position.
|
238
|
-
client.rotate_home_button_to(position)
|
239
|
-
status_bar_orientation.to_sym
|
240
|
-
end
|
241
|
-
|
242
|
-
private
|
243
|
-
|
244
|
-
# @!visibility private
|
245
|
-
#
|
246
|
-
# Calls #point_from which applies any :offset supplied in the options.
|
247
|
-
def query_for_coordinates(options)
|
248
|
-
uiquery = options[:query]
|
249
|
-
|
250
|
-
if uiquery.nil?
|
251
|
-
offset = options[:offset]
|
252
|
-
|
253
|
-
if offset && offset[:x] && offset[:y]
|
254
|
-
{
|
255
|
-
:coordinates => offset,
|
256
|
-
:view => offset
|
257
|
-
}
|
258
|
-
else
|
259
|
-
raise ArgumentError, %Q[
|
260
|
-
If query is nil, there must be a valid offset in the options.
|
261
|
-
|
262
|
-
Expected: options[:offset] = {:x => NUMERIC, :y => NUMERIC}
|
263
|
-
Actual: options[:offset] = #{offset ? offset : "nil"}
|
264
|
-
|
265
|
-
]
|
266
|
-
end
|
267
|
-
else
|
268
|
-
|
269
|
-
first_element = first_element_for_query(uiquery)
|
270
|
-
|
271
|
-
if first_element.nil?
|
272
|
-
msg = %Q[
|
273
|
-
Could not find any views with query:
|
274
|
-
|
275
|
-
#{uiquery}
|
276
|
-
|
277
|
-
Make sure your query returns at least one view.
|
278
|
-
|
279
|
-
]
|
280
|
-
Calabash::Cucumber::Map.new.screenshot_and_raise(msg)
|
281
|
-
else
|
282
|
-
{
|
283
|
-
:coordinates => point_from(first_element, options),
|
284
|
-
:view => first_element
|
285
|
-
}
|
286
|
-
end
|
287
|
-
end
|
288
|
-
end
|
289
|
-
|
290
|
-
# @!visibility private
|
291
|
-
def first_element_for_query(uiquery)
|
292
|
-
|
293
|
-
if uiquery.nil?
|
294
|
-
raise ArgumentError, "Query cannot be nil"
|
295
|
-
end
|
296
|
-
|
297
|
-
# Will raise if response "outcome" is not SUCCESS
|
298
|
-
results = Calabash::Cucumber::Map.raw_map(uiquery, :query)["results"]
|
299
|
-
|
300
|
-
if results.empty?
|
301
|
-
nil
|
302
|
-
else
|
303
|
-
results[0]
|
304
|
-
end
|
305
|
-
end
|
306
|
-
|
307
|
-
# @!visibility private
|
308
|
-
def element_for_device_screen
|
309
|
-
screen_dimensions = device.screen_dimensions
|
310
|
-
|
311
|
-
scale = screen_dimensions[:scale]
|
312
|
-
height = (screen_dimensions[:height]/scale).to_i
|
313
|
-
center_y = (height/2)
|
314
|
-
width = (screen_dimensions[:width]/scale).to_i
|
315
|
-
center_x = (width/2)
|
316
|
-
|
317
|
-
{
|
318
|
-
"screen" => true,
|
319
|
-
"rect" => {
|
320
|
-
"height" => height,
|
321
|
-
"width" => width,
|
322
|
-
"center_x" => center_x,
|
323
|
-
"center_y" => center_y
|
324
|
-
}
|
325
|
-
}
|
326
|
-
end
|
327
|
-
|
328
|
-
# @!visibility private
|
329
|
-
#
|
330
|
-
# Don't change the double quotes.
|
331
|
-
SPECIAL_ACTION_CHARS = {
|
332
|
-
"Delete" => "\b",
|
333
|
-
"Return" => "\n"
|
334
|
-
}.freeze
|
335
|
-
|
336
|
-
# @!visibility private
|
337
|
-
#
|
338
|
-
# Keys are from the UIReturnKeyType enum.
|
339
|
-
#
|
340
|
-
# The values are localization independent identifiers - these are
|
341
|
-
# stable across localizations and keyboard languages. The exception is
|
342
|
-
# Continue which is not stable.
|
343
|
-
RETURN_KEY_TYPE = {
|
344
|
-
0 => "Return",
|
345
|
-
1 => "Go",
|
346
|
-
2 => "Google",
|
347
|
-
# Needs special physical device vs simulator handling.
|
348
|
-
3 => "Join",
|
349
|
-
4 => "Next",
|
350
|
-
5 => "Route",
|
351
|
-
6 => "Search",
|
352
|
-
7 => "Send",
|
353
|
-
8 => "Yahoo",
|
354
|
-
9 => "Done",
|
355
|
-
10 => "Emergency call",
|
356
|
-
# https://xamarin.atlassian.net/browse/TCFW-344
|
357
|
-
# Localized!!! Apple bug.
|
358
|
-
11 => "Continue"
|
359
|
-
}.freeze
|
360
|
-
|
361
|
-
# @!visibility private
|
362
|
-
def mark_for_return_key_type(number)
|
363
|
-
# https://xamarin.atlassian.net/browse/TCFW-361
|
364
|
-
value = RETURN_KEY_TYPE[number]
|
365
|
-
if value == "Join" && !simulator?
|
366
|
-
"Join:"
|
367
|
-
else
|
368
|
-
value
|
369
|
-
end
|
370
|
-
end
|
371
|
-
|
372
|
-
# @!visibility private
|
373
|
-
def mark_for_return_key_of_first_responder(return_key_type_of_first_responder)
|
374
|
-
mark_for_return_key_type(return_key_type_of_first_responder)
|
375
|
-
end
|
376
|
-
end
|
377
|
-
end
|
378
|
-
end
|
379
|
-
end
|
data/lib/calabash/ios/legacy.rb
DELETED
data/lib/calabash/ios/web.rb
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
require 'calabash'
|
2
|
-
|
3
|
-
Before do |scenario|
|
4
|
-
if scenario.respond_to?(:scenario_outline)
|
5
|
-
scenario = scenario.scenario_outline
|
6
|
-
end
|
7
|
-
|
8
|
-
reset_between_scenarios(scenario) do
|
9
|
-
cal.reset_device_changes # Resets changes Calabash has made to the device
|
10
|
-
cal.ensure_app_installed # Installs the app unless it is already installed
|
11
|
-
cal.clear_app_data # Clears the application data
|
12
|
-
cal.start_app # Starts the application
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
After do |scenario|
|
17
|
-
if scenario.failed?
|
18
|
-
cal.screenshot_embed
|
19
|
-
end
|
20
|
-
|
21
|
-
cal.stop_app
|
22
|
-
end
|
23
|
-
|
24
|
-
def reset_between_scenarios(scenario, &block)
|
25
|
-
block.call
|
26
|
-
end
|
27
|
-
|
28
|
-
def reset_between_features(scenario, &block)
|
29
|
-
if scenario.feature != @last_feature
|
30
|
-
block.call
|
31
|
-
end
|
32
|
-
|
33
|
-
@last_feature = scenario.feature
|
34
|
-
end
|