Module: Calabash::Cucumber::KeyboardHelpers
- Includes:
- Logging, TestsHelpers
- Included in:
- Operations
- Defined in:
- lib/calabash-cucumber/keyboard_helpers.rb
Constant Summary collapse
- KEYPLANE_NAMES =
{ :small_letters => 'small-letters', :capital_letters => 'capital-letters', :numbers_and_punctuation => 'numbers-and-punctuation', :first_alternate => 'first-alternate', :numbers_and_punctuation_alternate => 'numbers-and-punctuation-alternate' }
- UIA_SUPPORTED_CHARS =
{ 'Delete' => '\b', 'Return' => '\n' # these are not supported yet and I am pretty sure that they # cannot be touched by passing an escaped character and instead # the must be found using UIAutomation calls. -jmoody #'Dictation' => nil, #'Shift' => nil, #'International' => nil, #'More' => nil, }
Constants included from Logging
Logging::CALABASH_NO_DEPRECATION
Instance Method Summary collapse
-
#_current_keyplane ⇒ Object
returns the current keyplane.
-
#_do_keyplane(kbtree_proc, keyplane_proc) ⇒ Object
process a keyplane.
-
#_ensure_can_enter_text(opts = {}) ⇒ Object
ensures that there is a keyboard to enter text.
-
#_ipad_keyboard_modes ⇒ Object
returns an array of possible ipad keyboard modes.
-
#_point_for_ipad_keyboard_mode_key ⇒ Object
returns the activation point of the iPad keyboard
mode
key. -
#_qstr_for_keyboard ⇒ Object
returns a query string for detecting a keyboard.
-
#_query_for_keyboard_mode_key ⇒ Object
returns a query for touching the iPad keyboard
mode
key. -
#_query_for_touch_for_keyboard_mode_option(top_or_bottom, mode) ⇒ Object
returns a query string for touching one of the options that appears when the iPad
mode
key is touched and held. -
#_query_uia_hide_keyboard_button ⇒ Object
returns a query string for finding the iPad ‘Hide keyboard’ button.
-
#_search_keyplanes_and_enter_char(chr, visited = Set.new) ⇒ Object
searches the available keyplanes for
chr
and if it is found, types it. -
#_touch_bottom_keyboard_mode_row ⇒ Object
touches the bottom option on the popup dialog that is presented when the the iPad keyboard
mode
key is touched and held. -
#_touch_top_keyboard_mode_row ⇒ Object
touches the top option on the popup dialog that is presented when the the iPad keyboard
mode
key is touched and held. - #_wait_for_keyboard_in_mode(mode, opts = {}) ⇒ Object
-
#await_keyboard ⇒ Object
DEPRECATED: Use
wait_for_keyboard
instead. -
#dismiss_ipad_keyboard ⇒ Object
dismisses a iPad keyboard by touching the ‘Hide keyboard’ button and waits for the keyboard to disappear.
-
#docked_keyboard_visible? ⇒ Boolean
returns
true
if adocked
keyboard is visible. -
#done ⇒ Object
touches the keyboard
action
key. -
#ensure_docked_keyboard ⇒ Object
ensures that the iPad keyboard is
docked
. -
#ensure_split_keyboard ⇒ Object
ensures that the iPad keyboard is
split
. -
#ensure_undocked_keyboard ⇒ Object
ensures that the iPad keyboard is
undocked
. -
#ipad_keyboard_mode(opts = {}) ⇒ Object
returns the keyboard
mode
. -
#keyboard_enter_char(chr, opts = {}) ⇒ Object
use keyboard to enter
chr
. -
#keyboard_enter_text(text) ⇒ Object
uses the keyboard to enter
text
. -
#keyboard_visible? ⇒ Boolean
returns true if there is a visible keyboard.
-
#split_keyboard_visible? ⇒ Boolean
returns
true
if asplit
keyboard is visible. -
#tap_keyboard_action_key ⇒ Object
touches the keyboard
action
key. -
#uia_keyboard_visible? ⇒ Boolean
used for detecting keyboards that are not normally visible to calabash e.g.
-
#uia_wait_for_keyboard(opts = {}) ⇒ Object
waits for a keyboard that is not normally visible to calabash e.g.
-
#undocked_keyboard_visible? ⇒ Boolean
returns
true
if anundocked
keyboard is visible. -
#wait_for_keyboard(opts = {}) ⇒ Object
waits for a keyboard to appear and once it does appear waits for 0.3 seconds.
Methods included from Logging
#_deprecated, #calabash_info, #calabash_warn, #debug_logging?, #full_console_logging?, #no_deprecation_warnings?
Methods included from TestsHelpers
#check_element_does_not_exist, #check_element_exists, #check_view_with_mark_exists, #classes, #each_cell, #each_cell_and_back, #element_does_not_exist, #element_exists, #navigation_path, #query_map, #view_with_mark_exists
Methods included from FailureHelpers
#fail, #screenshot, #screenshot_and_raise, #screenshot_embed
Instance Method Details
#_current_keyplane ⇒ Object
returns the current keyplane
334 335 336 337 338 339 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 334 def _current_keyplane kp_arr = _do_keyplane( lambda { query("view:'UIKBKeyplaneView'", 'keyplane', 'componentName') }, lambda { query("view:'UIKBKeyplaneView'", 'keyplane', 'name') }) kp_arr.first.downcase end |
#_do_keyplane(kbtree_proc, keyplane_proc) ⇒ Object
process a keyplane
raises an error if there is not visible keyplane
393 394 395 396 397 398 399 400 401 402 403 404 405 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 393 def _do_keyplane(kbtree_proc, keyplane_proc) desc = query("view:'UIKBKeyplaneView'", 'keyplane') fail('No keyplane (UIKBKeyplaneView keyplane)') if desc.empty? fail('Several keyplanes (UIKBKeyplaneView keyplane)') if desc.count > 1 kp_desc = desc.first if /^<UIKBTree/.match(kp_desc) #ios5+ kbtree_proc.call elsif /^<UIKBKeyplane/.match(kp_desc) #ios4 keyplane_proc.call end end |
#_ensure_can_enter_text(opts = {}) ⇒ Object
ensures that there is a keyboard to enter text
IMPORTANT will always raise an error when the keyboard is split and there is no run_loop
i.e. UIAutomation
is not available
the default options are
:screenshot +true+ raise with a screenshot
:skip +false+ skip any checking (a nop) - used when iterating over
keyplanes for keys
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 168 def _ensure_can_enter_text(opts={}) default_opts = {:screenshot => true, :skip => false} opts = default_opts.merge(opts) return if opts[:skip] screenshot = opts[:screenshot] unless keyboard_visible? msg = 'no visible keyboard' if screenshot screenshot_and_raise msg else raise msg end end if split_keyboard_visible? and uia_not_available? msg = 'cannot type on a split keyboard without launching with Instruments' if screenshot screenshot_and_raise msg else raise msg end end end |
#_ipad_keyboard_modes ⇒ Object
returns an array of possible ipad keyboard modes
123 124 125 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 123 def _ipad_keyboard_modes [:docked, :undocked, :split] end |
#_point_for_ipad_keyboard_mode_key ⇒ Object
returns the activation point of the iPad keyboard mode
key.
the mode
key is also known as the Hide keyboard
key.
raises an error when
-
the device is not an iPad
-
the app was not launched with instruments i.e. there is no
run_loop
439 440 441 442 443 444 445 446 447 448 449 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 439 def _point_for_ipad_keyboard_mode_key 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 => "#{}.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 |
#_qstr_for_keyboard ⇒ Object
returns a query string for detecting a keyboard
37 38 39 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 37 def _qstr_for_keyboard "view:'UIKBKeyplaneView'" end |
#_query_for_keyboard_mode_key ⇒ Object
returns a query for touching the iPad keyboard mode
key.
the mode
key is also know as the Hide keyboard
key.
use _point_for_keyboard_mode_key
if there is a run_loop
available
raises an error when
-
the device is not an iPad
-
the app was launched with Instruments i.e. there is a
run_loop
505 506 507 508 509 510 511 512 513 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 505 def _query_for_keyboard_mode_key raise 'cannot detect keyboard mode key on iphone' if device_family_iphone? if uia_available? raise "UIA is available, use '_point_for_keyboard_mode_key' instead" end qstr = "view:'UIKBKeyView'" idx = query(qstr).count - 1 "#{qstr} index:#{idx}" end |
#_query_for_touch_for_keyboard_mode_option(top_or_bottom, mode) ⇒ Object
returns a query string for touching one of the options that appears when the iPad mode
key is touched and held.
the mode
key is also know as the Hide keyboard
key.
valid arguments are:
top_or_bottom :top | :bottom
mode :docked | :undocked | :skipped
use _point_for_keyboard_mode_key
if there is a run_loop
available
raises an error when
-
the device is not an iPad
-
the app was launched with Instruments i.e. there is a
run_loop
-
it is passed invalid arguments
468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 468 def _query_for_touch_for_keyboard_mode_option(top_or_bottom, mode) raise 'the keyboard mode does not exist on the iphone' if device_family_iphone? if uia_available? raise "UIA is available, use '_point_for_keyboard_mode_key' instead" end valid = [:top, :bottom] unless valid.include? top_or_bottom raise "expected '#{top_or_bottom}' to be one of '#{valid}'" end valid = [:split, :undocked, :docked] unless valid.include? mode raise "expected '#{mode}' to be one of '#{valid}'" end hash = {:split => {:top => 'Merge', :bottom => 'Dock and Merge'}, :undocked => {:top => 'Dock', :bottom => 'Split'}, :docked => {:top => 'Undock', :bottom => 'Split'}} mark = hash[mode][top_or_bottom] "label marked:'#{mark}'" end |
#_query_uia_hide_keyboard_button ⇒ Object
returns a query string for finding the iPad ‘Hide keyboard’ button
408 409 410 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 408 def "uia.keyboard().buttons()['Hide keyboard']" end |
#_search_keyplanes_and_enter_char(chr, visited = Set.new) ⇒ Object
searches the available keyplanes for chr
and if it is found, types it
this is a recursive function
IMPORTANT: use the KEYPLANE_SEARCH_STEP_PAUSE
variable to control how quickly the next keyplane is searched. increase this value if you encounter problems with missed keystrokes.
raises an error if the chr
cannot be found
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 350 def _search_keyplanes_and_enter_char(chr, visited=Set.new) cur_kp = _current_keyplane begin keyboard_enter_char(chr, {:should_screenshot => false}) return true #found rescue pause = (ENV['KEYPLANE_SEARCH_STEP_PAUSE'] || 0.2).to_f sleep (pause) if pause > 0 visited.add(cur_kp) #figure out keyplane alternates props = _do_keyplane( lambda { query("view:'UIKBKeyplaneView'", 'keyplane', 'properties') }, lambda { query("view:'UIKBKeyplaneView'", 'keyplane', 'attributes', 'dict') } ).first known = KEYPLANE_NAMES.values found = false keyplane_selection_keys = ['shift', 'more'] keyplane_selection_keys.each do |key| sleep (pause) if pause > 0 plane = props["#{key}-alternate"] if known.member?(plane) and (not visited.member?(plane)) keyboard_enter_char(key.capitalize, {:should_screenshot => false}) found = _search_keyplanes_and_enter_char(chr, visited) return true if found #not found => try with other keyplane selection key keyplane_selection_keys.delete(key) other_key = keyplane_selection_keys.last keyboard_enter_char(other_key.capitalize, {:should_screenshot => false}) found = _search_keyplanes_and_enter_char(chr, visited) return true if found end end return false end end |
#_touch_bottom_keyboard_mode_row ⇒ Object
touches the bottom option on the popup dialog that is presented when the the iPad keyboard mode
key is touched and held.
the mode
key is also know as the Hide keyboard
key.
the mode
key allows the user to undock, dock, or split the keyboard.
521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 521 def _touch_bottom_keyboard_mode_row mode = ipad_keyboard_mode if uia_available? start_pt = _point_for_ipad_keyboard_mode_key # there are 10 pt btw the key and the popup and the row is 50 pt y_offset = 10 + 25 end_pt = {:x => (start_pt[:x] - 40), :y => (start_pt[:y] - y_offset)} uia_pan_offset(start_pt, end_pt, {}) else pan(_query_for_keyboard_mode_key, nil, {:duration => 1.0}) touch(_query_for_touch_for_keyboard_mode_option(:bottom, mode)) sleep(0.5) end 2.times { sleep(0.5) } end |
#_touch_top_keyboard_mode_row ⇒ Object
touches the top option on the popup dialog that is presented when the the iPad keyboard mode
key is touched and held.
the mode
key is also know as the Hide keyboard
key.
the mode
key allows the user to undock, dock, or split the keyboard.
543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 543 def _touch_top_keyboard_mode_row mode = ipad_keyboard_mode 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 y_offset = 10 + 50 + 25 end_pt = {:x => (start_pt[:x] - 40), :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) end 2.times { sleep(0.5) } end |
#_wait_for_keyboard_in_mode(mode, opts = {}) ⇒ Object
675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 675 def _wait_for_keyboard_in_mode(mode, opts={}) default_opts = {:post_timeout => 1.0} opts = default_opts.merge(opts) begin wait_for(opts) do case mode when :split then split_keyboard_visible? when :undocked undocked_keyboard_visible? when :docked docked_keyboard_visible? else screenshot_and_raise "expected '#{mode}' to be one of #{_ipad_keyboard_modes}" end end rescue actual = ipad_keyboard_mode o = screenshot_and_raise "expected keyboard to be '#{mode}' but found '#{actual}' in orientation '#{o}'" end end |
#await_keyboard ⇒ Object
DEPRECATED: Use wait_for_keyboard
instead.
117 118 119 120 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 117 def await_keyboard _deprecated('0.9.163', "use 'wait_for_keyboard' instead", :warn) wait_for_keyboard end |
#dismiss_ipad_keyboard ⇒ Object
dismisses a iPad keyboard by touching the ‘Hide keyboard’ button and waits for the keyboard to disappear
raises an error if the device is not an iPad. the dismiss keyboard key does not exist on the iPhone or iPod
417 418 419 420 421 422 423 424 425 426 427 428 429 430 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 417 def dismiss_ipad_keyboard screenshot_and_raise 'cannot dismiss keyboard on iphone' if device_family_iphone? if uia_available? send_uia_command({:command => "#{}.tap()"}) else touch(_query_for_keyboard_mode_key) end opts = {:timeout_message => 'keyboard did not disappear'} wait_for(opts) do not keyboard_visible? end end |
#docked_keyboard_visible? ⇒ Boolean
returns true
if a docked
keyboard is visible.
a docked
keyboard is pinned to the bottom of the view.
keyboards on the iPhone and iPod are docked
.
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 46 def docked_keyboard_visible? res = query(_qstr_for_keyboard).first return false if res.nil? return true if device_family_iphone? # ipad rect = res['rect'] o = .to_sym case o when :left then rect['center_x'] == 592 and rect['center_y'] == 512 when :right then rect['center_x'] == 176 and rect['center_y'] == 512 when :up then rect['center_x'] == 384 and rect['center_y'] == 132 when :down then rect['center_x'] == 384 and rect['center_y'] == 892 else false end end |
#done ⇒ Object
touches the keyboard action
key
the action
key depends on the keyboard.
some examples include:
-
Return
-
Next
-
Go
-
Join
-
Search
not all keyboards have an action
key raises an error if the key cannot be entered
329 330 331 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 329 def done tap_keyboard_action_key end |
#ensure_docked_keyboard ⇒ Object
ensures that the iPad keyboard is docked
docked
means the keyboard is pinned to bottom of the view
if the device is not an iPad, this is behaves like a call to wait_for_keyboard
raises an error when
-
there is no visible keyboard or
-
the
docked
keyboard cannot be achieved
571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 571 def ensure_docked_keyboard 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}" end begin wait_for({:post_timeout => 1.0}) do docked_keyboard_visible? end rescue mode = ipad_keyboard_mode o = screenshot_and_raise "expected keyboard to be ':docked' but found '#{mode}' in orientation '#{o}'" end end |
#ensure_split_keyboard ⇒ Object
ensures that the iPad keyboard is split
split
means the keyboard is floating in the middle of the view and is split into two sections to enable faster thumb typing.
if the device is not an iPad, this is behaves like a call to wait_for_keyboard
raises an error when
-
there is no visible keyboard or
-
the an
undocked
keyboard cannot be achieved
655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 655 def ensure_split_keyboard 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 _wait_for_keyboard_in_mode(:split) end |
#ensure_undocked_keyboard ⇒ Object
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 wait_for_keyboard
raises an error when
-
there is no visible keyboard or
-
the an
undocked
keyboard cannot be achieved
610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 610 def ensure_undocked_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) 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}" end _wait_for_keyboard_in_mode(:undocked) end |
#ipad_keyboard_mode(opts = {}) ⇒ Object
returns the keyboard mode
keyboard is pinned to bottom of the view #=> :docked
keyboard is floating in the middle of the view #=> :undocked
keyboard is floating and split #=> :split
no keyboard and :raise_on_no_visible_keyboard == +false+ #=> :unknown
raises an error if the device is not an iPad
raises an error if the :raise_on_no_visible_keyboard
is true
(default) and no keyboard is visible
set :raise_on_no_visible_keyboard
to false
to use in wait
functions
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 141 def ipad_keyboard_mode(opts = {}) raise 'the keyboard mode does not exist on the iphone or ipod' if device_family_iphone? default_opts = {:raise_on_no_visible_keyboard => true} opts = default_opts.merge(opts) if opts[:raise_on_no_visible_keyboard] screenshot_and_raise 'there is no visible keyboard' unless keyboard_visible? return :docked if docked_keyboard_visible? return :undocked if undocked_keyboard_visible? :split else return :docked if docked_keyboard_visible? return :undocked if undocked_keyboard_visible? return :split if split_keyboard_visible? :unknown end end |
#keyboard_enter_char(chr, opts = {}) ⇒ Object
use keyboard to enter chr
IMPORTANT: use the POST_ENTER_KEYBOARD
environmental variable to slow down the typing; adds a wait after each character is touched. this can fix problems where the typing is too fast and characters are skipped.
there are several special ‘characters’, some of which do not appear on all keyboards:
-
‘Delete’
-
‘Return’
raises error if there is no visible keyboard or the keyboard is not supported
use the should_screenshot
to control whether or not to raise an error if chr
is not found
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 211 def keyboard_enter_char(chr, opts={}) unless opts.is_a?(Hash) msg = "you should no longer pass a boolean as the second arg; pass {:should_screenshot => '#{opts}'} hash instead" _deprecated('0.9.163', msg, :warn) opts = {:should_screenshot => opts} end default_opts = {:should_screenshot => true, # introduce a small wait to avoid skipping characters # keep this as short as possible :wait_after_char => (ENV['POST_ENTER_KEYBOARD'] || 0.05).to_f} opts = default_opts.merge(opts) should_screenshot = opts[:should_screenshot] _ensure_can_enter_text({:screenshot => should_screenshot, :skip => (not should_screenshot)}) if uia_available? if chr.length == 1 uia_type_string chr else code = UIA_SUPPORTED_CHARS[chr] unless code raise "typing character '#{chr}' is not yet supported when running with Instruments" end # on iOS 6, the Delete char code is _not_ \b # on iOS 7, the Delete char code is \b on non-numeric keyboards # on numeric keyboards, it is actually a button on the # keyboard and not a key if code.eql?(UIA_SUPPORTED_CHARS['Delete']) uia("uia.keyboard().elements().firstWithName('Delete').tap()") elsif code.eql?(UIA_SUPPORTED_CHARS['Return']) tap_keyboard_action_key else uia_type_string(code, '') end end res = {'results' => []} else res = http({:method => :post, :path => 'keyboard'}, {:key => chr, :events => load_playback_data('touch_done')}) res = JSON.parse(res) if res['outcome'] != 'SUCCESS' msg = "Keyboard enter failed failed because: #{res['reason']}\n#{res['details']}" if should_screenshot screenshot_and_raise msg else raise msg end end end if ENV['POST_ENTER_KEYBOARD'] w = ENV['POST_ENTER_KEYBOARD'].to_f if w > 0 sleep(w) end end pause = opts[:wait_after_char] sleep(pause) if pause > 0 res['results'] end |
#keyboard_enter_text(text) ⇒ Object
uses the keyboard to enter text
raises an error if the text cannot be entered
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 280 def keyboard_enter_text(text) _ensure_can_enter_text if uia_available? text_before = _text_from_first_responder() text_before = text_before.gsub("\n","\\n") if text_before uia_type_string(text, text_before) else text.each_char do |ch| begin keyboard_enter_char(ch, {:should_screenshot => false}) rescue _search_keyplanes_and_enter_char(ch) end end end end |
#keyboard_visible? ⇒ Boolean
returns true if there is a visible keyboard
99 100 101 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 99 def keyboard_visible? docked_keyboard_visible? or undocked_keyboard_visible? or split_keyboard_visible? end |
#split_keyboard_visible? ⇒ Boolean
returns true
if a split
keyboard is visible.
a split
keyboard is floats in the middle of the view and is split to allow faster thumb typing
returns false
if the device is not an iPad; all keyboards on the iPhone and iPod are docked
92 93 94 95 96 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 92 def split_keyboard_visible? return false if device_family_iphone? query("view:'UIKBKeyView'").count > 0 and element_does_not_exist(_qstr_for_keyboard) end |
#tap_keyboard_action_key ⇒ Object
touches the keyboard action
key
the action
key depends on the keyboard. some examples include:
-
Return
-
Next
-
Go
-
Join
-
Search
not all keyboards have an action
key raises an error if the key cannot be entered
308 309 310 311 312 313 314 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 308 def tap_keyboard_action_key if uia_available? uia_type_string '\n', '', false else keyboard_enter_char 'Return' end end |
#uia_keyboard_visible? ⇒ Boolean
used for detecting keyboards that are not normally visible to calabash e.g. the keyboard on ‘z’
IMPORTANT this should only be used when the app does not respond to keyboard_visible?
raises an error if the there is no run_loop
705 706 707 708 709 710 711 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 705 def uia_keyboard_visible? unless uia_available? screenshot_and_raise 'only available if there is a run_loop i.e. the app was launched with Instruments' end res = uia_query_windows(:keyboard) not res.eql?(':nil') end |
#uia_wait_for_keyboard(opts = {}) ⇒ Object
waits for a keyboard that is not normally visible to calabash e.g. the keyboard on MFMailComposeViewController
IMPORTANT this should only be used when the app does not respond to keyboard_visible?
raises an error if the there is no run_loop
720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 720 def uia_wait_for_keyboard(opts={}) unless uia_available? screenshot_and_raise 'only available if there is a run_loop i.e. the app was launched with Instruments' end default_opts = {:timeout => 10, :retry_frequency => 0.1, :post_timeout => 0.5} opts = default_opts.merge(opts) unless opts[:timeout_message] msg = "waited for '#{opts[:timeout]}' for keyboard" opts[:timeout_message] = msg end wait_for(opts) do uia_keyboard_visible? end end |
#undocked_keyboard_visible? ⇒ Boolean
returns true
if an undocked
keyboard is visible.
a undocked
keyboard is floats in the middle of the view
returns false
if the device is not an iPad; all keyboards on the iPhone and iPod are docked
76 77 78 79 80 81 82 83 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 76 def undocked_keyboard_visible? return false if device_family_iphone? res = query(_qstr_for_keyboard).first return false if res.nil? not docked_keyboard_visible? end |
#wait_for_keyboard(opts = {}) ⇒ Object
waits for a keyboard to appear and once it does appear waits for 0.3 seconds
raises an error if no keyboard appears
107 108 109 110 111 112 113 114 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 107 def wait_for_keyboard(opts={}) default_opts = {:timeout_message => 'keyboard did not appear', :post_timeout => 0.3} opts = default_opts.merge(opts) wait_for(opts) do keyboard_visible? end end |