1# Copyright 2015 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
5import logging
6
7from autotest_lib.client.common_lib import error
8from autotest_lib.client.common_lib.cros import chrome
9from autotest_lib.client.cros import touch_playback_test_base
10
11
12class touch_TabSwitch(touch_playback_test_base.touch_playback_test_base):
13    """Test to verify the three finger tab switching touchpad gesture."""
14    version = 1
15
16    # Devices with older touchpads that do not recognize 3+ fingers.
17    _INVALID_BOARDS = ['x86-alex', 'x86-alex_he', 'x86-zgb', 'x86-zgb_he',
18                       'x86-mario', 'stout']
19
20    _DIRECTIONS = ['left', 'right']
21
22    def _is_testable(self):
23        """Returns True if the test can run on this device, else False."""
24        if not self._has_touchpad:
25            raise error.TestError('No touchpad found on this device!')
26
27        if self._platform in self._INVALID_BOARDS:
28            logging.info('Device does not support this gesture; aborting.')
29            return False
30
31        # Check if playback files are available on DUT to run test.
32        self._filepaths = self._find_test_files_from_directions(
33                'touchpad', 'three-finger-swipe-%s', self._DIRECTIONS)
34        if not self._filepaths:
35            logging.info('Missing gesture files, Aborting test.')
36            return False
37
38        return True
39
40    def _set_up_tabs(self, cr):
41        """Open two additional tabs for this test (total of three).
42
43        @raises TestError if browser doesn't end up with correct tab count.
44
45        """
46        self._tabs = cr.browser.tabs
47        tab_count = 3
48        for i in xrange(1, tab_count):
49            tab = cr.browser.tabs.New()
50
51        if len(self._tabs) != tab_count:
52            raise error.TestError('Expected %s tabs but found %s!' % (
53                    tab_count, len(self._tabs)))
54
55    def _require_active(self, index):
56        """Fail the test if the index-th tab is not active.
57
58        @param index: integer representing the position of our tab.
59
60        @raises: TestFail if the tab is not active as expected.
61
62        """
63        tab = self._tabs[index]
64        if tab.EvaluateJavaScript('document.hidden') == 'False':
65            raise error.TestFail('Expected page %s to be active!' % index)
66
67    def _check_tab_switch(self):
68        """ Verify correct tab switching behavior.
69
70        Regardless of australian scrolling setting, moving three fingers to
71        the left will set the tab to the left as the active tab.
72        Attempting to move past the last tab on either end will not wrap.
73
74        Expects the third (and last) tab to be active.
75
76        """
77        for tab_index in [1, 0, 0]:
78            self._blocking_playback(touch_type='touchpad',
79                                    filepath=self._filepaths['left'])
80            self._require_active(tab_index)
81
82        for tab_index in [1, 2, 2]:
83            self._blocking_playback(touch_type='touchpad',
84                                    filepath=self._filepaths['right'])
85            self._require_active(tab_index)
86
87    def run_once(self):
88        """Entry point of this test."""
89        if not self._is_testable():
90            return
91
92        # Log in and start test.
93        with chrome.Chrome(autotest_ext=True) as cr:
94            self._set_autotest_ext(cr.autotest_ext)
95            self._set_up_tabs(cr)
96
97            self._check_tab_switch()
98
99            # Toggle Australian scrolling and test again.
100            new_australian_state = not self._has_touchscreen
101            self._set_australian_scrolling(value=new_australian_state)
102            self._check_tab_switch()
103