Class: Keyboard

Inherits:
Object show all
Defined in:
lib/keyboard/keyboard.rb

Overview

The Keyboard class defines methods for navigating/typing keys on layouts that are provided by inheriting classes. Keyboard layouts are defined as a matrix of keys. The key types are: special keys - defined as Symbols, i.e. :SHIFT_LOCK, :SHIFT, :BACKSPACE normal keys - defined as Strings, i.e. ‘a’, ‘1’, ‘@’ Splat arrays can be used to simplify rows containing mixed key types. Just don’t make it confusing to read the layout!

Constant Summary collapse

DEBUG =

TODO: Use for debugging only! If pushed to master as false, key navigation will take forever.

false

Instance Method Summary collapse

Constructor Details

#initialize(dut) ⇒ Keyboard



12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/keyboard/keyboard.rb', line 12

def initialize(dut)
  @dut = dut
  @test_case = dut.send(:test_case)
  @layouts = []
  @start_layout_index = 0
  @verify_roi = nil
  @key_delay = 3.sec
  @shifted = false
  @shift_persists = false
  @wrap_rows = false
  @wrap_cols = false
  @deny_traversals = []
  reset
end

Instance Method Details

#displayed?Boolean

Public: Checks if the current keyboard is displayed.

Returns a Boolean true if the



108
109
110
111
112
# File 'lib/keyboard/keyboard.rb', line 108

def displayed?
  return false if displayed_rois.empty?
  displayed_rois.each {|roi| return true if roi.displayed?}
  false
end

#resetObject

Public: Resets all keyboard attributes.

Returns nothing.



117
118
119
120
121
# File 'lib/keyboard/keyboard.rb', line 117

def reset
  @shifted = false
  @cur_coords = nil        # set automatically on first access

  @cur_layout_index = nil  # set automatically on first access

end

#type?(text, args = {}) ⇒ Boolean

Public: This function is used to write the given text on the virtual keyboard.

text - String or Array of String keys to type. start_key - String non-default start key (default: nil). verify_roi - Roi object to verify the typed text (default: nil). delay_between_keys - Delay used between key presses in miliseconds min value of 3000 (default: 3000). nav_only - Boolean whether to navigate without selecting (default: false).

Used to navigate to a single key without selecting it.

Returns Boolean true if successfully able to write the given text. Else, returns false.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/keyboard/keyboard.rb', line 37

def type?(text, args={})
  @key_delay = args[:delay_between_keys].to_i if args[:delay_between_keys].to_i > 3000
  nav_only = args.fetch(:nav_only, false)
  logger.info("#{nav_only ? 'Navigating to' : 'Typing'} #{text.inspect} on the #{cur_layout.name} keyboard.")
  start_key = args[:start_key]
  # only verify if verify==true (from `type_keys?')

  verify_roi = args[:verify] ? args[:verify_roi] || @verify_roi : nil
  unless start_key.nil?
    @cur_coords = get_key_coords(start_key).first
  end
  unless text.is_a?(Array)
    text = [text]
  end
  first_char = true
  text.each do |val|
    if val.is_a?(String) && val.length > 1
      # type the string

      val.split('').each do |key|
        return false unless type?(key, nav_only: nav_only)
      end
    else
      val = :SPACE if val == ' '
      layout_index, shift, key = get_layout_for_key(val)
      # this is a defined key

      if layout_index != cur_layout_index
        # change to the specified layout

        return false unless type_key?(@layouts[layout_index].nav_to_key)
        last_row_count = cur_key_matrix.count
        last_row_width = cur_key_matrix[cur_coords[0]].count
        @cur_layout_index = layout_index
        last_nav_to_key = cur_layout.nav_to_key
        # check if we need to reset the coords due to difference in dimensions between last and new keyboard

        if cur_key_matrix.count != last_row_count || cur_key_matrix[cur_coords[0]].count != last_row_width
          @cur_coords = get_key_coords(last_nav_to_key).first
        end
        # check if we need to downshift to restore the default case of the new layout

        shift ||= (@shift_persists && @shifted)
      end
      # todo: implement shift lock for efficiency

      # if this layout auto-cases, this is the first character, and the key is uppercase, then shift is not req'd

      no_shift_reqd = cur_layout.auto_case && first_char && (key == key.upcase)
      if shift && !no_shift_reqd
        # press the shift key

        return false unless type_key?(cur_layout.shift_key)
      end
      if nav_only
        return false unless nav_to_key?(key)
      else
        return false unless type_key?(key)
      end
      first_char = false if first_char
      first_char = true if cur_layout.auto_case && key == :SPACE
    end
  end
  # all text typed successfully

  if verify_roi.nil?
    true
  else
    typed = verify_roi.retrieve.sub(/_$/, '')
    if typed == text
      true
    else
      logger.info(%Q(Tried to type "#{text}" but typed "#{typed}" instead!))
      false
    end
  end
end