calabash 2.0.0.pre10 → 2.0.0.pre11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -17
  3. data/bin/calabash +3 -4
  4. data/lib/calabash.rb +53 -10
  5. data/lib/calabash/android.rb +89 -28
  6. data/lib/calabash/android/adb.rb +32 -20
  7. data/lib/calabash/android/application.rb +1 -1
  8. data/lib/calabash/android/build/builder.rb +1 -1
  9. data/lib/calabash/android/build/java_keystore.rb +1 -1
  10. data/lib/calabash/android/build/resigner.rb +1 -1
  11. data/lib/calabash/android/device.rb +22 -66
  12. data/lib/calabash/android/device/helper_application.rb +95 -0
  13. data/lib/calabash/android/environment.rb +14 -1
  14. data/lib/calabash/android/gestures.rb +6 -22
  15. data/lib/calabash/android/interactions.rb +14 -17
  16. data/lib/calabash/android/lib/.irbrc +9 -1
  17. data/lib/calabash/android/lib/AndroidManifest.xml +23 -2
  18. data/lib/calabash/android/lib/HelperApplication.apk +0 -0
  19. data/lib/calabash/android/lib/HelperApplicationTestServer.apk +0 -0
  20. data/lib/calabash/android/lib/TestServer.apk +0 -0
  21. data/lib/calabash/android/life_cycle.rb +3 -3
  22. data/lib/calabash/android/orientation.rb +8 -8
  23. data/lib/calabash/android/physical_buttons.rb +19 -16
  24. data/lib/calabash/android/server.rb +1 -1
  25. data/lib/calabash/android/text.rb +12 -12
  26. data/lib/calabash/android/web.rb +12 -0
  27. data/lib/calabash/application.rb +3 -0
  28. data/lib/calabash/cli/generate.rb +8 -18
  29. data/lib/calabash/cli/helpers.rb +4 -9
  30. data/lib/calabash/cli/run.rb +1 -1
  31. data/lib/calabash/console_helpers.rb +179 -11
  32. data/lib/calabash/device.rb +4 -19
  33. data/lib/calabash/gestures.rb +292 -198
  34. data/lib/calabash/interactions.rb +3 -40
  35. data/lib/calabash/internal.rb +48 -0
  36. data/lib/calabash/ios.rb +76 -16
  37. data/lib/calabash/ios/automator.rb +9 -0
  38. data/lib/calabash/ios/automator/automator.rb +217 -0
  39. data/lib/calabash/ios/automator/coordinates.rb +37 -0
  40. data/lib/calabash/ios/automator/device_agent.rb +379 -0
  41. data/lib/calabash/ios/conditions.rb +1 -1
  42. data/lib/calabash/ios/console_helpers.rb +2 -2
  43. data/lib/calabash/ios/date_picker.rb +10 -8
  44. data/lib/calabash/ios/device.rb +0 -1
  45. data/lib/calabash/ios/device/device_implementation.rb +9 -21
  46. data/lib/calabash/ios/device/gestures_mixin.rb +53 -55
  47. data/lib/calabash/ios/device/keyboard_mixin.rb +21 -0
  48. data/lib/calabash/ios/device/rotation_mixin.rb +3 -65
  49. data/lib/calabash/ios/gestures.rb +24 -90
  50. data/lib/calabash/ios/interactions.rb +1 -6
  51. data/lib/calabash/ios/lib/.irbrc +9 -2
  52. data/lib/calabash/ios/orientation.rb +8 -8
  53. data/lib/calabash/ios/runtime.rb +14 -14
  54. data/lib/calabash/ios/scroll.rb +25 -17
  55. data/lib/calabash/ios/slider.rb +11 -18
  56. data/lib/calabash/ios/text.rb +20 -74
  57. data/lib/calabash/ios/uia.rb +1 -1
  58. data/lib/calabash/ios/web.rb +10 -0
  59. data/lib/calabash/lib/skeleton/{Gemfile → Gemfile.skeleton} +0 -0
  60. data/lib/calabash/lib/skeleton/config/{cucumber.yml → cucumber.yml.skeleton} +0 -0
  61. data/lib/calabash/lib/skeleton/features/{sample.feature → sample.feature.skeleton} +0 -0
  62. data/lib/calabash/lib/skeleton/features/step_definitions/{calabash_steps.rb → sample_steps.rb.skeleton} +8 -8
  63. data/lib/calabash/lib/skeleton/features/support/{dry_run.rb → dry_run.rb.skeleton} +2 -5
  64. data/lib/calabash/lib/skeleton/features/support/{env.rb → env.rb.skeleton} +2 -8
  65. data/lib/calabash/lib/skeleton/features/support/hooks.rb.skeleton +34 -0
  66. data/lib/calabash/life_cycle.rb +16 -8
  67. data/lib/calabash/location.rb +14 -15
  68. data/lib/calabash/orientation.rb +8 -8
  69. data/lib/calabash/page.rb +1 -4
  70. data/lib/calabash/retry.rb +33 -0
  71. data/lib/calabash/screenshot.rb +3 -3
  72. data/lib/calabash/stubs.rb +21 -0
  73. data/lib/calabash/text.rb +31 -19
  74. data/lib/calabash/utility.rb +41 -8
  75. data/lib/calabash/version.rb +1 -1
  76. data/lib/calabash/wait.rb +177 -192
  77. data/lib/calabash/web.rb +44 -0
  78. metadata +39 -32
  79. data/lib/calabash/ios/device/text_mixin.rb +0 -21
  80. data/lib/calabash/lib/skeleton/features/support/hooks.rb +0 -83
@@ -13,7 +13,7 @@ module Calabash
13
13
  # in the background
14
14
  # @raise [ArgumentError] If number of seconds is less than 1 and more
15
15
  # than 60 seconds.
16
- def _send_current_app_to_background(seconds)
16
+ define_method(:_send_current_app_to_background) do |seconds|
17
17
  unless (1..60).member?(seconds)
18
18
  raise ArgumentError,
19
19
  "Number of seconds: '#{seconds}' must be between 1 and 60"
@@ -30,11 +30,6 @@ module Calabash
30
30
  )
31
31
  uia(javascript)
32
32
  end
33
-
34
- # @!visibility private
35
- def _evaluate_javascript_in(query, javascript)
36
- query(query, calabashStringByEvaluatingJavaScript: javascript)
37
- end
38
33
  end
39
34
  end
40
35
  end
@@ -37,10 +37,17 @@ rescue LoadError => e
37
37
  end
38
38
 
39
39
  begin
40
-
41
40
  require 'calabash/ios'
42
41
 
43
- extend Calabash::IOS
42
+ IRB.conf[:PROMPT][:CALABASH] = {
43
+ :PROMPT_I => "calabash #{Calabash::VERSION}> ",
44
+ :PROMPT_S => "%03n> ",
45
+ :PROMPT_C => "%03n> ",
46
+ :RETURN => "%s\n"
47
+ }
48
+
49
+ IRB.conf[:PROMPT_MODE] = :CALABASH
50
+
44
51
  extend Calabash::ConsoleHelpers
45
52
 
46
53
  Calabash::IOS.setup_defaults!
@@ -13,7 +13,7 @@ module Calabash
13
13
  # @return [String] Returns the device orientation as one of
14
14
  # `{'down' | 'up' | 'left' | 'right'}`.
15
15
  def status_bar_orientation
16
- Device.default.status_bar_orientation
16
+ Calabash::Internal.with_default_device(required_os: :ios) {|device| device.status_bar_orientation}
17
17
  end
18
18
 
19
19
  # Rotate the device left - clockwise relative to the home button.
@@ -26,7 +26,7 @@ module Calabash
26
26
  # @return [String] The position of the home button relative to the status
27
27
  # bar after the rotation. Can be one of 'down', 'left', 'right', 'up'.
28
28
  def rotate_device_left
29
- Device.default.rotate(:left)
29
+ Calabash::Internal.with_default_device(required_os: :ios) {|device| device.rotate(:left)}
30
30
  status_bar_orientation
31
31
  end
32
32
 
@@ -40,7 +40,7 @@ module Calabash
40
40
  # @return [String] The position of the home button relative to the status
41
41
  # bar after the rotation. Can be one of 'down', 'left', 'right', 'up'.
42
42
  def rotate_device_right
43
- Device.default.rotate(:right)
43
+ Calabash::Internal.with_default_device(required_os: :ios) {|device| device.rotate(:right)}
44
44
  status_bar_orientation
45
45
  end
46
46
 
@@ -83,11 +83,11 @@ module Calabash
83
83
  canonical_position = :down if position.to_sym == :bottom
84
84
  canonical_position = :up if position.to_sym == :top
85
85
 
86
- Calabash::Device.default.rotate_home_button_to(canonical_position)
86
+ Calabash::Internal.with_default_device(required_os: :ios) {|device| device.rotate_home_button_to(canonical_position)}
87
87
  end
88
88
 
89
89
  # @!visibility private
90
- def _set_orientation_landscape
90
+ define_method(:_set_orientation_landscape) do
91
91
  orientation = status_bar_orientation
92
92
  return orientation if landscape?
93
93
 
@@ -95,7 +95,7 @@ module Calabash
95
95
  end
96
96
 
97
97
  # @!visibility private
98
- def _set_orientation_portrait
98
+ define_method(:_set_orientation_portrait) do
99
99
  orientation = status_bar_orientation
100
100
  return orientation if portrait?
101
101
 
@@ -103,13 +103,13 @@ module Calabash
103
103
  end
104
104
 
105
105
  # @!visibility private
106
- def _portrait?
106
+ define_method(:_portrait?) do
107
107
  orientation = status_bar_orientation
108
108
  orientation.eql?('up') || orientation.eql?('down')
109
109
  end
110
110
 
111
111
  # @!visibility private
112
- def _landscape?
112
+ define_method(:_landscape?) do
113
113
  orientation = status_bar_orientation
114
114
  orientation.eql?('right') || orientation.eql?('left')
115
115
  end
@@ -11,27 +11,27 @@ module Calabash
11
11
 
12
12
  # Is the device under test a simulator?
13
13
  def simulator?
14
- Calabash::IOS::Device.default.simulator?
14
+ Calabash::Internal.with_default_device(required_os: :ios) {|device| device.simulator?}
15
15
  end
16
16
 
17
17
  # Is the device under test a physical device?
18
18
  def physical_device?
19
- Calabash::IOS::Device.default.physical_device?
19
+ Calabash::Internal.with_default_device(required_os: :ios) {|device| device.physical_device?}
20
20
  end
21
21
 
22
22
  # Is the device under test an iPad?
23
23
  def ipad?
24
- Calabash::IOS::Device.default.device_family == 'iPad'
24
+ Calabash::Internal.with_default_device(required_os: :ios) {|device| device.device_family == 'iPad'}
25
25
  end
26
26
 
27
27
  # Is the device under test an iPhone?
28
28
  def iphone?
29
- Calabash::IOS::Device.default.device_family == 'iPhone'
29
+ Calabash::Internal.with_default_device(required_os: :ios) {|device| device.device_family == 'iPhone'}
30
30
  end
31
31
 
32
32
  # Is the device under test an iPod?
33
33
  def ipod?
34
- Calabash::IOS::Device.default.device_family == 'iPod'
34
+ Calabash::Internal.with_default_device(required_os: :ios) {|device| device.device_family == 'iPod'}
35
35
  end
36
36
 
37
37
  # Is the device under test an iPhone or iPod?
@@ -44,22 +44,22 @@ module Calabash
44
44
  # An iPhone only app running on an iPad will be displayed in an emulated
45
45
  # mode. Starting in iOS 7, such apps will always be launched in 2x mode.
46
46
  def iphone_app_emulated_on_ipad?
47
- Calabash::IOS::Device.default.iphone_app_emulated_on_ipad?
47
+ Calabash::Internal.with_default_device(required_os: :ios) {|device| device.iphone_app_emulated_on_ipad?}
48
48
  end
49
49
 
50
50
  # Is the device under test have a 4 inch screen?
51
51
  def iphone_4in?
52
- Calabash::IOS::Device.default.form_factor == 'iphone 4in'
52
+ Calabash::Internal.with_default_device(required_os: :ios) {|device| device.form_factor == 'iphone 4in'}
53
53
  end
54
54
 
55
55
  # Is the device under test an iPhone 6.
56
56
  def iphone_6?
57
- Calabash::IOS::Device.default.form_factor == 'iphone 6'
57
+ Calabash::Internal.with_default_device(required_os: :ios) {|device| device.form_factor == 'iphone 6'}
58
58
  end
59
59
 
60
60
  # Is the device under test an iPhone 6+?
61
61
  def iphone_6_plus?
62
- Calabash::IOS::Device.default.form_factor == 'iphone 6 +'
62
+ Calabash::Internal.with_default_device(required_os: :ios) {|device| device.form_factor == 'iphone 6 +'}
63
63
  end
64
64
 
65
65
  # Is the device under test an iPhone 3.5in?
@@ -72,7 +72,7 @@ module Calabash
72
72
  # @see #iphone_app_emulated_on_ipad?
73
73
  # @see #ipad?
74
74
  def iphone_35in?
75
- Calabash::IOS::Device.default.form_factor == 'iphone 3.5in'
75
+ Calabash::Internal.with_default_device(required_os: :ios) {|device| device.form_factor == 'iphone 3.5in'}
76
76
  end
77
77
 
78
78
  # The screen dimensions and details about scale and sample rates.
@@ -88,7 +88,7 @@ module Calabash
88
88
  #
89
89
  # @return [Hash] See the example.
90
90
  def app_screen_details
91
- Calabash::IOS::Device.default.screen_dimensions
91
+ Calabash::Internal.with_default_device(required_os: :ios) {|device| device.screen_dimensions}
92
92
  end
93
93
 
94
94
  # The version of iOS running on the test device.
@@ -100,7 +100,7 @@ module Calabash
100
100
  #
101
101
  # @return [RunLoop::Version] A version object.
102
102
  def ios_version
103
- Calabash::IOS::Device.default.ios_version
103
+ Calabash::Internal.with_default_device(required_os: :ios) {|device| device.ios_version}
104
104
  end
105
105
 
106
106
  # Is the device under test running iOS 6?
@@ -132,7 +132,7 @@ module Calabash
132
132
  #
133
133
  # @return [RunLoop::Version] A version object.
134
134
  def server_version
135
- Calabash::IOS::Device.default.server_version
135
+ Calabash::Internal.with_default_device(required_os: :ios) {|device| device.server_version}
136
136
  end
137
137
 
138
138
  # Details about the version of the app under test.
@@ -161,7 +161,7 @@ module Calabash
161
161
  # the methods in the {Calabash::IOS::Runtime} module instead.
162
162
  # @return[Hash] Key/value pairs that describe the runtime environment.
163
163
  def runtime_details
164
- Calabash::IOS::Device.default.runtime_details
164
+ Calabash::Internal.with_default_device(required_os: :ios) {|device| device.runtime_details}
165
165
  end
166
166
  end
167
167
  end
@@ -71,7 +71,7 @@ module Calabash
71
71
  raise RuntimeError, e
72
72
  end
73
73
 
74
- results = Device.default.map_route(query, :scroll, direction)
74
+ results = Calabash::Internal.with_default_device(required_os: :ios) {|device| device.map_route(query, :scroll, direction)}
75
75
 
76
76
  if results.first.nil?
77
77
  fail("Expected '#{query}' to match a UIScrollView or a subclass")
@@ -153,8 +153,10 @@ module Calabash
153
153
  position = merged_options[:scroll_position].to_sym
154
154
  animate = merged_options[:animate]
155
155
 
156
- results = Device.default.map_route(query, :scrollToRow, row.to_i,
157
- section.to_i, position, animate)
156
+ results = Calabash::Internal.with_default_device(required_os: :ios) do |device|
157
+ device.map_route(query, :scrollToRow, row.to_i,
158
+ section.to_i, position, animate)
159
+ end
158
160
 
159
161
  if results.first.nil?
160
162
  message = [
@@ -240,8 +242,10 @@ module Calabash
240
242
  position = merged_options[:scroll_position].to_sym
241
243
  animate = merged_options[:animate]
242
244
 
243
- results = Device.default.map_route(query, :scrollToRowWithMark, mark,
244
- position, animate)
245
+ results = Calabash::Internal.with_default_device(required_os: :ios) do |device|
246
+ device.map_route(query, :scrollToRowWithMark, mark,
247
+ position, animate)
248
+ end
245
249
 
246
250
  if results.first.nil?
247
251
  message = [
@@ -334,9 +338,12 @@ module Calabash
334
338
  position = merged_options[:scroll_position].to_sym
335
339
  animate = merged_options[:animate]
336
340
 
337
- results = Device.default.map_route(query, :collectionViewScroll,
338
- item.to_i, section.to_i,
339
- position, animate)
341
+ results = Calabash::Internal.with_default_device(required_os: :ios) do |device|
342
+ device.map_route(query, :collectionViewScroll,
343
+ item.to_i, section.to_i,
344
+ position, animate)
345
+ end
346
+
340
347
  if results.first.nil?
341
348
  message = [
342
349
  "Could not scroll collection to item '#{item}' and section '#{section}'.",
@@ -427,9 +434,11 @@ module Calabash
427
434
  position = merged_options[:scroll_position].to_sym
428
435
  animate = merged_options[:animate]
429
436
 
430
- results = Device.default.map_route(query,
431
- :collectionViewScrollToItemWithMark,
432
- mark, position, animate)
437
+ results = Calabash::Internal.with_default_device(required_os: :ios) do |device|
438
+ device.map_route(query,
439
+ :collectionViewScrollToItemWithMark,
440
+ mark, position, animate)
441
+ end
433
442
 
434
443
  if results.first.nil?
435
444
  message = [
@@ -455,8 +464,7 @@ module Calabash
455
464
  :left, :center_horizontal, :right]
456
465
 
457
466
  # @!visibility private
458
- def _wait_for_exactly_one_scroll_view(query)
459
-
467
+ define_method(:_wait_for_exactly_one_scroll_view) do |query|
460
468
  results = []
461
469
 
462
470
  found_none = "Expected '#{query}' to match exactly one view, but found no matches."
@@ -477,7 +485,7 @@ module Calabash
477
485
  end
478
486
 
479
487
  # @!visibility private
480
- def _expect_valid_scroll_positions(valid_positions, position)
488
+ define_method(:_expect_valid_scroll_positions) do |valid_positions, position|
481
489
  unless valid_positions.include?(position.to_sym)
482
490
  raise ArgumentError,
483
491
  "Expected '#{position}' to be one of #{valid_positions.join(', ')}"
@@ -485,7 +493,7 @@ module Calabash
485
493
  end
486
494
 
487
495
  # @!visibility private
488
- def _expect_valid_scroll_animate(animate)
496
+ define_method(:_expect_valid_scroll_animate) do |animate|
489
497
  unless [true, false].include?(animate)
490
498
  raise ArgumentError,
491
499
  "Expected '#{animate}' to be a Boolean true or false"
@@ -493,13 +501,13 @@ module Calabash
493
501
  end
494
502
 
495
503
  # @!visibility private
496
- def _expect_valid_scroll_options(valid_positions, options)
504
+ define_method(:_expect_valid_scroll_options) do |valid_positions, options|
497
505
  _expect_valid_scroll_positions(valid_positions, options[:scroll_position])
498
506
  _expect_valid_scroll_animate(options[:animate])
499
507
  end
500
508
 
501
509
  # @!visibility private
502
- def _expect_valid_scroll_mark(mark)
510
+ define_method(:_expect_valid_scroll_mark) do |mark|
503
511
  if mark.nil? || mark == ''
504
512
  raise ArgumentError,
505
513
  if mark.nil?
@@ -16,34 +16,25 @@ module Calabash
16
16
  # * Use the index language feature: "UISlider index:0"
17
17
  #
18
18
  # @example
19
- # slider_set_value("UISlider marked:'office slider'", 2)
20
- # slider_set_value("slider marked:'weather slider'", -1)
21
- # slider_set_value("UISlider", 11)
19
+ # cal_ios.slider_set_value("UISlider marked:'office slider'", 2)
20
+ # cal_ios.slider_set_value("slider marked:'weather slider'", -1)
21
+ # cal_ios.slider_set_value("UISlider", 11)
22
22
  #
23
23
  # @param [String, Hash, Calabash::Query] query A query to that indicates
24
24
  # in which slider to set the value.
25
25
  # @param [Numeric] value The value to set the slider to. value.to_s should
26
26
  # produce a String representation of a Number.
27
- #
28
- # @param [options] options Options to control the behavior of the gesture.
29
- # @option options [Boolean] :animate (true) Animate the change.
30
- # @option options [Boolean] :notify_targets (true) Simulate a UIEvent by
27
+ # @param [Boolean] animate (default: true) Animate the change.
28
+ # @param [Boolean] notify_targets (default: true) simulate a UIEvent by
31
29
  # calling every target/action pair defined on the UISlider matching
32
30
  # `query`.
33
31
  #
34
32
  # @raise [RuntimeError] When `query` does not match exactly one slider.
35
33
  # @raise [RuntimeError] When setting the value of the slider matched by
36
34
  # `query` is not successful.
37
- def slider_set_value(query, value, options={})
35
+ def slider_set_value(query, value, animate: true, notify_targets: true)
38
36
  Query.ensure_valid_query(query)
39
37
 
40
- default_options = {
41
- :animate => true,
42
- :notify_targets => true
43
- }
44
-
45
- merged_options = default_options.merge(options)
46
-
47
38
  found_none = "Expected '#{query}' to match exactly one view, but found no matches."
48
39
  query_object = Query.new(query)
49
40
  wait_for(found_none) do
@@ -53,7 +44,7 @@ module Calabash
53
44
  "Expected '#{query}' to match exactly one view, but found '#{results.length}'",
54
45
  results.join("\n")
55
46
  ].join("\n")
56
- fail(message)
47
+ raise message
57
48
  else
58
49
  results.length == 1
59
50
  end
@@ -61,9 +52,11 @@ module Calabash
61
52
 
62
53
  value_str = value.to_s
63
54
 
64
- args = [merged_options[:animate], merged_options[:notify_targets]]
55
+ args = [animate, notify_targets]
65
56
 
66
- Device.default.map_route(query, :changeSlider, value_str, *args)
57
+ Calabash::Internal.with_default_device(required_os: :ios) do |device|
58
+ device.map_route(query, :changeSlider, value_str, *args)
59
+ end
67
60
  end
68
61
  end
69
62
  end
@@ -3,21 +3,21 @@ module Calabash
3
3
  # Methods for entering text and interacting with iOS keyboards.
4
4
  module Text
5
5
  # @!visibility private
6
- def _enter_text(text)
6
+ define_method(:_enter_text) do |text|
7
7
  wait_for_keyboard
8
8
  existing_text = text_from_keyboard_first_responder
9
9
  options = { existing_text: existing_text }
10
- Device.default.uia_type_string(text, options)
10
+ Calabash::Internal.with_default_device(required_os: :ios) {|device| device.enter_text(text, options)}
11
11
  end
12
12
 
13
13
  # @!visibility private
14
- def _enter_text_in(view, text)
14
+ define_method(:_enter_text_in) do |view, text|
15
15
  tap(view)
16
16
  enter_text(text)
17
17
  end
18
18
 
19
19
  # @!visibility private
20
- def _clear_text
20
+ define_method(:_clear_text) do
21
21
  unless view_exists?("* isFirstResponder:1")
22
22
  raise 'Cannot clear text. No view has focus'
23
23
  end
@@ -26,7 +26,7 @@ module Calabash
26
26
  end
27
27
 
28
28
  # @!visibility private
29
- def _clear_text_in(view)
29
+ define_method(:_clear_text_in) do |view|
30
30
  unless keyboard_visible?
31
31
  tap(view)
32
32
  wait_for_keyboard
@@ -35,6 +35,7 @@ module Calabash
35
35
  unless wait_for_view(view)['text'].empty?
36
36
  tap(view)
37
37
  tap("UICalloutBarButton marked:'Select All'")
38
+ sleep 0.5
38
39
  tap_keyboard_delete_key
39
40
  end
40
41
 
@@ -49,7 +50,7 @@ module Calabash
49
50
  #
50
51
  # @return [Boolean] Returns true if a keyboard is visible and docked.
51
52
  def docked_keyboard_visible?
52
- Device.default.docked_keyboard_visible?
53
+ Calabash::Internal.with_default_device(required_os: :ios) {|device| device.docked_keyboard_visible?}
53
54
  end
54
55
 
55
56
  # Returns true if an undocked keyboard is visible.
@@ -59,7 +60,7 @@ module Calabash
59
60
  # @return [Boolean] Returns false if the device is not an iPad; all
60
61
  # keyboards on the iPhone and iPod are docked.
61
62
  def undocked_keyboard_visible?
62
- Device.default.undocked_keyboard_visible?
63
+ Calabash::Internal.with_default_device(required_os: :ios) {|device| device.undocked_keyboard_visible?}
63
64
  end
64
65
 
65
66
  # Returns true if a split keyboard is visible.
@@ -70,7 +71,7 @@ module Calabash
70
71
  # @return [Boolean] Returns false if the device is not an iPad; all
71
72
  # keyboards on the Phone and iPod are docked and not split.
72
73
  def split_keyboard_visible?
73
- Device.default.split_keyboard_visible?
74
+ Calabash::Internal.with_default_device(required_os: :ios) {|device| device.split_keyboard_visible?}
74
75
  end
75
76
 
76
77
  # Touches the keyboard action key.
@@ -90,86 +91,29 @@ module Calabash
90
91
  # @todo Refactor uia_route to a public API call
91
92
  # @todo Move this documentation to the public method
92
93
  # @!visibility private
93
- def _tap_keyboard_action_key(action_key)
94
+ define_method(:_tap_keyboard_action_key) do |action_key|
94
95
  unless action_key.nil?
95
96
  raise ArgumentError,
96
97
  "An iOS keyboard does not have multiple action keys"
97
98
  end
98
99
 
99
- char_sequence = ESCAPED_KEYBOARD_CHARACTERS[:action]
100
- Device.default.uia_route("uia.keyboard().typeString('#{char_sequence}')")
100
+ wait_for_keyboard
101
+ Calabash::Internal.with_default_device(required_os: :ios) {|device| device.tap_keyboard_action_key}
101
102
  end
102
103
 
103
104
  # @!visibility private
104
- def _keyboard_visible?
105
+ define_method(:_keyboard_visible?) do
105
106
  docked_keyboard_visible? || undocked_keyboard_visible? || split_keyboard_visible?
106
107
  end
107
108
 
108
109
  # Touches the keyboard delete key.
109
- #
110
- # The 'delete' key difficult to find and touch because its behavior
111
- # changes depending on the iOS version and keyboard type. Consider the
112
- # following:
113
- #
114
- # On iOS 6, the 'delete' char code is _not_ \b.
115
- # On iOS 7: The Delete char code is \b on non-numeric keyboards.
116
- # On numeric keyboards, the delete key is a button on the
117
- # the keyboard.
118
- #
119
- # By default, Calabash uses a raw UIAutomaton JavaScript call to tap the
120
- # element named 'Delete'. This works well in English localizations for
121
- # most keyboards. If you find that it does not work, use the options
122
- # pass either an translation of 'Delete' for your localization or use the
123
- # default the escaped keyboard character.
124
- #
125
110
  # @example
126
- # # Uses UIAutomation to tap the 'Delete' key or button.
127
- # tap_keyboard_delete_key
128
- #
129
- # # Types the \b key.
130
- # tap_keyboard_delete_key({:use_escaped_char => true})
111
+ # cal_ios.tap_keyboard_delete_key
131
112
  #
132
- # # Types the \d key.
133
- # tap_keyboard_delete_key({:use_escaped_char => '\d'})
134
- #
135
- # # Uses UIAutomation to tap the 'Slet' key or button.
136
- # tap_keyboard_delete_key({:delete_key_label => 'Slet'})
137
- #
138
- # # Don't specify both options! If :use_escape_sequence is truthy,
139
- # # Calabash will ignore the :delete_key_label and try to use an
140
- # # escaped character sequence.
141
- # tap_keyboard_delete_key({:use_escaped_char => true,
142
- # :delete_key_label => 'Slet'})
143
- #
144
- # @param [Hash] options Alternative ways to tap the delete key.
145
- # @option options [Boolean, String] :use_escaped_char (false) If true,
146
- # delete by typing the \b character. If this value is truthy, but not
147
- # 'true', they it is expected to be an alternative escaped character.
148
- # @option options [String] :delete_key_label ('Delete') An alternative
149
- # localization of 'Delete'.
150
- # @todo Need translations of 'Delete' key.
151
- def tap_keyboard_delete_key(options = {})
152
- default_options =
153
- {
154
- use_escaped_char: false,
155
- delete_key_label: 'Delete'
156
- }
157
- merged_options = default_options.merge(options)
158
-
159
- use_escape_sequence = merged_options[:use_escaped_char]
160
- if use_escape_sequence
161
- if use_escape_sequence.to_s == 'true'
162
- # Use the default \b
163
- char_sequence = ESCAPED_KEYBOARD_CHARACTERS[:delete]
164
- else
165
- char_sequence = use_escape_sequence
166
- end
167
- return Device.default.uia_route("uia.keyboard().typeString('#{char_sequence}')")
113
+ def tap_keyboard_delete_key
114
+ Calabash::Internal.with_default_device(required_os: :ios) do |device|
115
+ device.tap_keyboard_delete_key
168
116
  end
169
-
170
- delete_key_label = merged_options[:delete_key_label]
171
- uia = "uia.keyboard().elements().firstWithName('#{delete_key_label}').tap()"
172
- Device.default.uia_route(uia)
173
117
  end
174
118
 
175
119
  # Returns the the text in the first responder.
@@ -183,7 +127,9 @@ module Calabash
183
127
  #
184
128
  # @raise [RuntimeError] If there is no visible keyboard.
185
129
  def text_from_keyboard_first_responder
186
- Device.default.text_from_keyboard_first_responder
130
+ Calabash::Internal.with_default_device(required_os: :ios) do |device|
131
+ device.text_from_keyboard_first_responder
132
+ end
187
133
  end
188
134
 
189
135
  private