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
5import logging
6import time
7
8from autotest_lib.client.bin import test
9from autotest_lib.client.bin import utils
10from autotest_lib.client.common_lib import error
11from autotest_lib.client.common_lib.cros import chrome
12from autotest_lib.client.cros.input_playback import input_playback
13
14
15class logging_FeedbackReport(test.test):
16    """Tests if feedback report can be opened with no crashes in browser."""
17    version = 1
18    _FEEDBACK_ID = 'gfdkimpbcpahaombhbimeihdjnejgicl'
19    _FEEDBACK_STATE_TIMEOUT = 40
20    _WAIT = 2
21    _FEEDBACK_SENT_URL = 'support.google.com/chromebook/answer/3142217'
22
23    def warmup(self):
24        """Test setup."""
25        # Emulate keyboard to open feedback app.
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    def _open_feedback(self):
32        """Use keyboard shortcut to emulate input to open feedback app."""
33        self._player.blocking_playback_of_default_file(
34            input_type='keyboard', filename='keyboard_alt+shift+i')
35
36    def _check_feedback_elements(self):
37        """
38        Return whether feedback app is open or not.
39
40        @returns: True if all elements are present, else False.
41
42        """
43        # Verifying feedback app window is open.
44        if not self.feedback_app.EvaluateJavaScript('document.body != null'):
45            logging.info('Window not enabled.')
46            return False
47
48        # Verifying UI elements in window are enabled.
49        elements = ['cancel-button', 'send-report-button',
50                    'description-text']
51        for element in elements:
52            js = "document.getElementById('%s') != null" % element
53            if not self.feedback_app.EvaluateJavaScript(js):
54                logging.info("%s not enabled.", element)
55                return False
56
57        return True
58
59    def _check_feedback_extension_loaded(self):
60        """
61        Return whether feedback extension has loaded.
62
63        @returns: True if extension loaded, else False.
64
65        """
66
67        for extension in self.cr_exts.GetByExtensionId(self._FEEDBACK_ID):
68            url = extension.EvaluateJavaScript('location.href;')
69            if url.endswith('default.html'):
70                self.feedback_app = extension
71                return True
72        return False
73
74    def _confirm_feedback_state(self):
75        """
76        Fail test if feedback elements have not been found.
77
78        @raises: error.TestFail if feedback app not found.
79
80        """
81        utils.poll_for_condition(
82                lambda: self._check_feedback_extension_loaded(),
83                exception=error.TestError("Incorrect feedback id list."),
84                timeout=self._FEEDBACK_STATE_TIMEOUT)
85
86        utils.poll_for_condition(
87                lambda: self._check_feedback_elements(),
88                exception=error.TestFail('Feedback elements not enabled.'),
89                timeout=self._FEEDBACK_STATE_TIMEOUT)
90
91    def _enter_feedback_text(self):
92        """Enter Feedback message in the Text field"""
93        time.sleep(self._WAIT)
94        self._player.blocking_playback_of_default_file(
95               input_type='keyboard', filename='keyboard_T+e+s+t')
96
97    def _press_enter(self):
98        """Use keyboard shortcut to press Enter."""
99        self._player.blocking_playback_of_default_file(
100            input_type='keyboard', filename='keyboard_enter')
101
102    def _press_shift_tab(self):
103        """Use keyboard shortcut to press Shift-Tab."""
104        self._player.blocking_playback_of_default_file(
105            input_type='keyboard', filename='keyboard_shift+tab')
106
107    def _submit_feedback(self):
108        """Click on Send button to submit Feedback Report using keyboard input"""
109        self._enter_feedback_text()
110        self._press_shift_tab()
111        self._press_enter()
112
113    def _is_feedback_sent(self, start_time, timeout):
114        """Checks feedback is sent within timeout
115
116        @param start_time: beginning timestamp
117        @param timeout: duration of URL checks
118
119        @returns: True if feedback sent page is present
120        """
121        while True:
122            time.sleep(self._WAIT)
123            for tab in self.cr.browser.tabs:
124                if self._FEEDBACK_SENT_URL in tab.url:
125                    return True
126            if time.time() - start_time >= timeout:
127                break;
128        return False
129
130    def run_once(self):
131        """Run the test."""
132        with chrome.Chrome(disable_default_apps=False) as self.cr:
133            # Open and confirm feedback app is working.
134            time.sleep(self._WAIT)
135            self._open_feedback()
136            self.cr_exts = self.cr.browser.extensions
137            self.feedback_app = None
138            self._confirm_feedback_state()
139            self._submit_feedback()
140
141            start_time = time.time()
142            if not self._is_feedback_sent(start_time, self._WAIT * 30):
143                raise error.TestFail("Feedback NOT sent!")
144
145    def cleanup(self):
146        """Test cleanup."""
147