1# Copyright (c) 2013 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 cgi, os
6
7from autotest_lib.client.bin import test
8from autotest_lib.client.bin import utils
9from autotest_lib.client.common_lib.cros import chrome
10
11_DEFAULT_TIMEOUT = 60  # Seconds a tester has to respond to prompts
12
13
14class semiauto_test(test.test):
15    """Base class for semiauto tests in ChromeOS.
16
17    All these tests use telemetry and a simple interative webpage that
18    navigates the user through the test.
19    """
20    version = 1
21
22    def login_and_open_interactive_tab(self):
23        """Log in to machine, open browser, and navigate to dialog template.
24
25        Dialog template is on first tab.  Any other needed tabs can be opened
26        using the self._browser object.
27        """
28        self._browser = chrome.Chrome(init_network_controller=True).browser
29        self._tab = self._browser.tabs[0]
30        self._browser.platform.SetHTTPServerDirectories(
31                os.path.join(self.bindir, '..', '..', 'cros'))
32        self._tab.Navigate(self._browser.platform.http_server.UrlOf(
33                '/semiauto_shell.html'))
34
35    def close_browser(self):
36        """Close browser if open."""
37        if self._browser:
38            self._browser.Close()
39
40    def set_tab(self, html):
41        """Replace the body of self._tab with provided html.
42
43        @param html: the HTML that will replace the body of the dialog tab.
44        """
45        html_esc = html.replace('"', '\\"')
46
47        # Use JavaScript to set the output.
48        self._tab.ExecuteJavaScript('window.__ready = 0; '
49                                    'document.body.innerHTML="%s";' % html_esc)
50        self._tab.Activate()
51        self._tab.WaitForDocumentReadyStateToBeInteractiveOrBetter()
52
53    def clear_output(self):
54        """Replace the body of self._tab with a blank screen.
55        """
56        self.set_tab('')
57
58    def set_tab_with_buttons(self, html, buttons=['OK']):
59        """Replace the body of self._tab with provided html and buttons.
60
61        @param html: the HTML that will replace the body of the dialog tab.
62        @param buttons: the titles of some number of buttons to add to the
63                        page. Each button has an integer value, starting from
64                        0 for the first. Defaults to an 'OK' button.
65        """
66        html_total = html+'<br>'
67        index = 0
68        for title in buttons:
69            onclick = 'submit_button(%d)' % index
70            html_total += ('<input type="button" value="%s" onclick="%s">' % (
71                           cgi.escape(title), onclick))
72            index += 1
73        self.set_tab(html_total)
74
75    def set_tab_with_textbox(self, html, title=''):
76        """Replace the body of self._tab with provided html and a textbox.
77
78        Adds a textbox and Submit button to the page.  The value returned after
79        clicking the button is the text that was entered in the textbox.
80
81        @param html: the HTML that will replace the body of the dialog tab.
82        @param title: the title put next to the textbox.
83        """
84        textbox = '%s<input type="text" id="textinput"/>' % title
85        button = '<input type="button" value="SUBMIT" onclick="get_text()"/>'
86        html_total = '%s<br>%s<br>%s' % (html, textbox, button)
87        self.set_tab(html_total)
88
89    def wait_for_tab_result(self, timeout=_DEFAULT_TIMEOUT):
90        """Wait for interactive tab to be ready and get return value.
91
92        @param timeout: Maximum number of seconds to wait for result.
93
94        @return: value of window.__result.
95        """
96        complete = lambda: self._tab.EvaluateJavaScript('window.__ready') == 1
97        utils.poll_for_condition(condition=complete, timeout=timeout,
98                                 desc='User response')
99
100        result = self._tab.EvaluateJavaScript('window.__result')
101        self._tab.ExecuteJavaScript('window.__ready = 0; '
102                                    'window.__result = null;')
103        return result
104