calabash-cucumber 0.19.2 → 0.20.0
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.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
|