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
5from autotest_lib.client.cros import constants
6from autotest_lib.server import autotest
7
8
9class InteractiveClient(object):
10    """InteractiveClient represents a remote host for interactive tests.
11
12    An XML-RPC server is deployed to the remote host and a set of methods
13    exposed that allow you to open a browser window on that device, write
14    output and receive button clicks in order to develop interactive tests.
15    """
16
17    XMLRPC_BRINGUP_TIMEOUT_SECONDS = 60
18
19    def __init__(self, client_host):
20        """Construct a InteractiveClient.
21
22        @param client_host: host object representing a remote host.
23
24        """
25        self._host = client_host
26        # Make sure the client library is on the device so that the proxy code
27        # is there when we try to call it.
28        client_at = autotest.Autotest(self._host)
29        client_at.install()
30        # Start up the XML-RPC proxy on the client.
31        self._proxy = self._host.rpc_server_tracker.xmlrpc_connect(
32                constants.INTERACTIVE_XMLRPC_SERVER_COMMAND,
33                constants.INTERACTIVE_XMLRPC_SERVER_PORT,
34                command_name=
35                  constants.INTERACTIVE_XMLRPC_SERVER_CLEANUP_PATTERN,
36                ready_test_name=
37                  constants.INTERACTIVE_XMLRPC_SERVER_READY_METHOD,
38                timeout_seconds=self.XMLRPC_BRINGUP_TIMEOUT_SECONDS)
39
40
41    def login(self):
42        """Login to the system and open a tab.
43
44        The tab opened is used by other methods on this server to interact
45        with the user.
46
47        @return True on success, False otherwise.
48
49        """
50        return self._proxy.login()
51
52
53    def set_output(self, html):
54        """Replace the contents of the tab.
55
56        @param html: HTML document to replace tab contents with.
57
58        @return True on success, False otherwise.
59
60        """
61        return self._proxy.set_output(html)
62
63
64    def append_output(self, html):
65        """Append HTML to the contents of the tab.
66
67        @param html: HTML to append to the existing tab contents.
68
69        @return True on success, False otherwise.
70
71        """
72        return self._proxy.append_output(html)
73
74
75    def append_buttons(self, *args):
76        """Append confirmation buttons to the tab.
77
78        Each button is given an index, 0 for the first button, 1 for the second,
79        and so on.
80
81        @param title...: Title of button to append.
82
83        @return True on success, False otherwise.
84
85        """
86        return self._proxy.append_buttons(*args)
87
88
89    def wait_for_button(self, timeout):
90        """Wait for a button to be clicked.
91
92        Call append_buttons() before this to add buttons to the document.
93
94        @param timeout: Maximum time, in seconds, to wait for a click.
95
96        @return index of button that was clicked, or -1 on timeout.
97
98        """
99        return self._proxy.wait_for_button(timeout)
100
101
102    def check_for_button(self):
103        """Check whether a button has been clicked.
104
105        Call append_buttons() before this to add buttons to the document.
106
107        @return index of button that was clicked or -1 if no button
108            has been clicked.
109
110        """
111        return self._proxy.check_for_button()
112
113
114    def append_list(self, name):
115        """Append a results list to the contents of the tab.
116
117        @param name: Name to use for making modifications to the list.
118
119        @return True.
120
121        """
122        return self._proxy.append_list(name)
123
124
125    def append_list_item(self, list_name, item_name, html):
126        """Append an item to a results list.
127
128        @param list_name: Name of list provided to append_list().
129        @param item_name: Name to use for making modifications to the item.
130        @param html: HTML to place in the list item.
131
132        @return True.
133
134        """
135        return self._proxy.append_list_item(list_name, item_name, html)
136
137
138    def replace_list_item(self, item_name, html):
139        """Replace an item in a results list.
140
141        @param item_name: Name of item provided to append_list_item().
142        @param html: HTML to place in the list item.
143
144        @return True.
145
146        """
147        return self._proxy.replace_list_item(item_name, html)
148
149
150    def close(self):
151        """Tear down state associated with the client."""
152        # Log out the browser.
153        self._proxy.close()
154        # This does not close the host because it's shared with the client.
155