calabash-cucumber 0.9.163.pre6 → 0.9.163.pre7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/calabash-cucumber.gemspec +1 -1
- data/lib/calabash-cucumber/actions/instruments_actions.rb +135 -0
- data/lib/calabash-cucumber/actions/playback_actions.rb +104 -0
- data/lib/calabash-cucumber/connection.rb +16 -0
- data/lib/calabash-cucumber/connection_helpers.rb +17 -0
- data/lib/calabash-cucumber/core.rb +80 -553
- data/lib/calabash-cucumber/failure_helpers.rb +44 -0
- data/lib/calabash-cucumber/http_helpers.rb +102 -0
- data/lib/calabash-cucumber/ios7_operations.rb +46 -31
- data/lib/calabash-cucumber/keyboard_helpers.rb +26 -16
- data/lib/calabash-cucumber/launcher.rb +42 -8
- data/lib/calabash-cucumber/map.rb +28 -0
- data/lib/calabash-cucumber/operations.rb +0 -4
- data/lib/calabash-cucumber/playback_helpers.rb +200 -0
- data/lib/calabash-cucumber/query_helpers.rb +32 -0
- data/lib/calabash-cucumber/resources/double_tap_ios5_ipad.base64 +15 -0
- data/lib/calabash-cucumber/resources/double_tap_ios5_iphone.base64 +15 -0
- data/lib/calabash-cucumber/resources/double_tap_ios6_ipad.base64 +22 -0
- data/lib/calabash-cucumber/resources/double_tap_ios6_iphone.base64 +22 -0
- data/lib/calabash-cucumber/resources/swipe_down_ios5_iphone.base64 +31 -18
- data/lib/calabash-cucumber/resources/swipe_down_ios6_ipad.base64 +25 -0
- data/lib/calabash-cucumber/resources/swipe_down_ios6_iphone.base64 +25 -0
- data/lib/calabash-cucumber/resources/swipe_left_ios5_iphone.base64 +34 -79
- data/lib/calabash-cucumber/resources/swipe_left_ios6_ipad.base64 +28 -0
- data/lib/calabash-cucumber/resources/swipe_left_ios6_iphone.base64 +28 -0
- data/lib/calabash-cucumber/resources/swipe_right_ios6_ipad.base64 +25 -0
- data/lib/calabash-cucumber/resources/swipe_right_ios6_iphone.base64 +25 -0
- data/lib/calabash-cucumber/resources/swipe_up_ios5_iphone.base64 +28 -34
- data/lib/calabash-cucumber/resources/swipe_up_ios6_ipad.base64 +25 -0
- data/lib/calabash-cucumber/resources/swipe_up_ios6_iphone.base64 +25 -0
- data/lib/calabash-cucumber/resources/touch_hold_ios5_ipad.base64 +9 -0
- data/lib/calabash-cucumber/resources/touch_hold_ios5_iphone.base64 +9 -0
- data/lib/calabash-cucumber/resources/touch_hold_ios6_ipad.base64 +9 -0
- data/lib/calabash-cucumber/resources/touch_hold_ios6_iphone.base64 +9 -0
- data/lib/calabash-cucumber/rotation_helpers.rb +112 -0
- data/lib/calabash-cucumber/status_bar_helpers.rb +30 -0
- data/lib/calabash-cucumber/tests_helpers.rb +3 -42
- data/lib/calabash-cucumber/uia.rb +8 -7
- data/lib/calabash-cucumber/version.rb +2 -2
- data/lib/calabash-cucumber/wait_helpers.rb +19 -2
- metadata +31 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3e77722b47f41850b1ee76e4063c5eb61dacdf3d
|
4
|
+
data.tar.gz: 96dc9a33fd9b98813d4d2c713c83293e9eda4e93
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 47ac9916134d7060524e5329e43ed4134f1e46cdc88f96d3ae87340d256c82d5976eb425107f6ad1c19f8a6a4c6d768a74a6c5d758dceba0263b413690373b52
|
7
|
+
data.tar.gz: 5da6f00ae196bd032de780811b18719308151136d0f0692c039d82003e084fd58b87bb9e64466285bb2862b3902be7b4394b297789fba52c9b3ec2e0d331d690
|
data/calabash-cucumber.gemspec
CHANGED
@@ -26,7 +26,7 @@ Gem::Specification.new do |s|
|
|
26
26
|
s.add_dependency( "geocoder", "~>1.1.8")
|
27
27
|
s.add_dependency( "httpclient","~> 2.3.3")
|
28
28
|
s.add_dependency( "bundler", "~> 1.1")
|
29
|
-
s.add_dependency( "run_loop", "~> 0.1.0.
|
29
|
+
s.add_dependency( "run_loop", "~> 0.1.0.pre5" )
|
30
30
|
s.add_dependency( "awesome_print")
|
31
31
|
s.add_dependency( "xamarin-test-cloud", "~> 0.9.25")
|
32
32
|
|
@@ -0,0 +1,135 @@
|
|
1
|
+
require 'calabash-cucumber/uia'
|
2
|
+
require 'calabash-cucumber/connection_helpers'
|
3
|
+
require 'calabash-cucumber/failure_helpers'
|
4
|
+
require 'calabash-cucumber/query_helpers'
|
5
|
+
require 'calabash-cucumber/map'
|
6
|
+
|
7
|
+
class Calabash::Cucumber::InstrumentsActions
|
8
|
+
include Calabash::Cucumber::UIA
|
9
|
+
include Calabash::Cucumber::ConnectionHelpers
|
10
|
+
include Calabash::Cucumber::FailureHelpers
|
11
|
+
include Calabash::Cucumber::QueryHelpers
|
12
|
+
include Calabash::Cucumber::Map
|
13
|
+
|
14
|
+
def touch(options)
|
15
|
+
query_action(options, :uia_tap_offset)
|
16
|
+
end
|
17
|
+
|
18
|
+
def double_tap(options)
|
19
|
+
query_action(options, :uia_double_tap_offset)
|
20
|
+
end
|
21
|
+
|
22
|
+
def two_finger_tap(options)
|
23
|
+
query_action(options, :uia_two_finger_tap_offset)
|
24
|
+
end
|
25
|
+
|
26
|
+
def flick(options)
|
27
|
+
query_action(options) do |offset|
|
28
|
+
delta = {:offset => options[:delta] || {}}
|
29
|
+
uia_flick_offset(offset, point_from(offset, delta))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
def touch_hold(options)
|
35
|
+
query_action(options) do |offset|
|
36
|
+
duration = options[:duration] || 4
|
37
|
+
uia_touch_hold_offset(duration, offset)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def swipe(dir, options={})
|
42
|
+
options = options.merge(:direction => dir)
|
43
|
+
query_action(options, :uia_swipe_offset, options)
|
44
|
+
end
|
45
|
+
|
46
|
+
def pan(from, to, options={})
|
47
|
+
query_action(:query => from) do |from_offset|
|
48
|
+
query_action(:query => to) do |to_offset|
|
49
|
+
uia_pan_offset(from_offset, to_offset, options)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
def pinch(in_out, options)
|
56
|
+
query_action(options) do |offset|
|
57
|
+
options[:duration] = options[:duration] || 0.5
|
58
|
+
uia_pinch_offset(in_out, offset, options)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def send_app_to_background(secs)
|
63
|
+
uia_send_app_to_background(secs)
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
# Data interface
|
69
|
+
# options[:query] or options[:offset]
|
70
|
+
def query_action(options, action=nil, *args, &block)
|
71
|
+
ui_query = options[:query]
|
72
|
+
offset = options[:offset]
|
73
|
+
if ui_query
|
74
|
+
el = find_and_normalize_or_raise(ui_query)
|
75
|
+
final_offset = point_from(el, options)
|
76
|
+
if block_given?
|
77
|
+
yield final_offset
|
78
|
+
else
|
79
|
+
self.send(action, final_offset, *args)
|
80
|
+
end
|
81
|
+
[el]
|
82
|
+
else
|
83
|
+
##implies offset
|
84
|
+
if block_given?
|
85
|
+
yield offset
|
86
|
+
else
|
87
|
+
self.send(action, offset, *args)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def find_and_normalize_or_raise(ui_query)
|
93
|
+
raw_result = find_or_raise(ui_query)
|
94
|
+
orientation = raw_result['status_bar_orientation']
|
95
|
+
res = raw_result['results'].first
|
96
|
+
|
97
|
+
normalize_rect_for_orientation!(orientation, res['rect']) if res['rect']
|
98
|
+
|
99
|
+
res
|
100
|
+
end
|
101
|
+
|
102
|
+
def find_or_raise(ui_query)
|
103
|
+
raw_result = raw_map(ui_query, :query)
|
104
|
+
if raw_result['results'].empty?
|
105
|
+
screenshot_and_raise "Unable to find element matching query #{ui_query}"
|
106
|
+
else
|
107
|
+
raw_result
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def normalize_rect_for_orientation!(orientation, rect)
|
112
|
+
orientation = orientation.to_sym
|
113
|
+
launcher = Calabash::Cucumber::Launcher.launcher
|
114
|
+
screen_size = launcher.device.screen_size
|
115
|
+
case orientation
|
116
|
+
when :right
|
117
|
+
cx = rect['center_x']
|
118
|
+
rect['center_x'] = rect['center_y']
|
119
|
+
rect['center_y'] = screen_size[:width] - cx
|
120
|
+
when :left
|
121
|
+
cx = rect['center_x']
|
122
|
+
rect['center_x'] = screen_size[:height] - rect['center_y']
|
123
|
+
rect['center_y'] = cx
|
124
|
+
when :up
|
125
|
+
cy = rect['center_y']
|
126
|
+
cx = rect['center_x']
|
127
|
+
rect['center_y'] = screen_size[:height] - cy
|
128
|
+
rect['center_x'] = screen_size[:width] - cx
|
129
|
+
else
|
130
|
+
# no-op by design.
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
|
135
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'calabash-cucumber/connection'
|
2
|
+
require 'calabash-cucumber/playback_helpers'
|
3
|
+
require 'calabash-cucumber/connection_helpers'
|
4
|
+
require 'calabash-cucumber/failure_helpers'
|
5
|
+
require 'calabash-cucumber/query_helpers'
|
6
|
+
|
7
|
+
|
8
|
+
class Calabash::Cucumber::PlaybackActions
|
9
|
+
include Calabash::Cucumber::PlaybackHelpers
|
10
|
+
include Calabash::Cucumber::ConnectionHelpers
|
11
|
+
include Calabash::Cucumber::FailureHelpers
|
12
|
+
include Calabash::Cucumber::QueryHelpers
|
13
|
+
|
14
|
+
|
15
|
+
def touch(options)
|
16
|
+
playback('touch', options)
|
17
|
+
end
|
18
|
+
|
19
|
+
def double_tap(options)
|
20
|
+
playback('double_tap', options)
|
21
|
+
end
|
22
|
+
|
23
|
+
def two_finger_tap(*args)
|
24
|
+
raise error_message('two_finger_tap')
|
25
|
+
end
|
26
|
+
|
27
|
+
def flick(*args)
|
28
|
+
raise error_message('flick')
|
29
|
+
end
|
30
|
+
|
31
|
+
def touch_hold(options)
|
32
|
+
playback('touch_hold', options)
|
33
|
+
end
|
34
|
+
|
35
|
+
def swipe(dir, options={})
|
36
|
+
current_orientation = options[:status_bar_orientation].to_sym
|
37
|
+
if current_orientation == :left
|
38
|
+
case dir
|
39
|
+
when :left then
|
40
|
+
dir = :down
|
41
|
+
when :right then
|
42
|
+
dir = :up
|
43
|
+
when :up then
|
44
|
+
dir = :left
|
45
|
+
when :down then
|
46
|
+
dir = :right
|
47
|
+
else
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
if current_orientation == :right
|
52
|
+
case dir
|
53
|
+
when :left then
|
54
|
+
dir = :up
|
55
|
+
when :right then
|
56
|
+
dir = :down
|
57
|
+
when :up then
|
58
|
+
dir = :right
|
59
|
+
when :down then
|
60
|
+
dir = :left
|
61
|
+
else
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
if current_orientation == :up
|
66
|
+
case dir
|
67
|
+
when :left then
|
68
|
+
dir = :right
|
69
|
+
when :right then
|
70
|
+
dir = :left
|
71
|
+
when :up then
|
72
|
+
dir = :down
|
73
|
+
when :down then
|
74
|
+
dir = :up
|
75
|
+
else
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
playback("swipe_#{dir}", options)
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
def pan(from,to,options={})
|
84
|
+
interpolate 'pan', options.merge(:start => from, :end => to)
|
85
|
+
end
|
86
|
+
|
87
|
+
def pinch(in_out,options)
|
88
|
+
file = "pinch_in"
|
89
|
+
if in_out==:out
|
90
|
+
file = "pinch_out"
|
91
|
+
end
|
92
|
+
playback(file, options)
|
93
|
+
end
|
94
|
+
|
95
|
+
def send_app_to_background(secs)
|
96
|
+
raise 'Not implemented when running without instruments / UIA'
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
private
|
101
|
+
def error_message(gesture)
|
102
|
+
"Gesture: '#{gesture}' not supported unless running with instruments."
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'calabash-cucumber/connection'
|
2
|
+
|
3
|
+
module Calabash
|
4
|
+
module Cucumber
|
5
|
+
module ConnectionHelpers
|
6
|
+
|
7
|
+
def http(*args)
|
8
|
+
connection.http(*args)
|
9
|
+
end
|
10
|
+
|
11
|
+
def connection
|
12
|
+
Calabash::Cucumber::Connection.instance
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -1,21 +1,27 @@
|
|
1
1
|
require 'httpclient'
|
2
|
+
require 'json'
|
2
3
|
require 'geocoder'
|
4
|
+
require 'calabash-cucumber/connection'
|
5
|
+
require 'calabash-cucumber/connection_helpers'
|
3
6
|
require 'calabash-cucumber/launch/simulator_helper'
|
4
7
|
require 'calabash-cucumber/uia'
|
5
|
-
require 'calabash-cucumber/
|
8
|
+
require 'calabash-cucumber/query_helpers'
|
9
|
+
require 'calabash-cucumber/playback_helpers'
|
10
|
+
require 'calabash-cucumber/failure_helpers'
|
11
|
+
require 'calabash-cucumber/status_bar_helpers'
|
12
|
+
require 'calabash-cucumber/rotation_helpers'
|
13
|
+
require 'calabash-cucumber/map'
|
6
14
|
|
7
15
|
module Calabash
|
8
16
|
module Cucumber
|
9
17
|
module Core
|
18
|
+
include Calabash::Cucumber::ConnectionHelpers
|
19
|
+
include Calabash::Cucumber::QueryHelpers
|
20
|
+
include Calabash::Cucumber::FailureHelpers
|
21
|
+
include Calabash::Cucumber::Map
|
10
22
|
include Calabash::Cucumber::UIA
|
11
|
-
include Calabash::Cucumber::
|
12
|
-
|
13
|
-
DATA_PATH = File.expand_path(File.dirname(__FILE__))
|
14
|
-
CAL_HTTP_RETRY_COUNT=3
|
15
|
-
RETRYABLE_ERRORS = [HTTPClient::TimeoutError,
|
16
|
-
HTTPClient::KeepAliveDisconnected,
|
17
|
-
Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::ECONNABORTED,
|
18
|
-
Errno::ETIMEDOUT]
|
23
|
+
include Calabash::Cucumber::StatusBarHelpers
|
24
|
+
include Calabash::Cucumber::RotationHelpers
|
19
25
|
|
20
26
|
|
21
27
|
def macro(txt)
|
@@ -42,25 +48,6 @@ module Calabash
|
|
42
48
|
Calabash::Cucumber::VERSION
|
43
49
|
end
|
44
50
|
|
45
|
-
def perform(*args)
|
46
|
-
if args.length == 1
|
47
|
-
#simple selector
|
48
|
-
hash = args.first
|
49
|
-
q = hash[:on]
|
50
|
-
hash = hash.dup
|
51
|
-
hash.delete(:on)
|
52
|
-
args = [hash]
|
53
|
-
elsif args.length == 2
|
54
|
-
q = args[1][:on]
|
55
|
-
if args[0].is_a? Hash
|
56
|
-
args = [args[0]]
|
57
|
-
else
|
58
|
-
args = args[0]
|
59
|
-
end
|
60
|
-
end
|
61
|
-
map(q, :query, *args)
|
62
|
-
end
|
63
|
-
|
64
51
|
def query_all(uiquery, *args)
|
65
52
|
unless ENV['CALABASH_NO_DEPRECATION'] == '1'
|
66
53
|
puts "query_all is deprecated. Use the new all/visible feature."
|
@@ -69,99 +56,53 @@ module Calabash
|
|
69
56
|
map("all #{uiquery}", :query, *args)
|
70
57
|
end
|
71
58
|
|
72
|
-
|
73
59
|
def touch(uiquery, options={})
|
60
|
+
query_action_with_options(:touch, uiquery, options)
|
61
|
+
end
|
74
62
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
end
|
63
|
+
def double_tap(uiquery, options={})
|
64
|
+
query_action_with_options(:double_tap, uiquery, options)
|
65
|
+
end
|
66
|
+
|
67
|
+
def two_finger_tap(uiquery,options={})
|
68
|
+
query_action_with_options(:two_finger_tap, uiquery, options)
|
69
|
+
end
|
83
70
|
|
84
|
-
|
85
|
-
|
71
|
+
def flick(uiquery, delta, options={})
|
72
|
+
uiquery, options = extract_query_and_options(uiquery, options)
|
73
|
+
options[:delta] = delta
|
74
|
+
views_touched = launcher.actions.flick(options)
|
86
75
|
unless uiquery.nil?
|
87
|
-
screenshot_and_raise "could not find view
|
76
|
+
screenshot_and_raise "flick could not find view: '#{uiquery}', args: #{options}" if views_touched.empty?
|
88
77
|
end
|
89
78
|
views_touched
|
90
79
|
end
|
91
80
|
|
92
|
-
def
|
93
|
-
|
94
|
-
touch_ios7(options)
|
95
|
-
else
|
96
|
-
playback("touch", options)
|
97
|
-
end
|
81
|
+
def touch_hold(uiquery, options={})
|
82
|
+
query_action_with_options(:touch_hold, uiquery, options)
|
98
83
|
end
|
99
84
|
|
100
85
|
def swipe(dir, options={})
|
101
|
-
|
102
|
-
|
103
|
-
swipe_ios7(options.merge(:direction => dir))
|
104
|
-
else
|
105
|
-
current_orientation = status_bar_orientation.to_sym
|
106
|
-
if current_orientation == :left
|
107
|
-
case dir
|
108
|
-
when :left then
|
109
|
-
dir = :down
|
110
|
-
when :right then
|
111
|
-
dir = :up
|
112
|
-
when :up then
|
113
|
-
dir = :left
|
114
|
-
when :down then
|
115
|
-
dir = :right
|
116
|
-
else
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
if current_orientation == :right
|
121
|
-
case dir
|
122
|
-
when :left then
|
123
|
-
dir = :up
|
124
|
-
when :right then
|
125
|
-
dir = :down
|
126
|
-
when :up then
|
127
|
-
dir = :right
|
128
|
-
when :down then
|
129
|
-
dir = :left
|
130
|
-
else
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
if current_orientation == :up
|
135
|
-
case dir
|
136
|
-
when :left then
|
137
|
-
dir = :right
|
138
|
-
when :right then
|
139
|
-
dir = :left
|
140
|
-
when :up then
|
141
|
-
dir = :down
|
142
|
-
when :down then
|
143
|
-
dir = :up
|
144
|
-
else
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
playback("swipe_#{dir}", options)
|
86
|
+
unless uia?
|
87
|
+
options = options.merge(:status_bar_orientation => status_bar_orientation)
|
149
88
|
end
|
89
|
+
launcher.actions.swipe(dir.to_sym, options)
|
150
90
|
end
|
151
91
|
|
152
92
|
def pan(from, to, options={})
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
93
|
+
launcher.actions.pan(from, to, options)
|
94
|
+
end
|
95
|
+
|
96
|
+
def pinch(in_out, options={})
|
97
|
+
launcher.actions.pinch(in_out.to_sym,options)
|
158
98
|
end
|
159
99
|
|
100
|
+
|
160
101
|
def cell_swipe(options={})
|
161
|
-
if
|
162
|
-
raise "cell_swipe not supported
|
102
|
+
if uia?
|
103
|
+
raise "cell_swipe not supported with instruments, simply use swipe with a query that matches the cell"
|
163
104
|
end
|
164
|
-
playback(
|
105
|
+
playback('cell_swipe', options)
|
165
106
|
end
|
166
107
|
|
167
108
|
def scroll(uiquery, direction)
|
@@ -232,159 +173,12 @@ module Calabash
|
|
232
173
|
views_touched
|
233
174
|
end
|
234
175
|
|
235
|
-
def pinch(in_out, options={})
|
236
|
-
in_out = in_out.to_sym
|
237
|
-
if ios7?
|
238
|
-
pinch_ios7(in_out.to_sym, options)
|
239
|
-
else
|
240
|
-
file = "pinch_in"
|
241
|
-
if in_out==:out
|
242
|
-
file = "pinch_out"
|
243
|
-
end
|
244
|
-
playback(file, options)
|
245
|
-
end
|
246
|
-
end
|
247
|
-
|
248
|
-
def rotation_candidates
|
249
|
-
['rotate_left_home_down', 'rotate_left_home_left',
|
250
|
-
'rotate_left_home_right', 'rotate_left_home_up',
|
251
|
-
'rotate_right_home_down', 'rotate_right_home_left',
|
252
|
-
'rotate_right_home_right', 'rotate_right_home_up']
|
253
|
-
end
|
254
|
-
|
255
|
-
# orientations refer to home button position
|
256
|
-
# down ==> bottom
|
257
|
-
# up ==> top
|
258
|
-
# left ==> landscape with left home button AKA: _right_ landscape*
|
259
|
-
# right ==> landscape with right home button AKA: _left_ landscape*
|
260
|
-
#
|
261
|
-
# * see apple documentation for clarification about where the home button
|
262
|
-
# is in left and right landscape orientations
|
263
|
-
def rotate_home_button_to(dir)
|
264
|
-
dir_sym = dir.to_sym
|
265
|
-
if dir_sym.eql?(:top)
|
266
|
-
if ENV['CALABASH_FULL_CONSOLE_OUTPUT'] == '1'
|
267
|
-
warn "converting '#{dir}' to ':up' - please adjust your code"
|
268
|
-
end
|
269
|
-
dir_sym = :up
|
270
|
-
end
|
271
|
-
|
272
|
-
if dir_sym.eql?(:bottom)
|
273
|
-
if ENV['CALABASH_FULL_CONSOLE_OUTPUT'] == '1'
|
274
|
-
warn "converting '#{dir}' to ':down' - please adjust your code"
|
275
|
-
end
|
276
|
-
dir_sym = :down
|
277
|
-
end
|
278
|
-
|
279
|
-
directions = [:down, :up, :left, :right]
|
280
|
-
unless directions.include?(dir_sym)
|
281
|
-
screenshot_and_raise "expected one of '#{directions}' as an arg to 'rotate_home_button_to but found '#{dir}'"
|
282
|
-
end
|
283
|
-
|
284
|
-
res = status_bar_orientation()
|
285
|
-
if res.nil?
|
286
|
-
screenshot_and_raise "expected 'status_bar_orientation' to return a non-nil value"
|
287
|
-
else
|
288
|
-
res = res.to_sym
|
289
|
-
end
|
290
|
-
|
291
|
-
return res if res.eql? dir_sym
|
292
|
-
|
293
|
-
rotation_candidates.each { |candidate|
|
294
|
-
if ENV['CALABASH_FULL_CONSOLE_OUTPUT'] == '1'
|
295
|
-
puts "try to rotate to '#{dir_sym}' using '#{candidate}'"
|
296
|
-
end
|
297
|
-
playback(candidate)
|
298
|
-
# need a longer sleep for cloud testing
|
299
|
-
sleep(0.4)
|
300
|
-
|
301
|
-
res = status_bar_orientation
|
302
|
-
if res.nil?
|
303
|
-
screenshot_and_raise "expected 'status_bar_orientation' to return a non-nil value"
|
304
|
-
else
|
305
|
-
res = res.to_sym
|
306
|
-
end
|
307
|
-
|
308
|
-
return if res.eql? dir_sym
|
309
|
-
}
|
310
|
-
|
311
|
-
if ENV['CALABASH_FULL_CONSOLE_OUTPUT'] == '1'
|
312
|
-
warn "Could not rotate home button to '#{dir}'."
|
313
|
-
warn 'Is rotation enabled for this controller?'
|
314
|
-
warn "Will return 'down'"
|
315
|
-
end
|
316
|
-
:down
|
317
|
-
end
|
318
|
-
|
319
|
-
def device_orientation(force_down=false)
|
320
|
-
res = map(nil, :orientation, :device).first
|
321
|
-
|
322
|
-
if ['face up', 'face down'].include?(res)
|
323
|
-
if ENV['CALABASH_FULL_CONSOLE_OUTPUT'] == '1'
|
324
|
-
if force_down
|
325
|
-
puts "WARN found orientation '#{res}' - will rotate to force orientation to 'down'"
|
326
|
-
end
|
327
|
-
end
|
328
|
-
|
329
|
-
return res if !force_down
|
330
|
-
return rotate_home_button_to :down
|
331
|
-
end
|
332
|
-
|
333
|
-
return res if !res.eql?('unknown')
|
334
|
-
return res if !force_down
|
335
|
-
rotate_home_button_to(:down)
|
336
|
-
end
|
337
|
-
|
338
|
-
def status_bar_orientation
|
339
|
-
map(nil, :orientation, :status_bar).first
|
340
|
-
end
|
341
|
-
|
342
|
-
def rotate(dir)
|
343
|
-
dir = dir.to_sym
|
344
|
-
current_orientation = status_bar_orientation().to_sym
|
345
|
-
rotate_cmd = nil
|
346
|
-
case dir
|
347
|
-
when :left then
|
348
|
-
if current_orientation == :down
|
349
|
-
rotate_cmd = "left_home_down"
|
350
|
-
elsif current_orientation == :right
|
351
|
-
rotate_cmd = "left_home_right"
|
352
|
-
elsif current_orientation == :left
|
353
|
-
rotate_cmd = "left_home_left"
|
354
|
-
elsif current_orientation == :up
|
355
|
-
rotate_cmd = "left_home_up"
|
356
|
-
end
|
357
|
-
when :right then
|
358
|
-
if current_orientation == :down
|
359
|
-
rotate_cmd = "right_home_down"
|
360
|
-
elsif current_orientation == :left
|
361
|
-
rotate_cmd = "right_home_left"
|
362
|
-
elsif current_orientation == :right
|
363
|
-
rotate_cmd = "right_home_right"
|
364
|
-
elsif current_orientation == :up
|
365
|
-
rotate_cmd = "right_home_up"
|
366
|
-
end
|
367
|
-
end
|
368
|
-
|
369
|
-
if rotate_cmd.nil?
|
370
|
-
if ENV['CALABASH_FULL_CONSOLE_OUTPUT'] == '1'
|
371
|
-
puts "Could not rotate device in direction '#{dir}' with orientation '#{current_orientation} - will do nothing"
|
372
|
-
end
|
373
|
-
else
|
374
|
-
playback("rotate_#{rotate_cmd}")
|
375
|
-
end
|
376
|
-
end
|
377
|
-
|
378
176
|
def send_app_to_background(secs)
|
379
|
-
|
380
|
-
end
|
381
|
-
|
382
|
-
def console_attach
|
383
|
-
Calabash::Cucumber::Launcher.attach
|
177
|
+
launcher.actions.send_app_to_background(secs)
|
384
178
|
end
|
385
179
|
|
386
180
|
def set_location(options)
|
387
|
-
if
|
181
|
+
if uia?
|
388
182
|
uia_set_location(options)
|
389
183
|
else
|
390
184
|
if options[:place]
|
@@ -471,217 +265,6 @@ module Calabash
|
|
471
265
|
texts
|
472
266
|
end
|
473
267
|
|
474
|
-
def recording_name_for(recording_name, os, device)
|
475
|
-
if !recording_name.end_with? ".base64"
|
476
|
-
"#{recording_name}_#{os}_#{device}.base64"
|
477
|
-
else
|
478
|
-
recording_name
|
479
|
-
end
|
480
|
-
end
|
481
|
-
|
482
|
-
def load_recording(recording, rec_dir)
|
483
|
-
directories = playback_file_directories(rec_dir)
|
484
|
-
directories.each { |dir|
|
485
|
-
path = "#{dir}/#{recording}"
|
486
|
-
if File.exists?(path)
|
487
|
-
# useful for debugging recordings, but too verbose for release
|
488
|
-
# suggest (yet) another variable CALABASH_DEBUG_PLAYBACK ?
|
489
|
-
#if ENV['CALABASH_FULL_CONSOLE_OUTPUT'] == '1'
|
490
|
-
# puts "found compatible playback: '#{path}'"
|
491
|
-
#end
|
492
|
-
return File.read(path)
|
493
|
-
end
|
494
|
-
}
|
495
|
-
nil
|
496
|
-
end
|
497
|
-
|
498
|
-
def playback_file_directories (rec_dir)
|
499
|
-
# rec_dir is either ENV['PLAYBACK_DIR'] or ./features/playback
|
500
|
-
[File.expand_path(rec_dir),
|
501
|
-
"#{Dir.pwd}",
|
502
|
-
"#{Dir.pwd}/features",
|
503
|
-
"#{Dir.pwd}/features/playback",
|
504
|
-
"#{DATA_PATH}/resources/"].uniq
|
505
|
-
end
|
506
|
-
|
507
|
-
def load_playback_data(recording_name, options={})
|
508
|
-
os = options["OS"] || ENV["OS"]
|
509
|
-
device = options["DEVICE"] || ENV["DEVICE"] || "iphone"
|
510
|
-
|
511
|
-
unless os
|
512
|
-
if @calabash_launcher && @calabash_launcher.active?
|
513
|
-
major = @calabash_launcher.ios_major_version
|
514
|
-
else
|
515
|
-
major = Calabash::Cucumber::SimulatorHelper.ios_major_version
|
516
|
-
end
|
517
|
-
|
518
|
-
unless major
|
519
|
-
raise <<EOF
|
520
|
-
Unable to determine iOS major version
|
521
|
-
Most likely you have updated your calabash-cucumber client
|
522
|
-
but not your server. Please follow closely:
|
523
|
-
|
524
|
-
https://github.com/calabash/calabash-ios/wiki/B1-Updating-your-Calabash-iOS-version
|
525
|
-
|
526
|
-
If you are running version 0.9.120+ then please report this message as a bug.
|
527
|
-
EOF
|
528
|
-
end
|
529
|
-
os = "ios#{major}"
|
530
|
-
end
|
531
|
-
|
532
|
-
rec_dir = ENV['PLAYBACK_DIR'] || "#{Dir.pwd}/features/playback"
|
533
|
-
|
534
|
-
candidates = []
|
535
|
-
data = find_compatible_recording(recording_name, os, rec_dir, device, candidates)
|
536
|
-
|
537
|
-
if data.nil? and device=='ipad'
|
538
|
-
if ENV['CALABASH_FULL_CONSOLE_OUTPUT'] == '1'
|
539
|
-
puts "Unable to find recording for #{os} and #{device}. Trying with #{os} iphone"
|
540
|
-
end
|
541
|
-
data = find_compatible_recording(recording_name, os, rec_dir, 'iphone', candidates)
|
542
|
-
end
|
543
|
-
|
544
|
-
if data.nil?
|
545
|
-
searched_for = " searched for => \n"
|
546
|
-
candidates.each { |file| searched_for.concat(" * '#{file}'\n") }
|
547
|
-
searched_in = " in directories =>\n"
|
548
|
-
playback_file_directories(rec_dir).each { |dir| searched_in.concat(" * '#{dir}'\n") }
|
549
|
-
screenshot_and_raise "Playback file not found for: '#{recording_name}'\n#{searched_for}#{searched_in}"
|
550
|
-
end
|
551
|
-
|
552
|
-
data
|
553
|
-
end
|
554
|
-
|
555
|
-
def find_compatible_recording (recording_name, os, rec_dir, device, candidates)
|
556
|
-
recording = recording_name_for(recording_name, os, device)
|
557
|
-
data = load_recording(recording, rec_dir)
|
558
|
-
if data.nil?
|
559
|
-
candidates << recording
|
560
|
-
version_counter = os[-1, 1].to_i
|
561
|
-
loop do
|
562
|
-
version_counter = version_counter - 1
|
563
|
-
break if version_counter < 5
|
564
|
-
loop_os = "ios#{version_counter}"
|
565
|
-
recording = recording_name_for(recording_name, loop_os, device)
|
566
|
-
candidates << recording
|
567
|
-
data = load_recording(recording, rec_dir)
|
568
|
-
break if !data.nil?
|
569
|
-
end
|
570
|
-
end
|
571
|
-
data
|
572
|
-
end
|
573
|
-
|
574
|
-
def playback(recording, options={})
|
575
|
-
data = load_playback_data(recording)
|
576
|
-
|
577
|
-
post_data = %Q|{"events":"#{data}"|
|
578
|
-
post_data<< %Q|,"query":"#{escape_quotes(options[:query])}"| if options[:query]
|
579
|
-
post_data<< %Q|,"offset":#{options[:offset].to_json}| if options[:offset]
|
580
|
-
post_data<< %Q|,"reverse":#{options[:reverse]}| if options[:reverse]
|
581
|
-
post_data<< %Q|,"uia_gesture":"#{options[:uia_gesture]}"| if options[:uia_gesture]
|
582
|
-
post_data<< %Q|,"prototype":"#{options[:prototype]}"| if options[:prototype]
|
583
|
-
post_data << "}"
|
584
|
-
|
585
|
-
res = http({:method => :post, :raw => true, :path => 'play'}, post_data)
|
586
|
-
|
587
|
-
res = JSON.parse(res)
|
588
|
-
if res['outcome'] != 'SUCCESS'
|
589
|
-
screenshot_and_raise "playback failed because: #{res['reason']}\n#{res['details']}"
|
590
|
-
end
|
591
|
-
res['results']
|
592
|
-
end
|
593
|
-
|
594
|
-
def interpolate(recording, options={})
|
595
|
-
data = load_playback_data(recording)
|
596
|
-
|
597
|
-
post_data = %Q|{"events":"#{data}"|
|
598
|
-
post_data<< %Q|,"start":"#{escape_quotes(options[:start])}"| if options[:start]
|
599
|
-
post_data<< %Q|,"end":"#{escape_quotes(options[:end])}"| if options[:end]
|
600
|
-
post_data<< %Q|,"offset_start":#{options[:offset_start].to_json}| if options[:offset_start]
|
601
|
-
post_data<< %Q|,"offset_end":#{options[:offset_end].to_json}| if options[:offset_end]
|
602
|
-
post_data << "}"
|
603
|
-
|
604
|
-
res = http({:method => :post, :raw => true, :path => 'interpolate'}, post_data)
|
605
|
-
|
606
|
-
res = JSON.parse(res)
|
607
|
-
if res['outcome'] != 'SUCCESS'
|
608
|
-
screenshot_and_raise "interpolate failed because: #{res['reason']}\n#{res['details']}"
|
609
|
-
end
|
610
|
-
res['results']
|
611
|
-
end
|
612
|
-
|
613
|
-
def record_begin
|
614
|
-
http({:method => :post, :path => 'record'}, {:action => :start})
|
615
|
-
end
|
616
|
-
|
617
|
-
def record_end(file_name)
|
618
|
-
res = http({:method => :post, :path => 'record'}, {:action => :stop})
|
619
|
-
File.open("_recording.plist", 'wb') do |f|
|
620
|
-
f.write res
|
621
|
-
end
|
622
|
-
|
623
|
-
device = ENV['DEVICE'] || 'iphone'
|
624
|
-
os = ENV['OS']
|
625
|
-
|
626
|
-
unless os
|
627
|
-
if @calabash_launcher && @calabash_launcher.active?
|
628
|
-
major = @calabash_launcher.ios_major_version
|
629
|
-
else
|
630
|
-
major = Calabash::Cucumber::SimulatorHelper.ios_major_version
|
631
|
-
end
|
632
|
-
|
633
|
-
unless major
|
634
|
-
raise <<EOF
|
635
|
-
Unable to determine iOS major version
|
636
|
-
Most likely you have updated your calabash-cucumber client
|
637
|
-
but not your server. Please follow closely:
|
638
|
-
|
639
|
-
https://github.com/calabash/calabash-ios/wiki/B1-Updating-your-Calabash-iOS-version
|
640
|
-
|
641
|
-
If you are running version 0.9.120+ then please report this message as a bug.
|
642
|
-
EOF
|
643
|
-
end
|
644
|
-
os = "ios#{major}"
|
645
|
-
end
|
646
|
-
|
647
|
-
file_name = "#{file_name}_#{os}_#{device}.base64"
|
648
|
-
system("/usr/bin/plutil -convert binary1 -o _recording_binary.plist _recording.plist")
|
649
|
-
system("openssl base64 -in _recording_binary.plist -out '#{file_name}'")
|
650
|
-
system("rm _recording.plist _recording_binary.plist")
|
651
|
-
|
652
|
-
rec_dir = ENV['PLAYBACK_DIR'] || "#{Dir.pwd}/features/playback"
|
653
|
-
unless File.directory?(rec_dir)
|
654
|
-
if ENV['CALABASH_FULL_CONSOLE_OUTPUT'] == '1'
|
655
|
-
puts "creating playback directory at '#{rec_dir}'"
|
656
|
-
end
|
657
|
-
system("mkdir -p #{rec_dir}")
|
658
|
-
end
|
659
|
-
|
660
|
-
system("mv #{file_name} #{rec_dir}")
|
661
|
-
"#{file_name} ==> '#{rec_dir}/#{file_name}'"
|
662
|
-
|
663
|
-
end
|
664
|
-
|
665
|
-
def point_from(query_result, options)
|
666
|
-
offset_x = 0
|
667
|
-
offset_y = 0
|
668
|
-
if options[:offset]
|
669
|
-
offset_x += options[:offset][:x] || 0
|
670
|
-
offset_y += options[:offset][:y] || 0
|
671
|
-
end
|
672
|
-
x = offset_x
|
673
|
-
y = offset_y
|
674
|
-
rect = query_result["rect"] || query_result[:rect]
|
675
|
-
if rect
|
676
|
-
x += rect['center_x'] || rect[:center_x] || rect[:x] || 0
|
677
|
-
y += rect['center_y'] || rect[:center_y] || rect[:y] || 0
|
678
|
-
else
|
679
|
-
x += query_result['center_x'] || query_result[:center_x] || query_result[:x] || 0
|
680
|
-
y += query_result['center_y'] || query_result[:center_y] || query_result[:y] || 0
|
681
|
-
end
|
682
|
-
|
683
|
-
{:x => x, :y => y}
|
684
|
-
end
|
685
268
|
|
686
269
|
def backdoor(sel, arg)
|
687
270
|
json = {
|
@@ -701,28 +284,12 @@ EOF
|
|
701
284
|
# or HTTPClient::KeepAliveDisconnected
|
702
285
|
# which needs to be suppressed.
|
703
286
|
begin
|
704
|
-
http({:method => :post, :path => 'exit', :retryable_errors => RETRYABLE_ERRORS - [Errno::ECONNREFUSED, HTTPClient::KeepAliveDisconnected]})
|
287
|
+
http({:method => :post, :path => 'exit', :retryable_errors => Calabash::Cucumber::HTTPHelpers::RETRYABLE_ERRORS - [Errno::ECONNREFUSED, HTTPClient::KeepAliveDisconnected]})
|
705
288
|
rescue Errno::ECONNREFUSED, HTTPClient::KeepAliveDisconnected
|
706
289
|
[]
|
707
290
|
end
|
708
291
|
end
|
709
292
|
|
710
|
-
def map(query, method_name, *method_args)
|
711
|
-
operation_map = {
|
712
|
-
:method_name => method_name,
|
713
|
-
:arguments => method_args
|
714
|
-
}
|
715
|
-
res = http({:method => :post, :path => 'map'},
|
716
|
-
{:query => query, :operation => operation_map})
|
717
|
-
res = JSON.parse(res)
|
718
|
-
if res['outcome'] != 'SUCCESS'
|
719
|
-
screenshot_and_raise "map #{query}, #{method_name} failed because: #{res['reason']}\n#{res['details']}"
|
720
|
-
end
|
721
|
-
|
722
|
-
res['results']
|
723
|
-
end
|
724
|
-
|
725
|
-
|
726
293
|
## args :app for device bundle id, for sim path to app
|
727
294
|
##
|
728
295
|
def start_test_server_in_background(args={})
|
@@ -733,9 +300,8 @@ EOF
|
|
733
300
|
end
|
734
301
|
|
735
302
|
def stop_test_server
|
736
|
-
|
737
|
-
|
738
|
-
end
|
303
|
+
l = @calabash_launcher || Calabash::Cucumber::Launcher.launcher_if_used
|
304
|
+
l.stop if l
|
739
305
|
end
|
740
306
|
|
741
307
|
def shutdown_test_server
|
@@ -744,90 +310,51 @@ EOF
|
|
744
310
|
end
|
745
311
|
|
746
312
|
def default_device
|
747
|
-
|
313
|
+
l = Calabash::Cucumber::Launcher.launcher_if_used
|
314
|
+
l && l.device
|
748
315
|
end
|
749
316
|
|
750
|
-
|
751
|
-
|
752
|
-
options[:uri] = url_for(options[:path])
|
753
|
-
options[:method] = options[:method] || :get
|
754
|
-
if data
|
755
|
-
if options[:raw]
|
756
|
-
options[:body] = data
|
757
|
-
else
|
758
|
-
options[:body] = data.to_json
|
759
|
-
end
|
760
|
-
end
|
761
|
-
res = make_http_request(options)
|
762
|
-
res.force_encoding("UTF-8") if res.respond_to?(:force_encoding)
|
763
|
-
res
|
317
|
+
def uia?
|
318
|
+
Calabash::Cucumber::Launcher.instruments?
|
764
319
|
end
|
765
320
|
|
766
|
-
|
767
|
-
|
768
|
-
url = URI.parse(ENV['DEVICE_ENDPOINT']|| "http://localhost:37265")
|
769
|
-
path = url.path
|
770
|
-
if path.end_with? "/"
|
771
|
-
path = "#{path}#{verb}"
|
772
|
-
else
|
773
|
-
path = "#{path}/#{verb}"
|
774
|
-
end
|
775
|
-
url.path = path
|
776
|
-
url
|
321
|
+
def console_attach
|
322
|
+
launcher.attach
|
777
323
|
end
|
778
324
|
|
779
|
-
def
|
325
|
+
def launcher
|
326
|
+
Calabash::Cucumber::Launcher.launcher
|
327
|
+
end
|
780
328
|
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
@http = init_request(options)
|
787
|
-
end
|
788
|
-
if options[:method] == :post
|
789
|
-
body = @http.post(options[:uri], options[:body]).body
|
790
|
-
else
|
791
|
-
body = @http.get(options[:uri], options[:body]).body
|
792
|
-
end
|
793
|
-
break
|
794
|
-
rescue Exception => e
|
795
|
-
|
796
|
-
if retryable_errors.include?(e) || retryable_errors.any? { |c| e.is_a?(c) }
|
797
|
-
|
798
|
-
if count < CAL_HTTP_RETRY_COUNT-1
|
799
|
-
if e.is_a?(HTTPClient::TimeoutError)
|
800
|
-
sleep(3)
|
801
|
-
else
|
802
|
-
sleep(0.5)
|
803
|
-
end
|
804
|
-
@http.reset_all
|
805
|
-
@http=nil
|
806
|
-
STDOUT.write "Retrying.. #{e.class}: (#{e})\n"
|
807
|
-
STDOUT.flush
|
808
|
-
else
|
809
|
-
puts "Failing... #{e.class}"
|
810
|
-
raise e
|
811
|
-
end
|
812
|
-
else
|
813
|
-
raise e
|
814
|
-
end
|
815
|
-
end
|
329
|
+
def query_action_with_options(action, uiquery, options)
|
330
|
+
uiquery, options = extract_query_and_options(uiquery, options)
|
331
|
+
views_touched = launcher.actions.send(action, options)
|
332
|
+
unless uiquery.nil?
|
333
|
+
screenshot_and_raise "#{action} could not find view: '#{uiquery}', args: #{options}" if views_touched.empty?
|
816
334
|
end
|
335
|
+
views_touched
|
336
|
+
end
|
817
337
|
|
818
|
-
|
338
|
+
def extract_query_and_options(uiquery, options)
|
339
|
+
options = prepare_query_options(uiquery, options)
|
340
|
+
return options[:query], options
|
819
341
|
end
|
820
342
|
|
821
|
-
def
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
343
|
+
def prepare_query_options(uiquery, options)
|
344
|
+
opts = options.dup
|
345
|
+
if (uiquery.is_a?(Array))
|
346
|
+
raise 'No elements in array' if uiquery.empty?
|
347
|
+
uiquery = uiquery.first
|
348
|
+
end #this is deliberately not elsif (uiquery.first could be a hash)
|
349
|
+
|
350
|
+
if (uiquery.is_a?(Hash))
|
351
|
+
opts[:offset] = point_from(uiquery, options)
|
352
|
+
uiquery = nil
|
828
353
|
end
|
829
|
-
|
354
|
+
opts[:query] = uiquery
|
355
|
+
opts
|
830
356
|
end
|
357
|
+
|
831
358
|
end
|
832
359
|
end
|
833
360
|
end
|