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