calabash-cucumber 0.20.0 → 0.20.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/dylibs/libCalabashDyn.dylib +0 -0
- data/dylibs/libCalabashDynSim.dylib +0 -0
- data/lib/calabash-cucumber/automator/automator.rb +24 -0
- data/lib/calabash-cucumber/automator/device_agent.rb +81 -20
- data/lib/calabash-cucumber/console_helpers.rb +16 -1
- data/lib/calabash-cucumber/core.rb +306 -84
- data/lib/calabash-cucumber/device.rb +6 -0
- data/lib/calabash-cucumber/device_agent.rb +9 -23
- data/lib/calabash-cucumber/environment_helpers.rb +8 -0
- data/lib/calabash-cucumber/keyboard_helpers.rb +13 -8
- data/lib/calabash-cucumber/launcher.rb +36 -19
- data/lib/calabash-cucumber/map.rb +1 -1
- data/lib/calabash-cucumber/usage_tracker.rb +4 -1
- data/lib/calabash-cucumber/version.rb +2 -2
- data/scripts/.irbrc +1 -0
- data/staticlib/calabash.framework.zip +0 -0
- data/staticlib/libFrankCalabash.a +0 -0
- metadata +20 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5d80bc583ef0ea5ae3fb6548acd4d5ced7f15b2c
|
4
|
+
data.tar.gz: 61431194a8a83d91b41674c2d5ec6f83076b92fa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b9e3bbb6993f444dfd6a9e83e8e4de9d9c2b48080a820c71032967755366eb984de455bac2bfce9fe18a823050a482c8cdf937c56e1e8ae6cfc592b8047fcc8
|
7
|
+
data.tar.gz: c25c2390ba6e3b3542bfa5e5a1c5cad9dfc6ad73fea899405f2aacc8b25d09b817a3f92dee5a1285cd8a67044ee7b189730bb67c20fc8c9c439c115c6bb1a0af
|
data/dylibs/libCalabashDyn.dylib
CHANGED
Binary file
|
Binary file
|
@@ -34,6 +34,28 @@ module Calabash
|
|
34
34
|
abstract_method!
|
35
35
|
end
|
36
36
|
|
37
|
+
# @!visibility private
|
38
|
+
#
|
39
|
+
# This code is redundant. It would be easy to pass the Launcher
|
40
|
+
# device instance to the automator, but that would require an XTC patch.
|
41
|
+
#
|
42
|
+
# This code is also duplicated in the EnvironmentHelpers.
|
43
|
+
#
|
44
|
+
# We need the device screen size to support full-screen pan gestures.
|
45
|
+
#
|
46
|
+
# Asking for the top-most view is not good enough and asking for the
|
47
|
+
# largest UIWindow is not specific enough (map apps have a huge window).
|
48
|
+
def device
|
49
|
+
@device ||= begin
|
50
|
+
require "calabash-cucumber/http/http"
|
51
|
+
require "calabash-cucumber/environment"
|
52
|
+
require "calabash-cucumber/device"
|
53
|
+
_, body = Calabash::Cucumber::HTTP.ensure_connectivity
|
54
|
+
endpoint = Calabash::Cucumber::Environment.device_endpoint
|
55
|
+
Calabash::Cucumber::Device.new(endpoint, body)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
37
59
|
# @!visibility private
|
38
60
|
def touch(options)
|
39
61
|
abstract_method!
|
@@ -79,6 +101,8 @@ module Calabash
|
|
79
101
|
end
|
80
102
|
|
81
103
|
# @!visibility private
|
104
|
+
#
|
105
|
+
# Callers must validate the options.
|
82
106
|
def pinch(in_or_out, options)
|
83
107
|
abstract_method!
|
84
108
|
end
|
@@ -130,13 +130,14 @@ args[0] = #{args[0]}])
|
|
130
130
|
dupped_options = options.dup
|
131
131
|
|
132
132
|
if dupped_options[:query].nil?
|
133
|
-
|
133
|
+
element = element_for_device_screen
|
134
|
+
from_point = point_from(element, options)
|
135
|
+
else
|
136
|
+
hash = query_for_coordinates(dupped_options)
|
137
|
+
from_point = hash[:coordinates]
|
138
|
+
element = hash[:view]
|
134
139
|
end
|
135
140
|
|
136
|
-
hash = query_for_coordinates(dupped_options)
|
137
|
-
from_point = hash[:coordinates]
|
138
|
-
element = hash[:view]
|
139
|
-
|
140
141
|
# DeviceAgent does not understand the :force. Does anyone?
|
141
142
|
force = dupped_options[:force]
|
142
143
|
case force
|
@@ -158,7 +159,38 @@ args[0] = #{args[0]}])
|
|
158
159
|
direction = dupped_options[:direction]
|
159
160
|
to_point = Coordinates.end_point_for_swipe(direction, element, force)
|
160
161
|
client.pan_between_coordinates(from_point, to_point, gesture_options)
|
161
|
-
[
|
162
|
+
[element]
|
163
|
+
end
|
164
|
+
|
165
|
+
# @!visibility private
|
166
|
+
def pinch(in_out, options)
|
167
|
+
dupped_options = options.dup
|
168
|
+
|
169
|
+
if dupped_options[:query].nil?
|
170
|
+
element = element_for_device_screen
|
171
|
+
coordinates = point_from(element, options)
|
172
|
+
else
|
173
|
+
hash = query_for_coordinates(dupped_options)
|
174
|
+
element = hash[:view]
|
175
|
+
coordinates = hash[:coordinates]
|
176
|
+
end
|
177
|
+
|
178
|
+
in_out = in_out.to_s
|
179
|
+
duration = dupped_options[:duration]
|
180
|
+
amount = dupped_options[:amount]
|
181
|
+
|
182
|
+
gesture_options = {
|
183
|
+
:pinch_direction => in_out,
|
184
|
+
:amount => amount,
|
185
|
+
:duration => duration
|
186
|
+
}
|
187
|
+
|
188
|
+
client.perform_coordinate_gesture("pinch",
|
189
|
+
coordinates[:x],
|
190
|
+
coordinates[:y],
|
191
|
+
gesture_options)
|
192
|
+
|
193
|
+
[element]
|
162
194
|
end
|
163
195
|
|
164
196
|
# @!visibility private
|
@@ -223,12 +255,12 @@ args[0] = #{args[0]}])
|
|
223
255
|
|
224
256
|
# @!visibility private
|
225
257
|
def enter_text_with_keyboard(string, options={})
|
226
|
-
client.
|
258
|
+
client.enter_text_without_keyboard_check(string)
|
227
259
|
end
|
228
260
|
|
229
261
|
# @!visibility private
|
230
262
|
def enter_char_with_keyboard(char)
|
231
|
-
client.
|
263
|
+
client.enter_text_without_keyboard_check(char)
|
232
264
|
end
|
233
265
|
|
234
266
|
# @!visibility private
|
@@ -242,7 +274,7 @@ args[0] = #{args[0]}])
|
|
242
274
|
if mark
|
243
275
|
begin
|
244
276
|
# The underlying query for coordinates always expects results.
|
245
|
-
value = client.touch({marked: mark})
|
277
|
+
value = client.touch({type: "Button", marked: mark})
|
246
278
|
return value
|
247
279
|
rescue RuntimeError => _
|
248
280
|
RunLoop.log_debug("Cannot find mark '#{mark}' with query; will send a newline")
|
@@ -252,7 +284,7 @@ args[0] = #{args[0]}])
|
|
252
284
|
end
|
253
285
|
|
254
286
|
code = char_for_keyboard_action("Return")
|
255
|
-
client.
|
287
|
+
client.enter_text_without_keyboard_check(code)
|
256
288
|
end
|
257
289
|
|
258
290
|
# @!visibility private
|
@@ -262,7 +294,7 @@ args[0] = #{args[0]}])
|
|
262
294
|
|
263
295
|
# @!visibility private
|
264
296
|
def fast_enter_text(text)
|
265
|
-
client.
|
297
|
+
client.enter_text_without_keyboard_check(text)
|
266
298
|
end
|
267
299
|
|
268
300
|
# @!visibility private
|
@@ -353,6 +385,27 @@ Make sure your query returns at least one view.
|
|
353
385
|
end
|
354
386
|
end
|
355
387
|
|
388
|
+
# @!visibility private
|
389
|
+
def element_for_device_screen
|
390
|
+
screen_dimensions = device.screen_dimensions
|
391
|
+
|
392
|
+
scale = screen_dimensions[:scale]
|
393
|
+
height = (screen_dimensions[:height]/scale).to_i
|
394
|
+
center_y = (height/2)
|
395
|
+
width = (screen_dimensions[:width]/scale).to_i
|
396
|
+
center_x = (width/2)
|
397
|
+
|
398
|
+
{
|
399
|
+
"screen" => true,
|
400
|
+
"rect" => {
|
401
|
+
"height" => height,
|
402
|
+
"width" => width,
|
403
|
+
"center_x" => center_x,
|
404
|
+
"center_y" => center_y
|
405
|
+
}
|
406
|
+
}
|
407
|
+
end
|
408
|
+
|
356
409
|
# @!visibility private
|
357
410
|
#
|
358
411
|
# Don't change the double quotes.
|
@@ -400,17 +453,25 @@ Make sure your query returns at least one view.
|
|
400
453
|
# @!visibility private
|
401
454
|
def return_key_type_of_first_responder
|
402
455
|
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
456
|
+
query = "* isFirstResponder:1"
|
457
|
+
raw = Calabash::Cucumber::Map.raw_map(query, :query, :returnKeyType)
|
458
|
+
elements = raw["results"]
|
459
|
+
return nil if elements.count == 0
|
460
|
+
|
461
|
+
return_key_type = elements[0]
|
462
|
+
|
463
|
+
# first responder did not respond to :text selector
|
464
|
+
if return_key_type == "*****"
|
465
|
+
RunLoop.log_debug("First responder does not respond to :returnKeyType")
|
466
|
+
return nil
|
467
|
+
end
|
468
|
+
|
469
|
+
if return_key_type.nil?
|
470
|
+
RunLoop.log_debug("First responder has nil :returnKeyType")
|
471
|
+
return nil
|
410
472
|
end
|
411
473
|
|
412
|
-
|
413
|
-
nil
|
474
|
+
return_key_type
|
414
475
|
end
|
415
476
|
|
416
477
|
# @!visibility private
|
@@ -102,7 +102,9 @@ module Calabash
|
|
102
102
|
"Uti, non abuti.",
|
103
103
|
"Non Satis Scire",
|
104
104
|
"Nullius in verba",
|
105
|
-
"Det ka æn jå væer ei jált"
|
105
|
+
"Det ka æn jå væer ei jált",
|
106
|
+
"Dzień dobry",
|
107
|
+
"Jestem tu by ocalić świat"
|
106
108
|
]
|
107
109
|
puts RunLoop::Color.green("Calabash says, \"#{messages.shuffle.first}\"")
|
108
110
|
end
|
@@ -148,6 +150,19 @@ module Calabash
|
|
148
150
|
puts ""
|
149
151
|
end
|
150
152
|
|
153
|
+
# @!visibility private
|
154
|
+
# Do not call this method directly.
|
155
|
+
def _try_to_attach
|
156
|
+
begin
|
157
|
+
Calabash::Cucumber::HTTP.ping_app
|
158
|
+
launcher = Calabash::Cucumber::Launcher.new
|
159
|
+
launcher.attach
|
160
|
+
puts(RunLoop::Color.green("Attached to: #{launcher}"))
|
161
|
+
launcher
|
162
|
+
rescue => _
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
151
166
|
private
|
152
167
|
|
153
168
|
# List the visible element with given mark(s).
|
@@ -382,13 +382,13 @@ Expected: options[:offset] = {:x => NUMERIC, :y => NUMERIC}
|
|
382
382
|
# @option options {Hash} :offset (nil) optional offset to touch point.
|
383
383
|
# Offset supports an `:x` and `:y` key and causes the touch to be
|
384
384
|
# offset with `(x,y)` relative to the center.
|
385
|
-
# @option options {String} :query (nil) If specified, the swipe will be
|
386
|
-
# made on the first view matching this query. If this option is nil
|
387
|
-
# (the default), the swipe will happen on the first view matched by "*".
|
388
385
|
# @option options [Symbol] :force (normal) Indicates the force of the
|
389
386
|
# swipe. Valid values are :strong, :normal, :light.
|
387
|
+
# @option options {String} :query (nil) If specified, the swipe will be
|
388
|
+
# made on the first view matching this query. If this option is nil
|
389
|
+
# (the default), the swipe will happen at the center of the screen.
|
390
390
|
#
|
391
|
-
# @return {Array<Hash
|
391
|
+
# @return {Array<Hash>} An array with one element; the view that
|
392
392
|
# was swiped.
|
393
393
|
#
|
394
394
|
# @raise [ArgumentError] If :force is invalid.
|
@@ -584,20 +584,70 @@ The minimum duration is 0.0.
|
|
584
584
|
end
|
585
585
|
|
586
586
|
# Performs a "pinch" gesture.
|
587
|
+
#
|
587
588
|
# By default, the gesture starts at the center of the screen.
|
588
|
-
#
|
589
|
+
#
|
589
590
|
# @example
|
591
|
+
# # Zoom in
|
590
592
|
# pinch :out
|
591
|
-
#
|
593
|
+
#
|
594
|
+
# # Zoom out
|
592
595
|
# pinch :in, query:"MKMapView", offset:{x:42}
|
593
|
-
#
|
596
|
+
#
|
597
|
+
# @param {String, Symbol} in_out the direction to pinch ('in' or 'out')
|
594
598
|
# @param {Hash} options option for modifying the details of the touch.
|
595
|
-
# @option options {Hash} :offset (nil) optional offset to touch point.
|
596
|
-
#
|
597
|
-
#
|
598
|
-
# @
|
599
|
+
# @option options {Hash} :offset (nil) optional offset to touch point.
|
600
|
+
# @option options {String} :query (nil) The view to pinch on. If this
|
601
|
+
# value is nil, the pinch happens at the center of the screen.
|
602
|
+
# @option options {Numeric} :amount (100) How large (in points) the
|
603
|
+
# pinch should be. This option is ignored when running with UIAutomation.
|
604
|
+
# @option options {Numeric} :duration (1.0) duration of the 'pinch'. The
|
605
|
+
# minimum value of pan in UIAutomation is 0.5. For DeviceAgent, the
|
606
|
+
# duration must be > 0.
|
607
|
+
# @return {Array<Hash>} array containing the serialized version of
|
608
|
+
# the view touched.
|
609
|
+
#
|
610
|
+
# @raise [ArgumentError] If duration is < 0.5 for UIAutomation and <= 0
|
611
|
+
# for DeviceAgent.
|
612
|
+
# @raise [ArgumentError] If in_out argument is invalid.
|
599
613
|
def pinch(in_out, options={})
|
600
|
-
|
614
|
+
merged_options = {
|
615
|
+
:query => nil,
|
616
|
+
# Ignored by UIAutomation
|
617
|
+
:amount => 100,
|
618
|
+
:duration => 0.5
|
619
|
+
}.merge(options)
|
620
|
+
|
621
|
+
symbol = in_out.to_sym
|
622
|
+
|
623
|
+
if ![:in, :out].include?(symbol)
|
624
|
+
raise ArgumentError, %Q[
|
625
|
+
Invalid pinch direction: '#{symbol}'. Valid directions are:
|
626
|
+
|
627
|
+
"in", "out", :in, :out
|
628
|
+
|
629
|
+
]
|
630
|
+
end
|
631
|
+
|
632
|
+
duration = merged_options[:duration]
|
633
|
+
|
634
|
+
if uia_available? && duration < 0.5
|
635
|
+
raise ArgumentError, %Q[
|
636
|
+
Invalid duration: #{duration}
|
637
|
+
|
638
|
+
The minimum duration is 0.5
|
639
|
+
|
640
|
+
]
|
641
|
+
elsif duration <= 0.0
|
642
|
+
raise ArgumentError, %Q[
|
643
|
+
Invalid duration: #{duration}
|
644
|
+
|
645
|
+
The minimum duration is 0.0.
|
646
|
+
|
647
|
+
]
|
648
|
+
end
|
649
|
+
|
650
|
+
launcher.automator.pinch(in_out.to_sym, merged_options)
|
601
651
|
end
|
602
652
|
|
603
653
|
# @deprecated 0.21.0 Use #keyboard_enter_text
|
@@ -757,7 +807,7 @@ To type strings with more than one character, use keyboard_enter_text.
|
|
757
807
|
# for the keyboard to disappear.
|
758
808
|
#
|
759
809
|
# @note
|
760
|
-
#
|
810
|
+
# The dismiss keyboard key does not exist on the iPhone or iPod
|
761
811
|
#
|
762
812
|
# @raise [RuntimeError] If the device is not an iPad
|
763
813
|
# @raise [Calabash::Cucumber::WaitHelpers::WaitError] If the keyboard does
|
@@ -802,38 +852,111 @@ Use `ipad?` to branch in your test.
|
|
802
852
|
views_touched
|
803
853
|
end
|
804
854
|
|
855
|
+
# Scrolls to a mark in a UIScrollView.
|
856
|
+
#
|
857
|
+
# Make sure your query matches exactly one UIScrollView. If multiple
|
858
|
+
# scroll views are matched, the results can be unpredictable.
|
859
|
+
#
|
860
|
+
# @example
|
861
|
+
# scroll_to_mark("settings")
|
862
|
+
# scroll_to_mark("Android", {:animated => false})
|
863
|
+
# scroll_to_mark("Alarm", {:query => "UIScrollView marked:'Settings'"})
|
864
|
+
#
|
865
|
+
# @see #scroll_to_row_with_mark
|
866
|
+
# @see #scroll_to_collection_view_item_with_mark
|
867
|
+
#
|
868
|
+
# @param [String] mark an accessibility label or identifier or text
|
869
|
+
# @param [Hash] options controls the query and and scroll behavior
|
870
|
+
# @option options [String] :query ("UIScrollView index:0") A query to
|
871
|
+
# uniquely identify the scroll view if there are multiple scroll views.
|
872
|
+
# @option options [Boolean] :animate (true) should the scrolling be animated
|
873
|
+
# @option options [String] :failure_message (nil) If nil, a default failure
|
874
|
+
# message will be shown if this scroll scroll cannot be performed.
|
875
|
+
#
|
876
|
+
# @raise [RuntimeError] If the scroll cannot be performed
|
877
|
+
# @raise [RuntimeError] If the :query finds no scroll view
|
878
|
+
# @raise [ArgumentError] If the mark is nil
|
879
|
+
# @raise [ArgumentError] If the :query value is nil, "", or "*".
|
880
|
+
def scroll_to_mark(mark, options={})
|
881
|
+
if mark.nil?
|
882
|
+
raise ArgumentError, "The mark cannot be nil"
|
883
|
+
end
|
884
|
+
|
885
|
+
merged_options = {:query => "UIScrollView index:0",
|
886
|
+
:animate => true,
|
887
|
+
:failure_message => nil}.merge(options)
|
888
|
+
|
889
|
+
uiquery = merged_options[:query]
|
890
|
+
|
891
|
+
if uiquery.nil?
|
892
|
+
raise ArgumentError, "The :query option cannot be nil"
|
893
|
+
end
|
894
|
+
|
895
|
+
if uiquery == ""
|
896
|
+
raise ArgumentError, "The :query option cannot be the empty string"
|
897
|
+
end
|
898
|
+
|
899
|
+
if uiquery == "*"
|
900
|
+
raise ArgumentError, "The :query option cannot be the wildcard '*'"
|
901
|
+
end
|
902
|
+
|
903
|
+
args = [merged_options[:animate]]
|
904
|
+
|
905
|
+
views_touched = Map.map(uiquery, :scrollToMark, mark, *args)
|
906
|
+
|
907
|
+
message = merged_options[:failure_message]
|
908
|
+
|
909
|
+
if !message
|
910
|
+
message = %Q[
|
911
|
+
|
912
|
+
Unable to scroll to mark '#{mark}' in UIScrollView matching #{uiquery}"
|
913
|
+
|
914
|
+
]
|
915
|
+
end
|
916
|
+
|
917
|
+
Map.assert_map_results(views_touched, message)
|
918
|
+
views_touched
|
919
|
+
end
|
920
|
+
|
805
921
|
# Scroll a table view to a row. Table view should have only one section.
|
922
|
+
#
|
923
|
+
# Make sure your query matches exactly one UITableView. If multiple views
|
924
|
+
# are matched, the results can be unpredictable.
|
925
|
+
#
|
806
926
|
# @see #scroll_to_cell
|
927
|
+
#
|
807
928
|
# @example
|
808
|
-
# scroll_to_row "UITableView", 2
|
809
|
-
# @note this is implemented by calling the Obj-C `scrollToRowAtIndexPath:atScrollPosition:animated:` method
|
810
|
-
# and can do things users cant.
|
929
|
+
# scroll_to_row "UITableView index:0", 2
|
811
930
|
#
|
812
|
-
# @param {String} uiquery
|
931
|
+
# @param {String} uiquery Should match a UITableView
|
813
932
|
def scroll_to_row(uiquery, number)
|
814
933
|
views_touched = Map.map(uiquery, :scrollToRow, number)
|
815
|
-
msg = "
|
934
|
+
msg = "Unable to scroll to row #{number} in table view with '#{uiquery}'"
|
816
935
|
Map.assert_map_results(views_touched, msg)
|
817
936
|
views_touched
|
818
937
|
end
|
819
938
|
|
820
|
-
# Scroll a table view to a section and row.
|
939
|
+
# Scroll a table view to a section and row.
|
940
|
+
#
|
941
|
+
# Make sure your query matches exactly one UITableView. If multiple views
|
942
|
+
# are matched, the results can be unpredictable.
|
821
943
|
#
|
822
944
|
# @todo should expose a non-option first argument query and required parameters `section`, `row`
|
823
945
|
#
|
824
946
|
# @see #scroll_to_row
|
825
947
|
# @example
|
826
|
-
# scroll_to_cell
|
827
|
-
# @note this is implemented by calling the Obj-C `scrollToRowAtIndexPath:atScrollPosition:animated:` method
|
828
|
-
# and can do things users cant.
|
948
|
+
# scroll_to_cell row:4, section:0, animate: false
|
829
949
|
#
|
830
950
|
# @param {Hash} options specifies details of the scroll
|
831
|
-
# @option options {String} :query (
|
951
|
+
# @option options {String} :query ("UITableView index:0") query specifying
|
952
|
+
# which table view to scroll
|
832
953
|
# @option options {Fixnum} :section section to scroll to
|
833
954
|
# @option options {Fixnum} :row row to scroll to
|
834
955
|
# @option options {String} :scroll_position position to scroll to
|
835
956
|
# @option options {Boolean} :animated (true) animate or not
|
836
|
-
|
957
|
+
# @raise [ArgumentError] If row or section is nil
|
958
|
+
# @raise [ArgumentError] If the :query value is nil, "", or "*".
|
959
|
+
def scroll_to_cell(options={:query => "UITableView index:0",
|
837
960
|
:row => 0,
|
838
961
|
:section => 0,
|
839
962
|
:scroll_position => :top,
|
@@ -841,8 +964,8 @@ Use `ipad?` to branch in your test.
|
|
841
964
|
uiquery = options[:query] || 'tableView'
|
842
965
|
row = options[:row]
|
843
966
|
sec = options[:section]
|
844
|
-
if row.nil?
|
845
|
-
raise 'You must supply both :row and :section keys to scroll_to_cell'
|
967
|
+
if row.nil? || sec.nil?
|
968
|
+
raise ArgumentError, 'You must supply both :row and :section keys to scroll_to_cell'
|
846
969
|
end
|
847
970
|
|
848
971
|
args = []
|
@@ -862,14 +985,16 @@ Use `ipad?` to branch in your test.
|
|
862
985
|
|
863
986
|
# Scrolls to a mark in a UITableView.
|
864
987
|
#
|
988
|
+
# Make sure your query matches exactly one UITableView. If multiple
|
989
|
+
# views are matched, the results can be unpredictable.
|
990
|
+
#
|
865
991
|
# @example Scroll to the top of the item with the given mark.
|
866
992
|
# scroll_to_row_with_mark('settings', {:scroll_position => :top})
|
867
993
|
#
|
868
994
|
# @example Scroll to the bottom of the item with the given mark.
|
869
995
|
# scroll_to_row_with_mark('about', {:scroll_position => :bottom})
|
870
996
|
#
|
871
|
-
# @param [String] mark an accessibility
|
872
|
-
# or on the row
|
997
|
+
# @param [String] mark an accessibility label or identifier or text in row
|
873
998
|
# @param [Hash] options controls the query and and scroll behavior
|
874
999
|
#
|
875
1000
|
# @option options [String] :query ('tableView')
|
@@ -879,38 +1004,64 @@ Use `ipad?` to branch in your test.
|
|
879
1004
|
# `{:middle | :top | :bottom}`
|
880
1005
|
# @option options [Boolean] :animate (true)
|
881
1006
|
# should the scrolling be animated
|
1007
|
+
# @option options [String] :failure_message (nil) If nil, a default failure
|
1008
|
+
# message will be shown if this scroll scroll cannot be performed.
|
882
1009
|
#
|
883
1010
|
# @raise [RuntimeError] if the scroll cannot be performed
|
884
|
-
# @raise [RuntimeError] if the mark is nil
|
885
1011
|
# @raise [RuntimeError] if the table query finds no table view
|
886
1012
|
# @raise [RuntimeError] if the scroll position is invalid
|
887
|
-
|
888
|
-
|
889
|
-
|
1013
|
+
# @raise [ArgumentError] if the mark is nil
|
1014
|
+
# @raise [ArgumentError] If the :query value is nil, "", or "*".
|
1015
|
+
def scroll_to_row_with_mark(mark, options={})
|
1016
|
+
merged_options = {:query => "UITableView index:0",
|
1017
|
+
:scroll_position => :middle,
|
1018
|
+
:animate => true,
|
1019
|
+
:failure_message => nil}.merge(options)
|
1020
|
+
|
890
1021
|
if mark.nil?
|
891
|
-
|
1022
|
+
raise ArgumentError, "The mark cannot be nil"
|
892
1023
|
end
|
893
1024
|
|
894
|
-
uiquery =
|
1025
|
+
uiquery = merged_options[:query]
|
895
1026
|
|
896
|
-
|
897
|
-
|
898
|
-
args << options[:scroll_position]
|
899
|
-
else
|
900
|
-
args << 'middle'
|
1027
|
+
if uiquery.nil?
|
1028
|
+
raise ArgumentError, "The :query option cannot be nil"
|
901
1029
|
end
|
902
|
-
|
903
|
-
|
1030
|
+
|
1031
|
+
if uiquery == ""
|
1032
|
+
raise ArgumentError, "The :query option cannot be the empty string"
|
904
1033
|
end
|
905
1034
|
|
1035
|
+
if uiquery == "*"
|
1036
|
+
raise ArgumentError, "The :query option cannot be the wildcard '*'"
|
1037
|
+
end
|
1038
|
+
|
1039
|
+
args = [merged_options[:scroll_position], merged_options[:animate]]
|
1040
|
+
|
906
1041
|
views_touched = Map.map(uiquery, :scrollToRowWithMark, mark, *args)
|
907
|
-
|
908
|
-
|
1042
|
+
|
1043
|
+
message = merged_options[:failure_message]
|
1044
|
+
if !message
|
1045
|
+
message = %Q[
|
1046
|
+
Unable to scroll to mark: '#{mark}' in table view matched by query:
|
1047
|
+
|
1048
|
+
#{uiquery}
|
1049
|
+
|
1050
|
+
with options:
|
1051
|
+
|
1052
|
+
#{merged_options}
|
1053
|
+
|
1054
|
+
]
|
1055
|
+
end
|
1056
|
+
Map.assert_map_results(views_touched, message)
|
909
1057
|
views_touched
|
910
1058
|
end
|
911
1059
|
|
912
1060
|
# Scrolls to an item in a section of a UICollectionView.
|
913
1061
|
#
|
1062
|
+
# Make sure your query matches exactly one UICollectionView. If multiple
|
1063
|
+
# views are matched, the results can be unpredictable.
|
1064
|
+
#
|
914
1065
|
# @note item and section are zero-indexed
|
915
1066
|
#
|
916
1067
|
# @example Scroll to item 0 in section 2 to top.
|
@@ -922,12 +1073,12 @@ Use `ipad?` to branch in your test.
|
|
922
1073
|
# @example The following are the allowed :scroll_position values.
|
923
1074
|
# {:top | :center_vertical | :bottom | :left | :center_horizontal | :right}
|
924
1075
|
#
|
925
|
-
# @param [Integer]
|
926
|
-
# @param [Integer]
|
927
|
-
# @param [Hash]
|
1076
|
+
# @param [Integer] item_index the index of the item to scroll to. Must be >= 0.
|
1077
|
+
# @param [Integer] section_index the section of the item to scroll to. Must be > 0.
|
1078
|
+
# @param [Hash] options options for controlling the collection view query
|
928
1079
|
# and scroll behavior
|
929
1080
|
#
|
930
|
-
# @option opts [String] :query (
|
1081
|
+
# @option opts [String] :query ("UICollectionView index:0")
|
931
1082
|
# the query that is used to identify which collection view to scroll
|
932
1083
|
#
|
933
1084
|
# @option opts [Symbol] :scroll_position (top)
|
@@ -936,46 +1087,86 @@ Use `ipad?` to branch in your test.
|
|
936
1087
|
# @option opts [Boolean] :animate (true)
|
937
1088
|
# should the scrolling be animated
|
938
1089
|
#
|
939
|
-
# @option opts [String] :
|
1090
|
+
# @option opts [String] :failure_message (nil)
|
940
1091
|
# a custom error message to display if the scrolling fails - if not
|
941
1092
|
# specified, a generic failure will be displayed
|
942
1093
|
#
|
943
1094
|
# @raise [RuntimeError] if the scroll cannot be performed
|
944
1095
|
# @raise [RuntimeError] :query finds no collection view
|
945
1096
|
# @raise [RuntimeError] the collection view does not contain a cell at item/section
|
946
|
-
# @raise [
|
947
|
-
|
948
|
-
|
1097
|
+
# @raise [ArgumentError] :scroll_position is invalid
|
1098
|
+
# @raise [ArgumentError] item or section is < 0.
|
1099
|
+
# @raise [ArgumentError] If the :query value is nil, "", or "*".
|
1100
|
+
def scroll_to_collection_view_item(item_index, section_index, options={})
|
1101
|
+
default_options = {:query => "UICollectionView index:0",
|
949
1102
|
:scroll_position => :top,
|
950
1103
|
:animate => true,
|
951
|
-
:
|
952
|
-
|
953
|
-
uiquery =
|
1104
|
+
:failure_message => nil}
|
1105
|
+
merged_options = default_options.merge(options)
|
1106
|
+
uiquery = merged_options[:query]
|
1107
|
+
|
1108
|
+
if uiquery.nil?
|
1109
|
+
raise ArgumentError, "The :query option cannot be nil"
|
1110
|
+
end
|
1111
|
+
|
1112
|
+
if uiquery == ""
|
1113
|
+
raise ArgumentError, "The :query option cannot be the empty string"
|
1114
|
+
end
|
1115
|
+
|
1116
|
+
if uiquery == "*"
|
1117
|
+
raise ArgumentError, "The :query option cannot be the wildcard '*'"
|
1118
|
+
end
|
1119
|
+
|
1120
|
+
if item_index < 0
|
1121
|
+
raise ArgumentError, "Invalid item index: '#{item_index}' - must be >= 0"
|
1122
|
+
end
|
1123
|
+
|
1124
|
+
if section_index < 0
|
1125
|
+
raise ArgumentError, "Invalid section index: '#{section_index}' - must be >= 0"
|
1126
|
+
end
|
954
1127
|
|
955
|
-
scroll_position =
|
1128
|
+
scroll_position = merged_options[:scroll_position]
|
956
1129
|
candidates = [:top, :center_vertical, :bottom, :left, :center_horizontal, :right]
|
957
|
-
|
958
|
-
raise
|
1130
|
+
if !candidates.include?(scroll_position)
|
1131
|
+
raise ArgumentError, %Q[
|
1132
|
+
|
1133
|
+
Invalid :scroll_position option '#{scroll_position}'. Valid options are:
|
1134
|
+
|
1135
|
+
#{candidates.join(", ")}
|
1136
|
+
|
1137
|
+
]
|
959
1138
|
end
|
960
1139
|
|
961
|
-
animate =
|
1140
|
+
animate = merged_options[:animate]
|
962
1141
|
|
963
1142
|
views_touched = Map.map(uiquery, :collectionViewScroll,
|
964
|
-
|
1143
|
+
item_index.to_i, section_index.to_i,
|
965
1144
|
scroll_position, animate)
|
966
1145
|
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
1146
|
+
message = merged_options[:failure_message]
|
1147
|
+
if !message
|
1148
|
+
message = %Q[
|
1149
|
+
Unable to scroll to item index '#{item_index}' in section index '#{section_index}'
|
1150
|
+
in CollectionView matched by:
|
1151
|
+
|
1152
|
+
#{uiquery}
|
1153
|
+
|
1154
|
+
with options:
|
1155
|
+
|
1156
|
+
#{merged_options}
|
1157
|
+
|
1158
|
+
]
|
971
1159
|
end
|
972
1160
|
|
973
|
-
Map.assert_map_results(views_touched,
|
1161
|
+
Map.assert_map_results(views_touched, message)
|
974
1162
|
views_touched
|
975
1163
|
end
|
976
1164
|
|
977
1165
|
# Scrolls to mark in a UICollectionView.
|
978
1166
|
#
|
1167
|
+
# Make sure your query matches exactly one UICollectionView. If multiple
|
1168
|
+
# views are matched, the results can be unpredictable.
|
1169
|
+
#
|
979
1170
|
# @example Scroll to the top of the item with the given mark.
|
980
1171
|
# scroll_to_collection_view_item_with_mark('cat', {:scroll_position => :top})
|
981
1172
|
#
|
@@ -987,7 +1178,7 @@ Use `ipad?` to branch in your test.
|
|
987
1178
|
#
|
988
1179
|
# @param [String] mark an accessibility `{label | identifier}` or text in
|
989
1180
|
# or on the item
|
990
|
-
# @param [Hash]
|
1181
|
+
# @param [Hash] options options for controlling the collection view query
|
991
1182
|
# and scroll behavior
|
992
1183
|
#
|
993
1184
|
# @option opts [String] :query ('collectionView')
|
@@ -996,43 +1187,74 @@ Use `ipad?` to branch in your test.
|
|
996
1187
|
# the position in the collection view to scroll the item to
|
997
1188
|
# @option opts [Boolean] :animate (true) should the scroll
|
998
1189
|
# be animated
|
999
|
-
# @option opts [String] :
|
1000
|
-
#
|
1001
|
-
#
|
1190
|
+
# @option opts [String] :failure_message (nil) a custom error message to
|
1191
|
+
# display if the scrolling fails - if not specified, a generic failure
|
1192
|
+
# will be displayed
|
1002
1193
|
#
|
1003
1194
|
# @raise [RuntimeError] if the scroll cannot be performed
|
1004
|
-
# @raise [RuntimeError] if the mark is nil
|
1005
1195
|
# @raise [RuntimeError] :query finds no collection view
|
1006
1196
|
# @raise [RuntimeError] the collection view does not contain a cell
|
1007
1197
|
# with the mark
|
1008
1198
|
# @raise [RuntimeError] :scroll_position is invalid
|
1009
|
-
|
1010
|
-
|
1199
|
+
# @raise [ArgumentError] If the :query value is nil, "", or "*".
|
1200
|
+
# @raise [ArgumentError] if the mark is nil
|
1201
|
+
def scroll_to_collection_view_item_with_mark(mark, options={})
|
1202
|
+
default_options = {:query => "UICollectionView index:0",
|
1011
1203
|
:scroll_position => :top,
|
1012
1204
|
:animate => true,
|
1013
|
-
:
|
1014
|
-
|
1015
|
-
uiquery =
|
1205
|
+
:failure_message => nil}
|
1206
|
+
merged_options = default_options.merge(options)
|
1207
|
+
uiquery = merged_options[:query]
|
1016
1208
|
|
1017
1209
|
if mark.nil?
|
1018
|
-
raise
|
1210
|
+
raise ArgumentError, "The mark cannot be nil"
|
1019
1211
|
end
|
1020
1212
|
|
1021
|
-
|
1022
|
-
|
1213
|
+
if uiquery.nil?
|
1214
|
+
raise ArgumentError, "The :query option cannot be nil"
|
1215
|
+
end
|
1216
|
+
|
1217
|
+
if uiquery == ""
|
1218
|
+
raise ArgumentError, "The :query option cannot be the empty string"
|
1219
|
+
end
|
1220
|
+
|
1221
|
+
if uiquery == "*"
|
1222
|
+
raise ArgumentError, "The :query option cannot be the wildcard '*'"
|
1223
|
+
end
|
1224
|
+
|
1225
|
+
scroll_position = merged_options[:scroll_position]
|
1023
1226
|
candidates = [:top, :center_vertical, :bottom, :left, :center_horizontal, :right]
|
1024
|
-
|
1025
|
-
raise
|
1227
|
+
if !candidates.include?(scroll_position)
|
1228
|
+
raise ArgumentError, %Q[
|
1229
|
+
|
1230
|
+
Invalid :scroll_position option '#{scroll_position}'. Valid options are:
|
1231
|
+
|
1232
|
+
#{candidates.join(", ")}
|
1233
|
+
|
1234
|
+
]
|
1026
1235
|
end
|
1027
1236
|
|
1028
|
-
args
|
1029
|
-
args << opts[:animate]
|
1237
|
+
args = [scroll_position, merged_options[:animate]]
|
1030
1238
|
|
1031
|
-
views_touched = Map.map(uiquery,
|
1239
|
+
views_touched = Map.map(uiquery,
|
1240
|
+
:collectionViewScrollToItemWithMark,
|
1032
1241
|
mark, *args)
|
1033
1242
|
|
1034
|
-
|
1035
|
-
|
1243
|
+
message = merged_options[:failure_message]
|
1244
|
+
if !message
|
1245
|
+
message = %Q[
|
1246
|
+
Unable to scroll to item with mark '#{mark}' in UICollectionView matching query:
|
1247
|
+
|
1248
|
+
#{uiquery}
|
1249
|
+
|
1250
|
+
with options:
|
1251
|
+
|
1252
|
+
#{merged_options}
|
1253
|
+
|
1254
|
+
]
|
1255
|
+
end
|
1256
|
+
|
1257
|
+
Map.assert_map_results(views_touched, message)
|
1036
1258
|
views_touched
|
1037
1259
|
end
|
1038
1260
|
|
@@ -239,6 +239,12 @@ module Calabash
|
|
239
239
|
ios_version_object.major.to_s
|
240
240
|
end
|
241
241
|
|
242
|
+
# Is this device running iOS 10?
|
243
|
+
# @return [Boolean] true if the major version of the OS is 10
|
244
|
+
def ios10?
|
245
|
+
ios_version_object.major == 10
|
246
|
+
end
|
247
|
+
|
242
248
|
# Is this device running iOS 9?
|
243
249
|
# @return [Boolean] true if the major version of the OS is 9
|
244
250
|
def ios9?
|
@@ -24,7 +24,7 @@ module Calabash
|
|
24
24
|
@world = world
|
25
25
|
end
|
26
26
|
|
27
|
-
#
|
27
|
+
# Query the UI for elements.
|
28
28
|
#
|
29
29
|
# @example
|
30
30
|
# query({id: "login", :type "Button"})
|
@@ -126,7 +126,7 @@ module Calabash
|
|
126
126
|
#
|
127
127
|
# @raise [RuntimeError] if no view matches the uiquery after waiting.
|
128
128
|
def query_for_coordinate(uiquery)
|
129
|
-
|
129
|
+
with_screenshot_on_failure { client.query_for_coordinate(uiquery) }
|
130
130
|
end
|
131
131
|
|
132
132
|
# Perform a touch on the center of the first view matched the uiquery.
|
@@ -140,7 +140,7 @@ module Calabash
|
|
140
140
|
#
|
141
141
|
# @raise [RuntimeError] if no view matches the uiquery after waiting.
|
142
142
|
def touch(uiquery)
|
143
|
-
|
143
|
+
with_screenshot_on_failure { client.touch(uiquery) }
|
144
144
|
end
|
145
145
|
|
146
146
|
# Perform a touch at a coordinate.
|
@@ -173,7 +173,7 @@ module Calabash
|
|
173
173
|
#
|
174
174
|
# @raise [RuntimeError] if no view matches the uiquery after waiting.
|
175
175
|
def double_tap(uiquery)
|
176
|
-
|
176
|
+
with_screenshot_on_failure { client.double_tap(uiquery) }
|
177
177
|
end
|
178
178
|
|
179
179
|
# Perform a two finger tap on the center of the first view matched the uiquery.
|
@@ -187,7 +187,7 @@ module Calabash
|
|
187
187
|
#
|
188
188
|
# @raise [RuntimeError] if no view matches the uiquery after waiting.
|
189
189
|
def two_finger_tap(uiquery)
|
190
|
-
|
190
|
+
with_screenshot_on_failure { client.two_finger_tap(uiquery) }
|
191
191
|
end
|
192
192
|
|
193
193
|
# Perform a long press on the center of the first view matched the uiquery.
|
@@ -202,7 +202,7 @@ module Calabash
|
|
202
202
|
#
|
203
203
|
# @raise [RuntimeError] if no view matches the uiquery after waiting.
|
204
204
|
def long_press(uiquery, duration)
|
205
|
-
|
205
|
+
with_screenshot_on_failure { client.long_press(uiquery, {:duration => duration}) }
|
206
206
|
end
|
207
207
|
|
208
208
|
# Returns true if there is a keyboard visible.
|
@@ -228,7 +228,7 @@ module Calabash
|
|
228
228
|
# @raise [RuntimeError] if there is no visible keyboard.
|
229
229
|
# @deprecated 0.21.0 Use Core#enter_text
|
230
230
|
def enter_text(text)
|
231
|
-
|
231
|
+
with_screenshot_on_failure { client.enter_text(text) }
|
232
232
|
end
|
233
233
|
|
234
234
|
# Enter text into the first view matched by uiquery.
|
@@ -244,7 +244,7 @@ module Calabash
|
|
244
244
|
#
|
245
245
|
# @deprecated 0.21.0 Use Core#enter_text
|
246
246
|
def enter_text_in(uiquery, text)
|
247
|
-
|
247
|
+
with_screenshot_on_failure do
|
248
248
|
client.touch(uiquery)
|
249
249
|
client.wait_for_keyboard
|
250
250
|
client.enter_text(text)
|
@@ -311,20 +311,6 @@ module Calabash
|
|
311
311
|
client.springboard_alert
|
312
312
|
end
|
313
313
|
|
314
|
-
=begin
|
315
|
-
PROTECTED
|
316
|
-
=end
|
317
|
-
protected
|
318
|
-
|
319
|
-
# @!visibility private
|
320
|
-
def method_missing(name, *args, &block)
|
321
|
-
if world.respond_to?(name)
|
322
|
-
world.send(name, *args, &block)
|
323
|
-
else
|
324
|
-
super
|
325
|
-
end
|
326
|
-
end
|
327
|
-
|
328
314
|
=begin
|
329
315
|
PRIVATE
|
330
316
|
=end
|
@@ -334,7 +320,7 @@ PRIVATE
|
|
334
320
|
attr_reader :client, :world
|
335
321
|
|
336
322
|
# @!visibility private
|
337
|
-
def
|
323
|
+
def with_screenshot_on_failure(&block)
|
338
324
|
begin
|
339
325
|
block.call
|
340
326
|
rescue => e
|
@@ -192,6 +192,14 @@ module Calabash
|
|
192
192
|
_default_device_or_create.ios9?
|
193
193
|
end
|
194
194
|
|
195
|
+
# Is the device under test running iOS 10?
|
196
|
+
#
|
197
|
+
# @raise [RuntimeError] if the server cannot be reached
|
198
|
+
# @return [Boolean] true if device under test is running iOS 9
|
199
|
+
def ios10?
|
200
|
+
_default_device_or_create.ios10?
|
201
|
+
end
|
202
|
+
|
195
203
|
# Is the app that is being tested an iPhone app emulated on an iPad?
|
196
204
|
#
|
197
205
|
# @see Calabash::Cucumber::IPad
|
@@ -173,14 +173,19 @@ module Calabash
|
|
173
173
|
screenshot_and_raise "There must be a visible keyboard"
|
174
174
|
end
|
175
175
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
176
|
+
query = "* isFirstResponder:1"
|
177
|
+
elements = _query_wrapper(query, :text)
|
178
|
+
|
179
|
+
return "" if elements.count == 0
|
180
|
+
|
181
|
+
text = elements[0]
|
182
|
+
|
183
|
+
# first responder did not respond to :text selector
|
184
|
+
return "" if text == "*****"
|
185
|
+
|
186
|
+
return "" if text.nil?
|
187
|
+
|
188
|
+
text
|
184
189
|
end
|
185
190
|
|
186
191
|
# @visibility private
|
@@ -132,11 +132,11 @@ module Calabash
|
|
132
132
|
#
|
133
133
|
# +1 for tools to ask physical devices about attributes.
|
134
134
|
def device
|
135
|
-
@device ||=
|
135
|
+
@device ||= begin
|
136
136
|
_, body = Calabash::Cucumber::HTTP.ensure_connectivity
|
137
137
|
endpoint = Calabash::Cucumber::Environment.device_endpoint
|
138
138
|
Calabash::Cucumber::Device.new(endpoint, body)
|
139
|
-
end
|
139
|
+
end
|
140
140
|
end
|
141
141
|
|
142
142
|
# @!visibility private
|
@@ -170,20 +170,6 @@ module Calabash
|
|
170
170
|
:http_connection_timeout => 10}
|
171
171
|
merged_options = default_options.merge(options)
|
172
172
|
|
173
|
-
@run_loop = RunLoop::HostCache.default.read
|
174
|
-
|
175
|
-
if @run_loop[:automator] == :device_agent
|
176
|
-
# TODO Attach to DeviceAgent - run-loop supports this!
|
177
|
-
# TODO Rewrite UIA methods to raise in the context of UIA
|
178
|
-
raise RuntimeError, %Q[
|
179
|
-
|
180
|
-
Cannot attach to DeviceAgent automator.
|
181
|
-
|
182
|
-
This behavior is not implemented yet.
|
183
|
-
|
184
|
-
]
|
185
|
-
end
|
186
|
-
|
187
173
|
begin
|
188
174
|
Calabash::Cucumber::HTTP.ensure_connectivity(merged_options)
|
189
175
|
rescue Calabash::Cucumber::ServerNotRespondingError => _
|
@@ -207,13 +193,22 @@ Try `start_test_server_in_background`
|
|
207
193
|
return false
|
208
194
|
end
|
209
195
|
|
210
|
-
|
211
|
-
|
196
|
+
# TODO check that the :pid is alive - no sense attaching if Automator
|
197
|
+
# is not running.
|
198
|
+
run_loop_cache = RunLoop::HostCache.default.read
|
199
|
+
|
200
|
+
if run_loop_cache[:automator] == :device_agent
|
201
|
+
# Sets the @run_loop variable to a new RunLoop::DeviceAgent::Client
|
202
|
+
# instance.
|
203
|
+
@automator = _attach_to_device_agent!(run_loop_cache)
|
204
|
+
elsif run_loop_cache[:automator] == :instruments
|
205
|
+
@run_loop = run_loop_cache
|
206
|
+
@automator = Calabash::Cucumber::Automator::Instruments.new(run_loop_cache)
|
212
207
|
else
|
213
208
|
RunLoop.log_warn(
|
214
209
|
%Q[
|
215
210
|
|
216
|
-
Connected to an app that was not launched by Calabash using instruments.
|
211
|
+
Connected to an app that was not launched by Calabash using instruments or DeviceAgent.
|
217
212
|
|
218
213
|
Queries will work, but gestures and other automator actions will not.
|
219
214
|
|
@@ -627,6 +622,28 @@ true. Please remove this method call from your hooks.
|
|
627
622
|
value
|
628
623
|
end
|
629
624
|
end
|
625
|
+
|
626
|
+
# @!visibility private
|
627
|
+
def _attach_to_device_agent!(hash)
|
628
|
+
simctl = Calabash::Cucumber::Environment.simctl
|
629
|
+
instruments = Calabash::Cucumber::Environment.instruments
|
630
|
+
xcode = Calabash::Cucumber::Environment.xcode
|
631
|
+
|
632
|
+
options = { simctl: simctl, instruments: instruments, xcode: xcode}
|
633
|
+
device = RunLoop::Device.device_with_identifier(hash[:udid], options)
|
634
|
+
bundle_id = hash[:app]
|
635
|
+
|
636
|
+
options = { cbx_launcher: hash[:launcher] }
|
637
|
+
cbx_launcher = RunLoop::DeviceAgent::Client.detect_cbx_launcher(options, device)
|
638
|
+
launcher_options = hash[:launcher_options]
|
639
|
+
|
640
|
+
device_agent_client = RunLoop::DeviceAgent::Client.new(bundle_id,
|
641
|
+
device,
|
642
|
+
cbx_launcher,
|
643
|
+
launcher_options)
|
644
|
+
@run_loop = device_agent_client
|
645
|
+
Calabash::Cucumber::Automator::DeviceAgent.new(@run_loop)
|
646
|
+
end
|
630
647
|
end
|
631
648
|
end
|
632
649
|
end
|
@@ -145,7 +145,7 @@ details: #{hash["details"]}
|
|
145
145
|
def self.assert_map_results(map_results, msg)
|
146
146
|
compact = map_results.compact
|
147
147
|
if compact.empty? or compact.member? '<VOID>' or compact.member? '*****'
|
148
|
-
|
148
|
+
self.map_factory.screenshot_and_raise msg
|
149
149
|
end
|
150
150
|
end
|
151
151
|
|
@@ -163,7 +163,7 @@ module Calabash
|
|
163
163
|
hash = {
|
164
164
|
:event_name => "session",
|
165
165
|
:data_version => DATA_VERSION,
|
166
|
-
:
|
166
|
+
:distinct_id => user_id
|
167
167
|
}
|
168
168
|
|
169
169
|
if allowed == "system_info"
|
@@ -178,6 +178,9 @@ module Calabash
|
|
178
178
|
:used_cucumber => used_cucumber?,
|
179
179
|
|
180
180
|
:version => Calabash::Cucumber::VERSION,
|
181
|
+
:run_loop_version => RunLoop::VERSION,
|
182
|
+
|
183
|
+
:xcode_version => RunLoop::Xcode.new.version,
|
181
184
|
|
182
185
|
:ci => RunLoop::Environment.ci?,
|
183
186
|
:jenkins => RunLoop::Environment.jenkins?,
|
@@ -3,10 +3,10 @@ module Calabash
|
|
3
3
|
|
4
4
|
# @!visibility public
|
5
5
|
# The Calabash iOS gem version.
|
6
|
-
VERSION = "0.20.
|
6
|
+
VERSION = "0.20.3"
|
7
7
|
|
8
8
|
# @!visibility public
|
9
9
|
# The minimum required version of the Calabash embedded server.
|
10
|
-
MIN_SERVER_VERSION = "0.20.
|
10
|
+
MIN_SERVER_VERSION = "0.20.3"
|
11
11
|
end
|
12
12
|
end
|
data/scripts/.irbrc
CHANGED
Binary file
|
Binary file
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: calabash-cucumber
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.20.
|
4
|
+
version: 0.20.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Karl Krukow
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-10-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cucumber
|
@@ -84,7 +84,7 @@ dependencies:
|
|
84
84
|
requirements:
|
85
85
|
- - ">="
|
86
86
|
- !ruby/object:Gem::Version
|
87
|
-
version: 2.
|
87
|
+
version: 2.7.1
|
88
88
|
- - "<"
|
89
89
|
- !ruby/object:Gem::Version
|
90
90
|
version: '3.0'
|
@@ -94,7 +94,7 @@ dependencies:
|
|
94
94
|
requirements:
|
95
95
|
- - ">="
|
96
96
|
- !ruby/object:Gem::Version
|
97
|
-
version: 2.
|
97
|
+
version: 2.7.1
|
98
98
|
- - "<"
|
99
99
|
- !ruby/object:Gem::Version
|
100
100
|
version: '3.0'
|
@@ -132,7 +132,7 @@ dependencies:
|
|
132
132
|
requirements:
|
133
133
|
- - ">="
|
134
134
|
- !ruby/object:Gem::Version
|
135
|
-
version: 2.2.
|
135
|
+
version: 2.2.2
|
136
136
|
- - "<"
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '3.0'
|
@@ -142,7 +142,7 @@ dependencies:
|
|
142
142
|
requirements:
|
143
143
|
- - ">="
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version: 2.2.
|
145
|
+
version: 2.2.2
|
146
146
|
- - "<"
|
147
147
|
- !ruby/object:Gem::Version
|
148
148
|
version: '3.0'
|
@@ -286,6 +286,20 @@ dependencies:
|
|
286
286
|
- - ">="
|
287
287
|
- !ruby/object:Gem::Version
|
288
288
|
version: '0'
|
289
|
+
- !ruby/object:Gem::Dependency
|
290
|
+
name: rb-readline
|
291
|
+
requirement: !ruby/object:Gem::Requirement
|
292
|
+
requirements:
|
293
|
+
- - ">="
|
294
|
+
- !ruby/object:Gem::Version
|
295
|
+
version: '0'
|
296
|
+
type: :development
|
297
|
+
prerelease: false
|
298
|
+
version_requirements: !ruby/object:Gem::Requirement
|
299
|
+
requirements:
|
300
|
+
- - ">="
|
301
|
+
- !ruby/object:Gem::Version
|
302
|
+
version: '0'
|
289
303
|
- !ruby/object:Gem::Dependency
|
290
304
|
name: guard-rspec
|
291
305
|
requirement: !ruby/object:Gem::Requirement
|