Module: Calabash::Cucumber::KeyboardHelpers
- Includes:
- 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, }
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 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
327 328 329 330 331 332 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 327 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
386 387 388 389 390 391 392 393 394 395 396 397 398 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 386 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
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 165 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
120 121 122 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 120 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
432 433 434 435 436 437 438 439 440 441 442 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 432 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
34 35 36 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 34 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
498 499 500 501 502 503 504 505 506 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 498 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
461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 461 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
401 402 403 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 401 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
343 344 345 346 347 348 349 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 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 343 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.
514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 514 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.
536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 536 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
668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 668 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.
114 115 116 117 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 114 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
410 411 412 413 414 415 416 417 418 419 420 421 422 423 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 410 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
.
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 43 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
322 323 324 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 322 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
564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 564 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
648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 648 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
603 604 605 606 607 608 609 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 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 603 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
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 138 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
208 209 210 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 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 208 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 "Char #{chr} is not yet supported in when typing with Instruments" end # on iOS 6, the char code is _not_ \b # # as an aside, on iOS 7, the same approach (tap the 'Delete' key) also works if ios6? and code.eql?(UIA_SUPPORTED_CHARS['Delete']) uia("uia.keyboard().keys().firstWithName('Delete').tap()") 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
274 275 276 277 278 279 280 281 282 283 284 285 286 287 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 274 def keyboard_enter_text(text) _ensure_can_enter_text if uia_available? uia_type_string(text) 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
96 97 98 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 96 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
89 90 91 92 93 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 89 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
301 302 303 304 305 306 307 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 301 def tap_keyboard_action_key if uia_available? uia_type_string '\n' 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
698 699 700 701 702 703 704 705 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 698 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 # TODO refactor keyboard detection to use uia() function conventions (instead of UIATarget...) res = uia('UIATarget.localTarget().frontMostApp().keyboard()')['value'] 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
714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 714 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
73 74 75 76 77 78 79 80 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 73 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
104 105 106 107 108 109 110 111 |
# File 'lib/calabash-cucumber/keyboard_helpers.rb', line 104 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 |