Home | History | Annotate | Download | only in a11y
      1 # Copyright 2016 The Chromium OS Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 import os
      6 
      7 from autotest_lib.client.bin import test
      8 from autotest_lib.client.bin import utils
      9 from autotest_lib.client.common_lib import error
     10 from autotest_lib.client.cros.input_playback import input_playback
     11 
     12 
     13 class a11y_test_base(test.test):
     14     """Base class for a11y tests."""
     15     version = 1
     16 
     17     # ChromeVox extension id
     18     _CHROMEVOX_ID = 'mndnfokpggljbaajbnioimlmbfngpief'
     19     _CVOX_STATE_TIMEOUT = 40
     20     _CVOX_INDICATOR_TIMEOUT = 40
     21 
     22 
     23     def warmup(self):
     24         """Test setup."""
     25         # Emulate a keyboard for later ChromeVox toggle (if needed).
     26         # See input_playback. The keyboard is used to play back shortcuts.
     27         self._player = input_playback.InputPlayback()
     28         self._player.emulate(input_type='keyboard')
     29         self._player.find_connected_inputs()
     30 
     31 
     32     def _child_test_cleanup(self):
     33         """Can be overwritten by child classes and run duing parent cleanup."""
     34         return
     35 
     36 
     37     def cleanup(self):
     38         self._player.close()
     39         self._child_test_cleanup()
     40 
     41 
     42     def _toggle_chromevox(self):
     43         """Use keyboard shortcut and emulated keyboard to toggle ChromeVox."""
     44         self._player.blocking_playback_of_default_file(
     45                 input_type='keyboard', filename='keyboard_ctrl+alt+z')
     46 
     47     def _chromevox_move(self, direction):
     48         """Use ChromeVox move commands (search + arrow key).
     49 
     50         @param direction:  The direction in which to move, e.g. 'down'.
     51 
     52         """
     53         self._player.blocking_playback_of_default_file(
     54                 input_type='keyboard',
     55                 filename='keyboard_search+%s' % direction)
     56 
     57     def _set_feature(self, feature, value):
     58         """Set given feature to given value using a11y API call.
     59 
     60         Presupposes self._extension (with accessibilityFeatures enabled).
     61 
     62         @param feature: string of accessibility feature to change.
     63         @param value: boolean of expected value.
     64 
     65         @raises: error.TestError if feature cannot be set.
     66 
     67         """
     68         value_str = 'true' if value else 'false'
     69         cmd = ('window.__result = null;\n'
     70                'chrome.accessibilityFeatures.%s.set({value: %s});\n'
     71                'chrome.accessibilityFeatures.%s.get({}, function(d) {'
     72                'window.__result = d[\'value\']; });' % (
     73                        feature, value_str, feature))
     74         self._extension.ExecuteJavaScript(cmd)
     75 
     76         poll_cmd = 'window.__result == %s;' % value_str
     77         utils.poll_for_condition(
     78                 lambda: self._extension.EvaluateJavaScript(poll_cmd),
     79                 exception = error.TestError(
     80                         'Timeout while trying to set %s to %s' %
     81                         (feature, value_str)))
     82 
     83 
     84     def _get_chromevox_state(self):
     85         """Return whether ChromeVox is enabled or not.
     86 
     87         Presupposes self._extension (with management enabled).
     88 
     89         @returns: value of management.get.enabled.
     90 
     91         @raises: error.TestError if state cannot be determined.
     92 
     93         """
     94         cmd = ('window.__enabled = null;\n'
     95                'chrome.management.get(\'%s\', function(r) {'
     96                'if (r) {window.__enabled = r[\'enabled\'];} '
     97                'else {window.__enabled = false;}});' % self._CHROMEVOX_ID)
     98         self._extension.ExecuteJavaScript(cmd)
     99 
    100         poll_cmd = 'window.__enabled != null;'
    101         utils.poll_for_condition(
    102                 lambda: self._extension.EvaluateJavaScript(poll_cmd),
    103                 exception=error.TestError(
    104                         'ChromeVox: management.get.enabled was not set!'))
    105         return self._extension.EvaluateJavaScript('window.__enabled')
    106 
    107 
    108     def _confirm_chromevox_state(self, value):
    109         """Fail test unless ChromeVox state is given value.
    110 
    111         Presupposes self._extension (with management enabled).
    112 
    113         @param value: True or False, whether ChromeVox should be enabled.
    114 
    115         @raises: error.TestFail if actual state doesn't match expected.
    116 
    117         """
    118         utils.poll_for_condition(
    119                 lambda: self._get_chromevox_state() == value,
    120                 exception=error.TestFail('ChromeVox: enabled state '
    121                                          'was not %s.' % value),
    122                 timeout=self._CVOX_STATE_TIMEOUT)
    123 
    124 
    125     def _get_extension_path(self):
    126         """Return the path to the default accessibility extension.
    127 
    128         @returns: string of path to default extension.
    129 
    130         """
    131         this_dir = os.path.dirname(__file__)
    132         return os.path.join(this_dir, 'a11y_ext')
    133