calabash-cucumber 0.19.2 → 0.20.0
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.rb +9 -2
- data/lib/calabash-cucumber/abstract.rb +23 -0
- data/lib/calabash-cucumber/automator/automator.rb +158 -0
- data/lib/calabash-cucumber/automator/coordinates.rb +401 -0
- data/lib/calabash-cucumber/automator/device_agent.rb +424 -0
- data/lib/calabash-cucumber/automator/instruments.rb +441 -0
- data/lib/calabash-cucumber/connection_helpers.rb +1 -0
- data/lib/calabash-cucumber/core.rb +632 -138
- data/lib/calabash-cucumber/device_agent.rb +346 -0
- data/lib/calabash-cucumber/dot_dir.rb +1 -0
- data/lib/calabash-cucumber/environment.rb +1 -0
- data/lib/calabash-cucumber/environment_helpers.rb +4 -3
- data/lib/calabash-cucumber/http/http.rb +6 -4
- data/lib/calabash-cucumber/keyboard_helpers.rb +97 -679
- data/lib/calabash-cucumber/launcher.rb +107 -31
- data/lib/calabash-cucumber/log_tailer.rb +46 -0
- data/lib/calabash-cucumber/map.rb +7 -1
- data/lib/calabash-cucumber/rotation_helpers.rb +47 -139
- data/lib/calabash-cucumber/status_bar_helpers.rb +51 -20
- data/lib/calabash-cucumber/store/preferences.rb +3 -0
- data/lib/calabash-cucumber/uia.rb +333 -2
- data/lib/calabash-cucumber/usage_tracker.rb +2 -0
- data/lib/calabash-cucumber/version.rb +2 -2
- data/lib/calabash-cucumber/wait_helpers.rb +2 -0
- data/lib/calabash/formatters/html.rb +6 -1
- data/lib/frank-calabash.rb +10 -4
- data/scripts/.irbrc +3 -0
- data/staticlib/calabash.framework.zip +0 -0
- data/staticlib/libFrankCalabash.a +0 -0
- metadata +11 -6
- data/lib/calabash-cucumber/actions/instruments_actions.rb +0 -155
@@ -4,7 +4,13 @@ module Calabash
|
|
4
4
|
# Contains methods for interacting with the status bar.
|
5
5
|
module StatusBarHelpers
|
6
6
|
|
7
|
-
|
7
|
+
require "calabash-cucumber/map"
|
8
|
+
|
9
|
+
require "calabash-cucumber/connection_helpers"
|
10
|
+
include Calabash::Cucumber::ConnectionHelpers
|
11
|
+
|
12
|
+
# Returns the device orientation as reported by
|
13
|
+
# `[[UIDevice currentDevice] orientation]`.
|
8
14
|
#
|
9
15
|
# @note This method is not used internally by the gem. It is provided
|
10
16
|
# as an alternative to `status_bar_orientation`. We recommend that you
|
@@ -16,25 +22,10 @@ module Calabash
|
|
16
22
|
# @see #status_bar_orientation
|
17
23
|
# @see Calabash::Cucumber::RotationHelpers#rotate_home_button_to
|
18
24
|
#
|
19
|
-
# @param [Boolean] force_down if true, do rotations until a down
|
20
|
-
# orientation is achieved
|
21
25
|
# @return [Symbol] Returns the device orientation as one of
|
22
|
-
# `{
|
23
|
-
def device_orientation
|
24
|
-
|
25
|
-
|
26
|
-
if ['face up', 'face down'].include?(res)
|
27
|
-
if force_down
|
28
|
-
puts "WARN found orientation '#{res}' - will rotate to force orientation to 'down'"
|
29
|
-
end
|
30
|
-
|
31
|
-
return res unless force_down
|
32
|
-
return rotate_home_button_to :down
|
33
|
-
end
|
34
|
-
|
35
|
-
return res unless res.eql?('unknown')
|
36
|
-
return res unless force_down
|
37
|
-
rotate_home_button_to(:down)
|
26
|
+
# `{'down', 'up', 'left', 'right', 'face up', 'face down', 'unknown'}`.
|
27
|
+
def device_orientation
|
28
|
+
Map.map(nil, :orientation, :device).first
|
38
29
|
end
|
39
30
|
|
40
31
|
# Returns the home button position relative to the status bar.
|
@@ -50,6 +41,47 @@ module Calabash
|
|
50
41
|
Map.map(nil, :orientation, :status_bar).first
|
51
42
|
end
|
52
43
|
|
44
|
+
# Returns details about the status bar like the frame, its visibility,
|
45
|
+
# and orientation.
|
46
|
+
#
|
47
|
+
# Requires calabash server 0.20.0.
|
48
|
+
def status_bar_details
|
49
|
+
result = http({:method => :get, :raw => true, :path => "statusBar"})
|
50
|
+
if result == ""
|
51
|
+
RunLoop::log_debug("status_bar_details is only available in Calabash iOS >= 0.20.0")
|
52
|
+
RunLoop::log_debug("Using default status bar details based on orientation.")
|
53
|
+
|
54
|
+
if portrait?
|
55
|
+
{
|
56
|
+
"frame" => {
|
57
|
+
"y" => 0,
|
58
|
+
"height" => 20,
|
59
|
+
"width" => 375,
|
60
|
+
"x" => 0
|
61
|
+
},
|
62
|
+
"hidden" => false,
|
63
|
+
"orientation" => status_bar_orientation,
|
64
|
+
"warning" => "These are default values. Update the server to 0.20.0"
|
65
|
+
}
|
66
|
+
else
|
67
|
+
{
|
68
|
+
"frame" => {
|
69
|
+
"y" => 0,
|
70
|
+
"height" => 10,
|
71
|
+
"width" => 375,
|
72
|
+
"x" => 0
|
73
|
+
},
|
74
|
+
"hidden" => false,
|
75
|
+
"orientation" => status_bar_orientation,
|
76
|
+
"warning" => "These are default values. Update the server to 0.20.0"
|
77
|
+
}
|
78
|
+
end
|
79
|
+
else
|
80
|
+
hash = JSON.parse(result)
|
81
|
+
hash["results"]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
53
85
|
# Is the device in the portrait orientation?
|
54
86
|
#
|
55
87
|
# @return [Boolean] Returns true if the device is in the 'up' or 'down'
|
@@ -67,7 +99,6 @@ module Calabash
|
|
67
99
|
o = status_bar_orientation
|
68
100
|
o.eql?('right') or o.eql?('left')
|
69
101
|
end
|
70
|
-
|
71
102
|
end
|
72
103
|
end
|
73
104
|
end
|
@@ -11,16 +11,19 @@ module Calabash
|
|
11
11
|
class Preferences
|
12
12
|
require "calabash-cucumber/dot_dir"
|
13
13
|
|
14
|
+
# @!visibility private
|
14
15
|
def initialize
|
15
16
|
dot_dir = Calabash::Cucumber::DotDir.directory
|
16
17
|
@path = File.join(dot_dir, "preferences", "preferences.json")
|
17
18
|
end
|
18
19
|
|
20
|
+
# @!visibility private
|
19
21
|
def to_s
|
20
22
|
puts "Preferences:"
|
21
23
|
ap read
|
22
24
|
end
|
23
25
|
|
26
|
+
# @!visibility private
|
24
27
|
def inspect
|
25
28
|
to_s
|
26
29
|
end
|
@@ -16,7 +16,7 @@ module Calabash
|
|
16
16
|
|
17
17
|
# UIA only makes sense if there is a run loop
|
18
18
|
launcher = Calabash::Cucumber::Launcher.launcher_if_used
|
19
|
-
run_loop = launcher && launcher.
|
19
|
+
run_loop = launcher && launcher.attached_to_automator? && launcher.run_loop
|
20
20
|
|
21
21
|
# Automatically attach in the calabash console
|
22
22
|
if !run_loop && defined?(IRB)
|
@@ -307,6 +307,47 @@ module Calabash
|
|
307
307
|
uia("target.setDeviceOrientation(#{uia_orientation})")
|
308
308
|
end
|
309
309
|
|
310
|
+
# Used for detecting keyboards that are not normally visible to calabash;
|
311
|
+
# e.g. the keyboard on the `MFMailComposeViewController`
|
312
|
+
#
|
313
|
+
# @note
|
314
|
+
# IMPORTANT this should only be used when the app does not respond to
|
315
|
+
# `keyboard_visible?` and UIAutomation is being used.
|
316
|
+
#
|
317
|
+
# @see #keyboard_visible?
|
318
|
+
#
|
319
|
+
# @raise [RuntimeError] If the app was not launched with instruments
|
320
|
+
def uia_keyboard_visible?
|
321
|
+
res = uia_query_windows(:keyboard)
|
322
|
+
res != ":nil"
|
323
|
+
end
|
324
|
+
|
325
|
+
# Waits for a keyboard that is not normally visible to calabash;
|
326
|
+
# e.g. the keyboard on `MFMailComposeViewController`.
|
327
|
+
#
|
328
|
+
# @note
|
329
|
+
# IMPORTANT this should only be used when the app does not respond to
|
330
|
+
# `keyboard_visible?` and UIAutomation is being used.
|
331
|
+
#
|
332
|
+
# @see #keyboard_visible?
|
333
|
+
#
|
334
|
+
# @raise [RuntimeError] if the app was not launched with instruments
|
335
|
+
def uia_wait_for_keyboard(options={})
|
336
|
+
default_opts = {
|
337
|
+
:timeout => 10,
|
338
|
+
:retry_frequency => 0.1,
|
339
|
+
:post_timeout => 0.5,
|
340
|
+
:timeout_message => "Keyboard did not appear"
|
341
|
+
}
|
342
|
+
|
343
|
+
options = default_opts.merge(options)
|
344
|
+
|
345
|
+
wait_for(options) do
|
346
|
+
uia_keyboard_visible?
|
347
|
+
end
|
348
|
+
true
|
349
|
+
end
|
350
|
+
|
310
351
|
# @!visibility private
|
311
352
|
def uia_type_string(string, opt_text_before='', escape=true)
|
312
353
|
result = uia_handle_command(:typeString, string, opt_text_before)
|
@@ -337,6 +378,7 @@ module Calabash
|
|
337
378
|
end
|
338
379
|
end
|
339
380
|
|
381
|
+
# @!visibility private
|
340
382
|
def uia_type_string_raw(str)
|
341
383
|
uia("uia.keyboard().typeString('#{str}')")
|
342
384
|
end
|
@@ -404,7 +446,6 @@ module Calabash
|
|
404
446
|
end
|
405
447
|
|
406
448
|
uia_result(uia(command))
|
407
|
-
|
408
449
|
end
|
409
450
|
|
410
451
|
# @!visibility private
|
@@ -459,6 +500,7 @@ module Calabash
|
|
459
500
|
end
|
460
501
|
|
461
502
|
private
|
503
|
+
|
462
504
|
def validate_hash_is_location!(options)
|
463
505
|
return if options[:latitude] and options[:longitude]
|
464
506
|
if (options[:latitude] and not options[:longitude]) ||
|
@@ -483,3 +525,292 @@ module Calabash
|
|
483
525
|
end
|
484
526
|
end
|
485
527
|
end
|
528
|
+
|
529
|
+
module Calabash::Cucumber::UIA
|
530
|
+
|
531
|
+
# @!visibility private
|
532
|
+
def self.redefine_instance_methods_if_necessary(xcode, automator=nil)
|
533
|
+
return if Calabash::Cucumber::Environment.xtc?
|
534
|
+
|
535
|
+
if xcode.version_gte_8?
|
536
|
+
reason = "UIAutomation is not available in Xcode >= 8.0."
|
537
|
+
return self.redefine_instance_methods_to_raise(reason)
|
538
|
+
end
|
539
|
+
|
540
|
+
if automator && automator.name == :device_agent
|
541
|
+
reason = "UIAutomation is not available when testing with DeviceAgent."
|
542
|
+
return self.redefine_instance_methods_to_raise(reason)
|
543
|
+
end
|
544
|
+
end
|
545
|
+
|
546
|
+
# @!visibility private
|
547
|
+
def self.redefine_instance_methods_to_raise(reason)
|
548
|
+
methods = Calabash::Cucumber::UIA.instance_methods
|
549
|
+
methods.each do |method_name|
|
550
|
+
Calabash::Cucumber::UIA.send(:remove_method, method_name)
|
551
|
+
|
552
|
+
Calabash::Cucumber::UIA.send(:define_method, method_name) do |*args|
|
553
|
+
|
554
|
+
case method_name
|
555
|
+
when :uia
|
556
|
+
raise RuntimeError, %Q[
|
557
|
+
|
558
|
+
#{reason}
|
559
|
+
|
560
|
+
#{method_name} has been removed from the Calabash API.
|
561
|
+
|
562
|
+
It is not possible to make raw UIAutomation JavaScript calls.
|
563
|
+
|
564
|
+
If you are trying to make query, use the DeviceAgent query API.
|
565
|
+
|
566
|
+
device_agent.query({type: "TextField", index:1})
|
567
|
+
device_agent.query({marked: "Cancel"})
|
568
|
+
|
569
|
+
If you are trying to perform a gesture or enter text, in most cases the normal
|
570
|
+
Core method will work. If a normal Core method does work, try the DeviceAgent
|
571
|
+
Gesture API.
|
572
|
+
|
573
|
+
device_agent.touch({type: "TextField", index:1})
|
574
|
+
device_agent.touch({marked: "Button"})
|
575
|
+
|
576
|
+
If you cannot find an equivalent DeviceAgent workaround, please create an issue
|
577
|
+
and include:
|
578
|
+
|
579
|
+
1. At a high level, what you are trying to do.
|
580
|
+
2. The JavaScript you are trying to invoke.
|
581
|
+
|
582
|
+
Links:
|
583
|
+
|
584
|
+
* http://calabashapi.xamarin.com/ios/Calabash/Cucumber/DeviceAgent.html
|
585
|
+
* https://github.com/calabash/calabash-ios/issues
|
586
|
+
]
|
587
|
+
when :uia_call, :uia_call_windows, :uia_call_method, :uia_names
|
588
|
+
raise RuntimeError, %Q[
|
589
|
+
|
590
|
+
#{reason}
|
591
|
+
|
592
|
+
#{method_name} has been removed from the Calabash API.
|
593
|
+
|
594
|
+
There is no suggested workaround for this method. Please review the DeviceAgent
|
595
|
+
API for a replacement. If you can find no replacement, please create an issue
|
596
|
+
and include:
|
597
|
+
|
598
|
+
If you are trying to make query, use the DeviceAgent query API.
|
599
|
+
|
600
|
+
device_agent.query({type: "TextField", index:1})
|
601
|
+
device_agent.query({marked: "Cancel"})
|
602
|
+
|
603
|
+
If you are trying to perform a gesture or enter text, in most cases the normal
|
604
|
+
Core method will work. If a normal Core method does work, try the DeviceAgent
|
605
|
+
Gesture API.
|
606
|
+
|
607
|
+
device_agent.touch({type: "TextField", index:1})
|
608
|
+
device_agent.touch({marked: "Button"})
|
609
|
+
|
610
|
+
If you cannot find an equivalent DeviceAgent workaround, please create an issue
|
611
|
+
and include:
|
612
|
+
|
613
|
+
1. At a high level, what you are trying to do.
|
614
|
+
2. The method you are invoking with the arguments.
|
615
|
+
|
616
|
+
Links:
|
617
|
+
|
618
|
+
* http://calabashapi.xamarin.com/ios/Calabash/Cucumber/DeviceAgent.html
|
619
|
+
* https://github.com/calabash/calabash-ios/issues
|
620
|
+
]
|
621
|
+
when :uia_element_exists?, :uia_element_does_not_exist?
|
622
|
+
raise RuntimeError, %Q[
|
623
|
+
|
624
|
+
#{reason}
|
625
|
+
|
626
|
+
#{method_name} has been removed from the Calabash API.
|
627
|
+
|
628
|
+
Use the DeviceAgent wait API.
|
629
|
+
|
630
|
+
device_agent.wait_for_view({marked: "Cancel"})
|
631
|
+
device_agent.wait_for_no_view({marked: "Cancel"})
|
632
|
+
|
633
|
+
]
|
634
|
+
when :uia_query, :uia_query_el
|
635
|
+
raise RuntimeError, %Q[
|
636
|
+
|
637
|
+
#{reason}
|
638
|
+
|
639
|
+
#{method_name} has been removed from the Calabash API.
|
640
|
+
|
641
|
+
Use the DeviceAgent query API.
|
642
|
+
|
643
|
+
device_agent.query({marked: "Cancel"})
|
644
|
+
device_agent.query({type: "TextField", index:1})
|
645
|
+
|
646
|
+
]
|
647
|
+
|
648
|
+
when :uia_query_windows
|
649
|
+
|
650
|
+
raise RuntimeError, %Q[
|
651
|
+
|
652
|
+
#{reason}
|
653
|
+
|
654
|
+
#{method_name} has been removed from the Calabash API.
|
655
|
+
|
656
|
+
Try to use the DeviceAgent query API.
|
657
|
+
|
658
|
+
device_agent.query({marked: "Cancel"})
|
659
|
+
device_agent.query({type: "TextField", index:1})
|
660
|
+
|
661
|
+
If the DeviceAgent query API does not find the correct views, please create an
|
662
|
+
issue and include:
|
663
|
+
|
664
|
+
1. At a high level, what you are trying to do.
|
665
|
+
2. The method you are invoking with the arguments.
|
666
|
+
|
667
|
+
]
|
668
|
+
when :uia_screenshot
|
669
|
+
raise RuntimeError, %Q[
|
670
|
+
|
671
|
+
#{reason}
|
672
|
+
|
673
|
+
#{method_name} has been removed from the Calabash API.
|
674
|
+
|
675
|
+
There is no replacement for this method.
|
676
|
+
|
677
|
+
Please create an issue and include:
|
678
|
+
|
679
|
+
1. At a high level, what you are trying to do.
|
680
|
+
2. A screenshot of the view you are trying capture.
|
681
|
+
|
682
|
+
]
|
683
|
+
when :uia_orientation, :uia_rotate_home_button_to, :uia_rotate
|
684
|
+
raise RuntimeError, %Q[
|
685
|
+
|
686
|
+
#{reason}
|
687
|
+
|
688
|
+
#{method_name} has been removed from the Calabash API.
|
689
|
+
|
690
|
+
You should not be calling this method. Always call the orientation methods
|
691
|
+
defined in the Core API.
|
692
|
+
|
693
|
+
]
|
694
|
+
when :uia_type_string, :uia_type_string_raw, :uia_enter, :uia_set_responder_value
|
695
|
+
raise RuntimeError, %Q[
|
696
|
+
|
697
|
+
#{reason}
|
698
|
+
|
699
|
+
#{method_name} has been removed from the Calabash API.
|
700
|
+
|
701
|
+
In general, you should use the the text input methods defined in Core.
|
702
|
+
|
703
|
+
In some cases you will need to use the DeviceAgent query and keyboard API.
|
704
|
+
|
705
|
+
device_agent.touch({type: "TextField", index: 1})
|
706
|
+
wait_for_keyboard
|
707
|
+
keyboard_enter_text("Hello")
|
708
|
+
|
709
|
+
It is important to note that the DeviceAgent implementations of:
|
710
|
+
|
711
|
+
* keyboard_enter_text
|
712
|
+
* keyboard_enter_char
|
713
|
+
* enter_text_in
|
714
|
+
* enter_text
|
715
|
+
* fast_enter_text
|
716
|
+
|
717
|
+
have exactly the same performance.
|
718
|
+
|
719
|
+
You should prefer `enter_text` or `enter_text_in` because it matches the
|
720
|
+
Calabash 2.0 API.
|
721
|
+
|
722
|
+
]
|
723
|
+
when :uia_set_location
|
724
|
+
raise RuntimeError, %Q[
|
725
|
+
|
726
|
+
#{reason}
|
727
|
+
|
728
|
+
#{method_name} has been removed from the Calabash API.
|
729
|
+
|
730
|
+
This method has been broken for various iOS versions and device combinations
|
731
|
+
for years.
|
732
|
+
|
733
|
+
At the moment, we do not have replacement for location spoofing with DeviceAgent.
|
734
|
+
|
735
|
+
]
|
736
|
+
when :uia_send_app_to_background
|
737
|
+
raise RuntimeError, %Q[
|
738
|
+
|
739
|
+
#{reason}
|
740
|
+
|
741
|
+
#{method_name} has been removed from the Calabash API.
|
742
|
+
|
743
|
+
You should not use this method. If the Core send_app_to_background is not
|
744
|
+
working under UIAutomation, please create a GitHub issue.
|
745
|
+
|
746
|
+
https://github.com/calabash/calabash-ios/issues
|
747
|
+
|
748
|
+
]
|
749
|
+
when :uia_keyboard_visible?, :uia_wait_for_keyboard
|
750
|
+
raise RuntimeError, %Q[
|
751
|
+
|
752
|
+
#{reason}
|
753
|
+
|
754
|
+
#{method_name} has been removed from the Calabash API.
|
755
|
+
|
756
|
+
We have not found a case (yet) where the the Core keyboard_visible? and
|
757
|
+
wait_for_keyboard methods do not work when using DeviceAgent. If you find a
|
758
|
+
case where the Core methods do not work, please create a GitHub issue.
|
759
|
+
|
760
|
+
The current DeviceAgent keyboard API is scheduled for removal. It is crucial
|
761
|
+
that you report workflows that require the DeviceAgent keyboard API.
|
762
|
+
|
763
|
+
device_agent.keyboard_visible?
|
764
|
+
wait_for { device_agent.keyboard_visible? }
|
765
|
+
|
766
|
+
https://github.com/calabash/calabash-ios/issues
|
767
|
+
|
768
|
+
]
|
769
|
+
when :uia_handle_command, :uia_serialize_command,
|
770
|
+
:uia_serialize_arguments, :uia_serialize_argument,
|
771
|
+
:escape_uia_string, :send_uia_command
|
772
|
+
raise RuntimeError, %Q[
|
773
|
+
|
774
|
+
#{reason}
|
775
|
+
|
776
|
+
#{method_name} has been removed from the Calabash API.
|
777
|
+
|
778
|
+
There is no replacement.
|
779
|
+
|
780
|
+
]
|
781
|
+
when :uia_tap, :uia_tap_mark, :uia_tap_offset,
|
782
|
+
:uia_double_tap, :uia_double_tap_mark, :uia_double_tap_offset,
|
783
|
+
:uia_two_finger_tap, :uia_two_finger_tap_offset,
|
784
|
+
:uia_touch_hold, :uia_touch_hold_offset,
|
785
|
+
:uia_pan, :uia_pan_offset,
|
786
|
+
:uia_swipe, :uia_swipe_offset, :uia_flick_offset,
|
787
|
+
:uia_drag_inside, :uia_drag_inside_mark,
|
788
|
+
:uia_pinch, :uia_pinch_offset, :uia_scroll_to
|
789
|
+
raise RuntimeError, %Q[
|
790
|
+
|
791
|
+
#{reason}
|
792
|
+
|
793
|
+
#{method_name} has been removed from the Calabash API.
|
794
|
+
|
795
|
+
DeviceAgent is our replacement for UIAutomation. In most cases, you will not
|
796
|
+
need to use a special DeviceAgent gesture method like you did with UIAutomation.
|
797
|
+
|
798
|
+
If a Core gesture method does not work, there is a DeviceAgent gesture API.
|
799
|
+
|
800
|
+
device_agent.touch({type: "Button", marked: "Back"})
|
801
|
+
|
802
|
+
For UIA pan gestures (flick, swipe, pan) use pan_coordinates.
|
803
|
+
|
804
|
+
from_point = device_agent.query_for_coordinate({marked: "From"})
|
805
|
+
to_point = device_agent.query_for_coordinate({marked: "To"})
|
806
|
+
pan_coordinates(from_point, to_point)
|
807
|
+
|
808
|
+
]
|
809
|
+
else
|
810
|
+
raise ArgumentError, "This #{method_name} has not been handled"
|
811
|
+
end
|
812
|
+
end
|
813
|
+
end
|
814
|
+
true
|
815
|
+
end
|
816
|
+
end
|