1
2 import requests
3 import time
4
5 import pytest
6 import re
7 from _pytest import runner
8 from tlib.base import TestHelper
9 import logging
10
11 DEVICE_UNPLUGGED = "disconnected"
12 DEVICE_OFFLINE = "offline"
13 DEVICE_UNAUTHORIZED = "unauthorized"
14 DEVICE_ONLINE = "online"
15
17 """
18 Function to validate if webdriver is running and a connection can be established
19
20 @param tlib_logger: TLib logger
21 @type tlib_logger: logging.logger
22 @param adb_logger: ADB logger
23 @type adb_logger: logging.logger
24 @param log: When true, log debugging information
25 @type log: bool
26 """
27 try:
28 if log: tlib_logger.debug("Checking if Webdriver is running")
29 response = requests.get("http://localhost:8080/wd/hub/status", timeout=10)
30 except requests.ConnectionError as e:
31 if log: adb_logger.debug("Connection to Webdriver failed:\n%s" % e)
32 return False
33
34 return response.status_code == 200
35
36
38 """
39 Get status of a device using it's serial id\n
40 Serial id can be either a ID (for devices connected to USB) or an IP and port (For devices connected via IP)
41
42 @param tlib_logger: TLib logger
43 @type tlib_logger: logging.logger
44 @param adb_logger: ADB logger
45 @type adb_logger: logging.logger
46 @param serial_id: Device's serial number
47 @type serial_id: str
48 """
49
50 out = TestHelper.run_command(adb_logger, ["adb", "devices"], fail_on_error=False)
51 if re.search(serial_id, out[0]) is None:
52 tlib_logger.debug("Device {serial_id} is not connected".format(serial_id=serial_id))
53 return DEVICE_UNPLUGGED
54 elif re.search("{serial_id}\s+offline".format(serial_id=serial_id), out[0]) is not None:
55 tlib_logger.debug("Device {serial_id} is offline".format(serial_id=serial_id))
56 return DEVICE_OFFLINE
57 elif re.search("{serial_id}\s+unauthorized".format(serial_id=serial_id), out[0]) is not None:
58 tlib_logger.debug("Device {serial_id} is offline".format(serial_id=serial_id))
59 return DEVICE_UNAUTHORIZED
60 elif re.search("{serial_id}\s+device".format(serial_id=serial_id), out[0]) is not None:
61 tlib_logger.debug("Device {serial_id} is online".format(serial_id=serial_id))
62 return DEVICE_ONLINE
63 else:
64 tlib_logger.error("Unknown device status\n%s" % out[0])
65 pytest.fail("Unknown device status\n%s" % out[0])
66
67
69 """
70 Connects to an android device via IP and waits for the connection to be established.
71
72 @param tlib_logger: TLib logger
73 @type tlib_logger: logging.logger
74 @param adb_logger: ADB logger
75 @type adb_logger: logging.logger
76 @param serial_id: Device's serial number
77 @type serial_id: str
78 """
79
80 tlib_logger.debug("Setting up IP connection to device {serial_id}".format(serial_id=serial_id))
81 status = get_device_status(tlib_logger, adb_logger, serial_id)
82
83 if status == DEVICE_ONLINE:
84 tlib_logger.debug("Device is already online".format(serial_id=serial_id))
85 return
86
87
88 if status == DEVICE_OFFLINE:
89 tlib_logger.warn("Device {serial_id} is offline, disconnecting and retrying".format(serial_id=serial_id))
90 terminate_ip_connection(tlib_logger, adb_logger, serial_id)
91 elif status == DEVICE_UNAUTHORIZED:
92 terminate_ip_connection(tlib_logger, adb_logger, serial_id)
93 tlib_logger.error("Device {serial_id} is not authorized, aborting".format(serial_id=serial_id))
94 pytest.fail("Device {serial_id} is not authorized, aborting".format(serial_id=serial_id))
95 elif status == DEVICE_UNPLUGGED:
96 tlib_logger.warn("Device {serial_id} is disconecting, resetting connection".format(serial_id=serial_id))
97 terminate_ip_connection(tlib_logger, adb_logger, serial_id)
98
99 timeout = 0.5
100
101
102 for i in range(1, int(3 / timeout)):
103 out = TestHelper.run_command(adb_logger, ["adb", "connect", serial_id])
104 log_adb_output(adb_logger, out)
105
106 if get_device_status(tlib_logger, adb_logger, serial_id) == DEVICE_ONLINE:
107 tlib_logger.debug("Connected to device")
108 return
109 else:
110 tlib_logger.debug("Not yet connected")
111 time.sleep(timeout)
112
113
114 adb_logger.error(r"Timeout while connecting to device {serial_id}\nADB output:\n{out}".format(serial_id=serial_id, out=out))
115
116 pytest.fail(r"Timeout while connecting to device {serial_id}\nADB output:\n{out}".format(serial_id=serial_id, out=out))
117
118
120 """
121 Disconnects from device
122
123 @param tlib_logger: TLib logger
124 @type tlib_logger: logging.logger
125 @param adb_logger: ADB logger
126 @type adb_logger: logging.logger
127 @param serial_id: Device's serial number
128 @type serial_id: str
129 """
130 tlib_logger.debug("Disconnecting from device {serial_id}".format(serial_id=serial_id))
131 out = TestHelper.run_command(adb_logger, ["adb", "disconnect", serial_id])
132 log_adb_output(adb_logger, out)
133
134
136 """
137 Stops Webdriver app o the device
138
139 @param tlib_logger: TLib logger
140 @type tlib_logger: logging.logger
141 @param adb_logger: ADB logger
142 @type adb_logger: logging.logger
143 @param serial_id: Device's serial number
144 @type serial_id: str
145 """
146 tlib_logger.debug("Closing Webdriver on {serial_id}".format(serial_id=serial_id))
147 if serial_id is None or serial_id == "":
148 out = TestHelper.run_command(adb_logger,
149 ["adb", "shell", "am", "force-stop", "org.openqa.selenium.android.app"])
150 else:
151 out = TestHelper.run_command(adb_logger,
152 ["adb", "-s", serial_id, "shell", "am", "force-stop", "org.openqa.selenium.android.app"])
153 log_adb_output(adb_logger, out)
154
155
157 """
158 Setup port forwarding between computer and device.
159
160 @param tlib_logger: TLib logger
161 @type tlib_logger: logging.logger
162 @param adb_logger: ADB logger
163 @type adb_logger: logging.logger
164 @param serial_id: Device's serial number
165 @type serial_id: str
166 """
167 tlib_logger.info("Setting up port forwarding")
168 if serial_id is None or serial_id == "":
169 out = TestHelper.run_command(adb_logger, ["adb", "forward", "tcp:8080", "tcp:8080"])
170 else:
171 out = TestHelper.run_command(adb_logger, ["adb", "-s", serial_id, "forward", "tcp:8080", "tcp:8080"])
172 log_adb_output(adb_logger, out)
173
174
176 """
177 Terminates all port forwarding connections
178
179 @param tlib_logger: TLib logger
180 @type tlib_logger: logging.logger
181 @param adb_logger: ADB logger
182 @type adb_logger: logging.logger
183 """
184 tlib_logger.info("Tearing down port forwarding")
185 out = TestHelper.run_command(adb_logger, ["adb", "forward", "--remove-all"])
186 log_adb_output(adb_logger, out)
187
188
190 """
191 Stops adb on the machine\n
192 This can be required by TeamCity so some folders are not locked
193
194 @param tlib_logger: TLib logger
195 @type tlib_logger: logging.logger
196 @param adb_logger: ADB logger
197 @type adb_logger: logging.logger
198 """
199 tlib_logger.info("Stopping ADB")
200 out = TestHelper.run_command(adb_logger, ["adb", "kill-server"], fail_on_error=False)
201 log_adb_output(adb_logger, out)
202
203
205 """
206 Starts Webdriver app on the device
207
208 @param tlib_logger: TLib logger
209 @type tlib_logger: logging.logger
210 @param adb_logger: ADB logger
211 @type adb_logger: logging.logger
212 @param serial_id: Device's serial number
213 @type serial_id: str
214 """
215 tlib_logger.info("Starting webdriver on the device")
216 if serial_id is None or serial_id == "":
217 out = TestHelper.run_command(adb_logger, ["adb", "shell", "am", "start", "-a", "android.intent.action.MAIN",
218 "-n", "org.openqa.selenium.android.app/.MainActivity", "-e", "debug", "true"])
219 else:
220 out = TestHelper.run_command(adb_logger,
221 ["adb", "-s", serial_id, "shell", "am", "start", "-a", "android.intent.action.MAIN",
222 "-n", "org.openqa.selenium.android.app/.MainActivity",
223 "-e", "debug", "true"])
224 log_adb_output(adb_logger, out)
225
226
228 """
229 Waits up to 3 seconds for a connection to Webdriver
230
231 @param tlib_logger: TLib logger
232 @type tlib_logger: logging.logger
233 @param adb_logger: ADB logger
234 @type adb_logger: logging.logger
235 """
236
237 tlib_logger.debug("Waiting for connection to Webdriver")
238 timeout = 0.5
239 for i in range(1, int(3 / timeout)):
240 if is_webdriver_running(tlib_logger, adb_logger, False):
241 tlib_logger.debug("Webdriver started successfully")
242 break
243 tlib_logger.debug("Can't connect to Webdriver, retrying in {timeout} seconds".format(timeout=timeout))
244 time.sleep(timeout)
245
246 if not is_webdriver_running(tlib_logger, adb_logger, False):
247 tlib_logger.error("Couldn't start Webdriver. Make sure it's installed and running\n"
248 "See https://code.google.com/p/selenium/wiki/AndroidDriver#Setup_the_Emulator for more details")
249
250 pytest.fail("Couldn't start Webdriver. Make sure it's installed and running\n"
251 "See https://code.google.com/p/selenium/wiki/AndroidDriver#Setup_the_Emulator for more details")
252
253
254
256 """
257 Connects to a device and starts webdriver
258
259 @param tlib_logger: TLib logger
260 @type tlib_logger: logging.logger
261 @param adb_logger: ADB logger
262 @type adb_logger: logging.logger
263 @param serial_id: Device's serial number
264 @type serial_id: str
265 """
266
267 if is_webdriver_running(tlib_logger, adb_logger, log=False):
268 tlib_logger.debug("Already connected to device")
269 return
270
271 tlib_logger.info("Connecting to Webdriver")
272
273
274 if TestHelper.is_valid_ip(serial_id):
275 setup_ip_connection(tlib_logger, adb_logger, serial_id)
276
277 setup_port_forwarding(tlib_logger, adb_logger, serial_id)
278
279
280 if is_webdriver_running(tlib_logger, adb_logger):
281 tlib_logger.debug("Connected to Webdriver")
282 return
283
284
285 start_webdriver(tlib_logger, adb_logger, serial_id)
286
287
288 wait_for_connection_to_webdriver(tlib_logger, adb_logger)
289
290 tlib_logger.info("Connection to Webdriver established")
291
292
293
295 """
296 Closes webdriver and disconnects from device
297
298 @param tlib_logger: TLib logger
299 @type tlib_logger: logging.logger
300 @param adb_logger: ADB logger
301 @type adb_logger: logging.logger
302 @param serial_id: Device's serial number
303 @type serial_id: str
304 """
305
306 tlib_logger.info("Disconnecting from Webdriver")
307 close_webdriver(tlib_logger, adb_logger, serial_id)
308
309
310 if TestHelper.is_valid_ip(serial_id):
311 terminate_ip_connection(tlib_logger, adb_logger, serial_id)
312
313
314 try:
315 stop_adb_server(tlib_logger, adb_logger)
316 except runner.Failed:
317
318 adb_logger.warn("Error stopping ADB server")
319
320 tlib_logger.info("Disconnected from Webdriver")
321
322
324 """
325 Logs ADB output
326
327 @param logger: ADB logger
328 @type logger: logging.logger
329 """
330 if out[0] is not None and out[0] != '':
331 logger.debug("\n" + out[0])
332
333 if out[1] is not None and out[1] != '':
334 logger.debug("\n" + out[1])
335