calabash-cucumber 0.20.0 → 0.20.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|