lib/calabash-cucumber/keyboard_helpers.rb in calabash-cucumber-0.16.2 vs lib/calabash-cucumber/keyboard_helpers.rb in calabash-cucumber-0.16.3
- old
+ new
@@ -4,10 +4,22 @@
require 'calabash-cucumber/environment_helpers'
require 'calabash-cucumber/utils/logging'
module Calabash
module Cucumber
+
+
+ # Raised when there is a problem involving a keyboard mode. There are
+ # three keyboard modes: docked, split, and undocked.
+ #
+ # All iPads support these keyboard modes, but the user can disable them
+ # in Settings.app.
+ #
+ # The iPhone 6+ family also supports keyboard modes, but Calabash does
+ # support keyboard modes on these devices.
+ class KeyboardModeError < StandardError; ; end
+
# Collection of methods for interacting with the keyboard.
#
# We've gone to great lengths to provide the fastest keyboard entry possible.
#
# If you are having trouble with skipped or are receiving JSON octet
@@ -78,40 +90,27 @@
# Keyboards on the iPhone and iPod are docked.
#
# @return [Boolean] if a keyboard is visible and docked.
def docked_keyboard_visible?
res = query(_qstr_for_keyboard).first
+
return false if res.nil?
return true if device_family_iphone?
- rect = res['rect']
- o = status_bar_orientation.to_sym
- case o
- when :left
- if ios8?
- rect['center_x'] == 512 and rect['center_y'] == 592
- else
- rect['center_x'] == 592 and rect['center_y'] == 512
- end
- when :right
- if ios8?
- rect['center_x'] == 512 and rect['center_y'] == 592
- else
- rect['center_x'] == 176 and rect['center_y'] == 512
- end
- when :up
- if ios8?
- rect['center_x'] == 384 and rect['center_y'] == 892
- else
- rect['center_x'] == 384 and rect['center_y'] == 132
- end
- when :down
- rect['center_x'] == 384 and rect['center_y'] == 892
- else
- false
+ orientation = status_bar_orientation.to_sym
+ keyboard_height = res['rect']['height']
+ keyboard_y = res['rect']['y']
+ scale = screen_dimensions[:scale]
+
+ if orientation == :left || orientation == :right
+ screen_height = screen_dimensions[:width]/scale
+ else
+ screen_height = screen_dimensions[:height]/scale
end
+
+ screen_height - keyboard_height == keyboard_y
end
# Returns true if an undocked keyboard is visible.
#
# A undocked keyboard is floats in the middle of the view.
@@ -591,14 +590,10 @@
raise 'the keyboard mode does not exist on the on the iphone' if device_family_iphone?
raise 'cannot detect keyboard mode key without launching with instruments' unless uia_available?
res = send_uia_command({:command => "#{_query_uia_hide_keyboard_button}.rect()"})
origin = res['value']['origin']
{:x => origin['x'], :y => origin['y']}
-
- # this did not work.
- #size = res['value']['size']
- #{:x => (origin['x'] (size['width']/2)), :y => (origin['y'] (size['height']/2))}
end
# @!visibility private
# Returns a query string for touching one of the options that appears when
# the iPad mode key is touched and held.
@@ -698,12 +693,14 @@
if uia_available?
start_pt = _point_for_ipad_keyboard_mode_key
# there are 10 pt btw the key and the popup and each row is 50 pt
# NB: no amount of offsetting seems to allow touching the top row
# when the keyboard is split
+
+ x_offset = 40
y_offset = 10 + 50 + 25
- end_pt = {:x => (start_pt[:x] - 40), :y => (start_pt[:y] - y_offset)}
+ end_pt = {:x => (start_pt[:x] - x_offset), :y => (start_pt[:y] - y_offset)}
uia_pan_offset(start_pt, end_pt, {:duration => 1.0})
else
pan(_query_for_keyboard_mode_key, nil, {})
touch(_query_for_touch_for_keyboard_mode_option(:top, mode))
sleep(0.5)
@@ -724,19 +721,27 @@
wait_for_keyboard
return if device_family_iphone?
mode = ipad_keyboard_mode
- case mode
- when :split then
- _touch_bottom_keyboard_mode_row
- when :undocked then
- _touch_top_keyboard_mode_row
- when :docked then
- # already docked
- else
- screenshot_and_raise "expected '#{mode}' to be one of #{_ipad_keyboard_modes}"
+
+ return if mode == :docked
+
+ if ios9?
+ raise KeyboardModeError,
+ 'Changing keyboard modes is not supported on iOS 9'
+ else
+ case mode
+ when :split then
+ _touch_bottom_keyboard_mode_row
+ when :undocked then
+ _touch_top_keyboard_mode_row
+ when :docked then
+ # already docked
+ else
+ screenshot_and_raise "expected '#{mode}' to be one of #{_ipad_keyboard_modes}"
+ end
end
begin
wait_for({:post_timeout => 1.0}) do
docked_keyboard_visible?
@@ -746,11 +751,10 @@
o = status_bar_orientation
screenshot_and_raise "expected keyboard to be ':docked' but found '#{mode}' in orientation '#{o}'"
end
end
-
# Ensures that the iPad keyboard is undocked.
#
# Undocked means the keyboard is floating in the middle of the view.
#
# If the device is not an iPad, this is behaves like a call to
@@ -760,39 +764,46 @@
# `wait_for_keyboard`.
#
# @raise [RuntimeError] if there is no visible keyboard
# @raise [RuntimeError] an undocked keyboard was not achieved
def ensure_undocked_keyboard
- wait_for_keyboard()
+ wait_for_keyboard
return if device_family_iphone?
mode = ipad_keyboard_mode
- case mode
- when :split then
- # keep these condition separate because even though they do the same
- # thing, the else condition is a hack
- if ios5?
- # iOS 5 has no 'Merge' feature in split keyboard, so dock first then
- # undock from docked mode
- _touch_bottom_keyboard_mode_row
- _wait_for_keyboard_in_mode(:docked)
+
+ return if mode == :undocked
+
+ if ios9?
+ raise KeyboardModeError,
+ 'Changing keyboard modes is not supported on iOS 9'
+ else
+ case mode
+ when :split then
+ # keep these condition separate because even though they do the same
+ # thing, the else condition is a hack
+ if ios5?
+ # iOS 5 has no 'Merge' feature in split keyboard, so dock first then
+ # undock from docked mode
+ _touch_bottom_keyboard_mode_row
+ _wait_for_keyboard_in_mode(:docked)
+ else
+ # in iOS > 5, it seems to be impossible consistently touch the
+ # the top keyboard mode popup button, so we punt
+ _touch_bottom_keyboard_mode_row
+ _wait_for_keyboard_in_mode(:docked)
+ end
+ _touch_top_keyboard_mode_row
+ when :undocked then
+ # already undocked
+ when :docked then
+ _touch_top_keyboard_mode_row
else
- # in iOS > 5, it seems to be impossible consistently touch the
- # the top keyboard mode popup button, so we punt
- _touch_bottom_keyboard_mode_row
- _wait_for_keyboard_in_mode(:docked)
- end
- _touch_top_keyboard_mode_row
- when :undocked then
- # already undocked
- when :docked then
- _touch_top_keyboard_mode_row
- else
- screenshot_and_raise "expected '#{mode}' to be one of #{_ipad_keyboard_modes}"
+ screenshot_and_raise "expected '#{mode}' to be one of #{_ipad_keyboard_modes}"
+ end
end
-
_wait_for_keyboard_in_mode(:undocked)
end
# Ensures that the iPad keyboard is split.
@@ -812,20 +823,27 @@
wait_for_keyboard
return if device_family_iphone?
mode = ipad_keyboard_mode
- case mode
- when :split then
- # already split
- when :undocked then
- _touch_bottom_keyboard_mode_row
- when :docked then
- _touch_bottom_keyboard_mode_row
- else
- screenshot_and_raise "expected '#{mode}' to be one of #{_ipad_keyboard_modes}"
- end
+ return if mode == :split
+
+ if ios9?
+ raise KeyboardModeError,
+ 'Changing keyboard modes is not supported on iOS 9'
+ else
+ case mode
+ when :split then
+ # already split
+ when :undocked then
+ _touch_bottom_keyboard_mode_row
+ when :docked then
+ _touch_bottom_keyboard_mode_row
+ else
+ screenshot_and_raise "expected '#{mode}' to be one of #{_ipad_keyboard_modes}"
+ end
+ end
_wait_for_keyboard_in_mode(:split)
end
# @!visibility private
def _wait_for_keyboard_in_mode(mode, opts={})