Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(142)

Side by Side Diff: chrome/test/pyautolib/chromotinglib.py

Issue 222873002: Remove pyauto tests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: sync Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 # Copyright (c) 2012 The Chromium 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
5 """Includes different methods to drive chromoting UI."""
6
7 import os
8 import subprocess
9 import sys
10 import time
11
12 from pyauto_errors import JSONInterfaceError
13
14
15 class ChromotingMixIn(object):
16 """MixIn for PyUITest that adds Chromoting-specific methods.
17
18 Prepend it as a base class of a test to enable Chromoting functionality.
19 This is a separate class from PyUITest to avoid namespace collisions.
20
21 Example usage:
22 class ChromotingExample(chromoting.ChromotingMixIn, pyauto.PyUITest):
23 def testShare(self):
24 app = self.InstallApp(self.GetWebappPath())
25 self.LaunchApp(app)
26 self.Authenticate()
27 self.assertTrue(self.Share())
28 """
29
30 def _ExecuteJavascript(self, command, tab_index, windex):
31 """Helper that returns immediately after running a Javascript command.
32 """
33 try:
34 self.ExecuteJavascript(
35 '%s; window.domAutomationController.send("done");' % command,
36 tab_index, windex)
37 return True
38 except JSONInterfaceError:
39 print '_ExecuteJavascript threw JSONInterfaceError'
40 return False
41
42 def _WaitForJavascriptCondition(self, condition, tab_index, windex,
43 timeout=-1):
44 """Waits until the Javascript condition is true.
45
46 This is different from a naive self.WaitUntil(lambda: self.GetDOMValue())
47 because it uses Javascript to check the condition instead of Python.
48
49 Returns: True if condition is satisfied or otherwise False.
50 """
51 try:
52 return self.WaitUntil(lambda: self.GetDOMValue(
53 '(%s) ? "1" : ""' % condition, tab_index, windex), timeout)
54 except JSONInterfaceError:
55 print '_WaitForJavascriptCondition threw JSONInterfaceError'
56 return False
57
58 def _ExecuteAndWaitForMode(self, command, mode, tab_index, windex):
59 """ Executes JavaScript and wait for remoting app mode equal to
60 the given mode.
61
62 Returns: True if condition is satisfied or otherwise False.
63 """
64 if not self._ExecuteJavascript(command, tab_index, windex):
65 return False
66 return self._WaitForJavascriptCondition(
67 'remoting.currentMode == remoting.AppMode.%s' % mode,
68 tab_index, windex)
69
70 def _ExecuteAndWaitForMajorMode(self, command, mode, tab_index, windex):
71 """ Executes JavaScript and wait for remoting app major mode equal to
72 the given mode.
73
74 Returns: True if condition is satisfied or otherwise False.
75 """
76 if not self._ExecuteJavascript(command, tab_index, windex):
77 return False
78 return self._WaitForJavascriptCondition(
79 'remoting.getMajorMode() == remoting.AppMode.%s' % mode,
80 tab_index, windex)
81
82 def GetWebappPath(self):
83 """Returns the path to the webapp.
84
85 Expects the webapp to be in the same place as the pyautolib binaries.
86 """
87 return os.path.join(self.BrowserPath(), 'remoting', 'remoting.webapp')
88
89 def _GetHelperRunner(self):
90 """Returns the python binary name that runs chromoting_helper.py."""
91 if sys.platform.startswith('win'):
92 return 'python'
93 else:
94 return 'suid-python'
95
96 def _GetHelper(self):
97 """Get chromoting_helper.py."""
98 return os.path.join(os.path.dirname(__file__), 'chromoting_helper.py')
99
100 def InstallHostDaemon(self):
101 """Installs the host daemon."""
102 subprocess.call([self._GetHelperRunner(), self._GetHelper(),
103 'install', self.BrowserPath()])
104
105 def UninstallHostDaemon(self):
106 """Uninstalls the host daemon."""
107 subprocess.call([self._GetHelperRunner(), self._GetHelper(),
108 'uninstall', self.BrowserPath()])
109
110 def ContinueAuth(self, tab_index=1, windex=0):
111 """Starts authentication."""
112 self.assertTrue(
113 self._WaitForJavascriptCondition('window.remoting && remoting.oauth2',
114 tab_index, windex),
115 msg='Timed out while waiting for remoting app to finish loading.')
116 self._ExecuteJavascript('remoting.oauth2.doAuthRedirect();',
117 tab_index, windex)
118
119 def SignIn(self, email=None, password=None, otp=None,
120 tab_index=1, windex=0):
121 """Logs a user in.
122
123 PyAuto tests start with a clean profile, so Chromoting tests should call
124 this for every run after launching the app. If email or password is
125 omitted, the user can type it into the browser window manually.
126 """
127 self.assertTrue(
128 self._WaitForJavascriptCondition('document.getElementById("signIn")',
129 tab_index, windex),
130 msg='Unable to redirect for authentication.')
131
132 if email:
133 self._ExecuteJavascript('document.getElementById("Email").value = "%s";'
134 'document.getElementById("Passwd").focus();'
135 % email, tab_index, windex)
136
137 if password:
138 self._ExecuteJavascript('document.getElementById("Passwd").value = "%s";'
139 'document.getElementById("signIn").click();'
140 % password, tab_index, windex)
141
142 if otp:
143 self.assertTrue(
144 self._WaitForJavascriptCondition(
145 'document.getElementById("smsVerifyPin")',
146 tab_index, windex),
147 msg='Invalid username or password.')
148 self._ExecuteJavascript(
149 'document.getElementById("smsUserPin").value = "%s";'
150 'document.getElementById("smsVerifyPin").click();' % otp,
151 tab_index, windex)
152
153 # If the account adder screen appears, then skip it.
154 self.assertTrue(
155 self._WaitForJavascriptCondition(
156 'document.getElementById("skip") || '
157 'document.getElementById("submit_approve_access")',
158 tab_index, windex),
159 msg='No "skip adding account" or "approve access" link.')
160 self._ExecuteJavascript(
161 'if (document.getElementById("skip")) '
162 '{ document.getElementById("skip").click(); }',
163 tab_index, windex)
164
165 def AllowAccess(self, tab_index=1, windex=0):
166 """Allows access to chromoting webapp."""
167 # Approve access.
168 self.assertTrue(
169 self._WaitForJavascriptCondition(
170 'document.getElementById("submit_approve_access")',
171 tab_index, windex),
172 msg='Did not go to permission page.')
173 self._WaitForJavascriptCondition(
174 '!document.getElementById("submit_approve_access").disabled',
175 tab_index, windex)
176 self._ExecuteJavascript(
177 'document.getElementById("submit_approve_access").click();',
178 tab_index, windex)
179
180 # Wait for some things to be ready.
181 self.assertTrue(
182 self._WaitForJavascriptCondition(
183 'window.remoting && remoting.oauth2 && ' \
184 'remoting.oauth2.isAuthenticated()',
185 tab_index, windex),
186 msg='OAuth2 authentication failed.')
187 self.assertTrue(
188 self._WaitForJavascriptCondition(
189 'window.localStorage.getItem("remoting-email")',
190 tab_index, windex),
191 msg='Chromoting app did not reload after authentication.')
192
193 def DenyAccess(self, tab_index=1, windex=0):
194 """Deny and then allow access to chromoting webapp."""
195 self.assertTrue(
196 self._WaitForJavascriptCondition(
197 'document.getElementById("submit_deny_access")',
198 tab_index, windex),
199 msg='Did not go to permission page.')
200 self._WaitForJavascriptCondition(
201 '!document.getElementById("submit_deny_access").disabled',
202 tab_index, windex)
203 self._ExecuteJavascript(
204 'document.getElementById("submit_deny_access").click();',
205 tab_index, windex)
206
207 def SignOut(self, tab_index=1, windex=0):
208 """Signs out from chromoting and signs back in."""
209 self._ExecuteAndWaitForMode(
210 'document.getElementById("sign-out").click();',
211 'UNAUTHENTICATED', tab_index, windex)
212
213 def Authenticate(self, tab_index=1, windex=0):
214 """Finishes authentication flow for user."""
215 self.ContinueAuth(tab_index, windex)
216 account = self.GetPrivateInfo()['test_chromoting_account']
217 self.host.SignIn(account['username'], account['password'], None,
218 tab_index, windex)
219 self.host.AllowAccess(tab_index, windex)
220
221 def StartMe2Me(self, tab_index=1, windex=0):
222 """Starts Me2Me. """
223 self._ExecuteJavascript(
224 'document.getElementById("get-started-me2me").click();',
225 tab_index, windex)
226 self.assertTrue(
227 self._WaitForJavascriptCondition(
228 'document.getElementById("me2me-content").hidden == false',
229 tab_index, windex),
230 msg='No me2me content')
231
232 def Share(self, tab_index=1, windex=0):
233 """Generates an access code and waits for incoming connections.
234
235 Returns:
236 The access code on success; None otherwise.
237 """
238 self._ExecuteAndWaitForMode(
239 'remoting.tryShare();',
240 'HOST_WAITING_FOR_CONNECTION', tab_index, windex)
241 return self.GetDOMValue(
242 'document.getElementById("access-code-display").innerText',
243 tab_index, windex)
244
245 def CancelShare(self, tab_index=1, windex=0):
246 """Stops sharing the desktop on the host side."""
247 self.assertTrue(
248 self._ExecuteAndWaitForMode(
249 'remoting.cancelShare();',
250 'HOST_SHARE_FINISHED', tab_index, windex),
251 msg='Stopping sharing from the host side failed')
252
253 def CleanupHostList(self, tab_index=1, windex=0):
254 """Removes hosts due to failure on previous stop-daemon"""
255 self.EnableConnectionsInstalled()
256 this_host_name = self.GetDOMValue(
257 'document.getElementById("this-host-name").textContent',
258 tab_index, windex)
259 if this_host_name.endswith(' (offline)'):
260 this_host_name = this_host_name[:-10]
261 self.DisableConnections()
262
263 total_hosts = self.GetDOMValue(
264 'document.getElementById("host-list").childNodes.length',
265 tab_index, windex)
266
267 # Start from the end while deleting bogus hosts
268 index = total_hosts
269 while index > 0:
270 index -= 1
271 try:
272 hostname = self.GetDOMValue(
273 'document.getElementById("host-list")'
274 '.childNodes[%s].textContent' % index,
275 tab_index, windex)
276 if hostname == this_host_name or \
277 hostname == this_host_name + ' (offline)':
278 self._ExecuteJavascript(
279 'document.getElementById("host-list")'
280 '.childNodes[%s].childNodes[3].click()' % index,
281 tab_index, windex)
282 self._ExecuteJavascript(
283 'document.getElementById("confirm-host-delete").click()',
284 tab_index, windex)
285 except JSONInterfaceError:
286 print 'Ignore the error on deleting host'
287
288 if self._WaitForJavascriptCondition(
289 'document.getElementById("this-host-connect")'
290 '.getAttribute("data-daemon-state") == "enabled"',
291 tab_index, windex, 1):
292 self.DisableConnections()
293
294 def EnableConnectionsInstalled(self, pin_exercise=False,
295 tab_index=1, windex=0):
296 """Enables the remote connections on the host side."""
297 if sys.platform.startswith('darwin'):
298 subprocess.call([self._GetHelperRunner(), self._GetHelper(), 'enable'])
299
300 self.assertTrue(
301 self._ExecuteAndWaitForMode(
302 'document.getElementById("start-daemon").click();',
303 'HOST_SETUP_ASK_PIN', tab_index, windex),
304 msg='Cannot start host setup')
305 self.assertTrue(
306 self._WaitForJavascriptCondition(
307 'document.getElementById("ask-pin-form").hidden == false',
308 tab_index, windex),
309 msg='No ask pin dialog')
310
311 if pin_exercise:
312 # Cancels the pin prompt
313 self._ExecuteJavascript(
314 'document.getElementById("daemon-pin-cancel").click();',
315 tab_index, windex)
316
317 # Enables again
318 self.assertTrue(
319 self._ExecuteAndWaitForMode(
320 'document.getElementById("start-daemon").click();',
321 'HOST_SETUP_ASK_PIN', tab_index, windex),
322 msg='Cannot start host setup')
323
324 # Click ok without typing in pins
325 self._ExecuteJavascript(
326 'document.getElementById("daemon-pin-ok").click();',
327 tab_index, windex)
328 self.assertTrue(
329 self._WaitForJavascriptCondition(
330 'document.getElementById("daemon-pin-error-message")',
331 tab_index, windex),
332 msg='No pin error message')
333
334 # Mis-matching pins
335 self._ExecuteJavascript(
336 'document.getElementById("daemon-pin-entry").value = "111111";',
337 tab_index, windex)
338 self._ExecuteJavascript(
339 'document.getElementById("daemon-pin-confirm").value = "123456";',
340 tab_index, windex)
341 self.assertTrue(
342 self._WaitForJavascriptCondition(
343 'document.getElementById("daemon-pin-error-message")',
344 tab_index, windex),
345 msg='No pin error message')
346
347 # Types in correct pins
348 self._ExecuteJavascript(
349 'document.getElementById("daemon-pin-entry").value = "111111";',
350 tab_index, windex)
351 self._ExecuteJavascript(
352 'document.getElementById("daemon-pin-confirm").value = "111111";',
353 tab_index, windex)
354 self.assertTrue(
355 self._ExecuteAndWaitForMode(
356 'document.getElementById("daemon-pin-ok").click();',
357 'HOST_SETUP_PROCESSING', tab_index, windex),
358 msg='Host setup was not started')
359
360 # Handles preference panes
361 self.assertTrue(
362 self._WaitForJavascriptCondition(
363 'remoting.currentMode == remoting.AppMode.HOST_SETUP_DONE',
364 tab_index, windex),
365 msg='Host setup was not done')
366
367 # Dismisses the host config done dialog
368 self.assertTrue(
369 self._WaitForJavascriptCondition(
370 'document.getElementById("host-setup-dialog")'
371 '.childNodes[5].hidden == false',
372 tab_index, windex),
373 msg='No host setup done dialog')
374 self.assertTrue(
375 self._ExecuteAndWaitForMode(
376 'document.getElementById("host-config-done-dismiss").click();',
377 'HOME', tab_index, windex),
378 msg='Failed to dismiss host setup confirmation dialog')
379
380 def EnableConnectionsUninstalledAndCancel(self, tab_index=1, windex=0):
381 """Enables remote connections while host is not installed yet."""
382 self.assertTrue(
383 self._ExecuteAndWaitForMode(
384 'document.getElementById("start-daemon").click();',
385 'HOST_SETUP_INSTALL', tab_index, windex),
386 msg='Cannot start host install')
387 self.assertTrue(
388 self._ExecuteAndWaitForMode(
389 'document.getElementById("host-config-install-dismiss").click();',
390 'HOME', tab_index, windex),
391 msg='Failed to dismiss host install dialog')
392
393 def DisableConnections(self, tab_index=1, windex=0):
394 """Disables the remote connections on the host side."""
395 if sys.platform.startswith('darwin'):
396 subprocess.call([self._GetHelperRunner(), self._GetHelper(), 'disable'])
397
398 # Re-try to make disabling connection more stable
399 for _ in range (1, 4):
400 self._ExecuteJavascript(
401 'document.getElementById("stop-daemon").click();',
402 tab_index, windex)
403
404 # Immediately waiting for host-setup-dialog hidden sometimes times out
405 # even though visually it is hidden. Add some sleep here
406 time.sleep(2)
407
408 if self._WaitForJavascriptCondition(
409 'document.getElementById("host-setup-dialog")'
410 '.childNodes[3].hidden == true',
411 tab_index, windex, 1):
412 break;
413
414 self.assertTrue(
415 self._ExecuteAndWaitForMode(
416 'document.getElementById("host-config-done-dismiss").click();',
417 'HOME', tab_index, windex),
418 msg='Failed to dismiss host setup confirmation dialog')
419
420 def Connect(self, access_code, tab_index=1, windex=0):
421 """Connects to a Chromoting host and starts the session."""
422 self.assertTrue(
423 self._ExecuteAndWaitForMode(
424 'document.getElementById("access-code-entry").value = "%s";'
425 'remoting.connectIt2Me();' % access_code,
426 'IN_SESSION', tab_index, windex),
427 msg='Cannot connect it2me session')
428
429 def ChangePin(self, pin='222222', tab_index=1, windex=0):
430 """Changes pin for enabled host."""
431 if sys.platform.startswith('darwin'):
432 subprocess.call([self._GetHelperRunner(), self._GetHelper(), 'changepin'])
433
434 self.assertTrue(
435 self._ExecuteAndWaitForMode(
436 'document.getElementById("change-daemon-pin").click();',
437 'HOST_SETUP_ASK_PIN', tab_index, windex),
438 msg='Cannot change daemon pin')
439 self.assertTrue(
440 self._WaitForJavascriptCondition(
441 'document.getElementById("ask-pin-form").hidden == false',
442 tab_index, windex),
443 msg='No ask pin dialog')
444
445 self._ExecuteJavascript(
446 'document.getElementById("daemon-pin-entry").value = "' + pin + '";',
447 tab_index, windex)
448 self._ExecuteJavascript(
449 'document.getElementById("daemon-pin-confirm").value = "' +
450 pin + '";', tab_index, windex)
451 self.assertTrue(
452 self._ExecuteAndWaitForMode(
453 'document.getElementById("daemon-pin-ok").click();',
454 'HOST_SETUP_PROCESSING', tab_index, windex),
455 msg='Host setup was not started')
456
457 # Handles preference panes
458 self.assertTrue(
459 self._WaitForJavascriptCondition(
460 'remoting.currentMode == remoting.AppMode.HOST_SETUP_DONE',
461 tab_index, windex),
462 msg='Host setup was not done')
463
464 # Dismisses the host config done dialog
465 self.assertTrue(
466 self._WaitForJavascriptCondition(
467 'document.getElementById("host-setup-dialog")'
468 '.childNodes[5].hidden == false',
469 tab_index, windex),
470 msg='No host setup done dialog')
471 self.assertTrue(
472 self._ExecuteAndWaitForMode(
473 'document.getElementById("host-config-done-dismiss").click();',
474 'HOME', tab_index, windex),
475 msg='Failed to dismiss host setup confirmation dialog')
476
477 def ChangeName(self, new_name='Changed', tab_index=1, windex=0):
478 """Changes the host name."""
479 self._ExecuteJavascript(
480 'document.getElementById("this-host-rename").click();',
481 tab_index, windex)
482 self._ExecuteJavascript(
483 'document.getElementById("this-host-name").childNodes[0].value = "' +
484 new_name + '";', tab_index, windex)
485 self._ExecuteJavascript(
486 'document.getElementById("this-host-rename").click();',
487 tab_index, windex)
488
489 def ConnectMe2Me(self, pin='111111', mode='IN_SESSION',
490 tab_index=1, windex=0):
491 """Connects to a Chromoting host and starts the session."""
492
493 # There is delay from the enabling remote connections to the host
494 # showing up in the host list. We need to reload the web app to get
495 # the host to show up. We will repeat this a few times to make sure
496 # eventually host appears.
497 for _ in range(1, 13):
498 self._ExecuteJavascript(
499 'window.location.reload();',
500 tab_index, windex)
501
502 # pyauto _GetResultFromJSONRequest throws JSONInterfaceError after
503 # 45 seconds if ExecuteJavascript is called right after reload.
504 # Waiting 2s here can avoid this. So instead of getting the error and
505 # wait 45s, we wait 2s here. If the error still happens, the following
506 # retry will handle that.
507 time.sleep(2)
508
509 # If this-host-connect is still not enabled, let's retry one more time.
510 this_host_connect_enabled = False
511 for _ in range(1, 3):
512 daemon_state_enabled = self._WaitForJavascriptCondition(
513 'document.getElementById("this-host-connect")'
514 '.getAttribute("data-daemon-state") == "enabled"',
515 tab_index, windex, 1)
516 host_online = self._WaitForJavascriptCondition(
517 'document.getElementById("this-host-name")'
518 '.textContent.toString().indexOf("offline") == -1',
519 tab_index, windex, 1)
520 this_host_connect_enabled = daemon_state_enabled and host_online
521 if this_host_connect_enabled:
522 break
523 if this_host_connect_enabled:
524 break;
525
526 # Clicking this-host-connect does work right after this-host-connect
527 # is enabled. Need to retry.
528 for _ in range(1, 4):
529 self._ExecuteJavascript(
530 'document.getElementById("this-host-connect").click();',
531 tab_index, windex)
532
533 # pyauto _GetResultFromJSONRequest throws JSONInterfaceError after
534 # a long time out if WaitUntil is called right after click.
535 # Waiting 2s here can avoid this.
536 time.sleep(2)
537
538 # If cannot detect that pin-form appears, retry one more time.
539 pin_form_exposed = False
540 for _ in range(1, 3):
541 pin_form_exposed = self._WaitForJavascriptCondition(
542 'document.getElementById("client-dialog")'
543 '.childNodes[9].hidden == false',
544 tab_index, windex, 1)
545 if pin_form_exposed:
546 break
547
548 if pin_form_exposed:
549 break
550
551 # Dismiss connect failure dialog before retry
552 if self._WaitForJavascriptCondition(
553 'document.getElementById("client-dialog")'
554 '.childNodes[25].hidden == false',
555 tab_index, windex, 1):
556 self._ExecuteJavascript(
557 'document.getElementById("client-finished-me2me-button")'
558 '.click();',
559 tab_index, windex)
560
561 self._ExecuteJavascript(
562 'document.getElementById("pin-entry").value = "' + pin + '";',
563 tab_index, windex)
564 self.assertTrue(
565 self._ExecuteAndWaitForMode(
566 'document.getElementById("pin-form").childNodes[5].click();',
567 mode, tab_index, windex),
568 msg='Session was not started')
569
570 def Disconnect(self, tab_index=1, windex=0):
571 """Disconnects from the Chromoting it2me session on the client side."""
572 self.assertTrue(
573 self._ExecuteAndWaitForMode(
574 'remoting.disconnect();',
575 'CLIENT_SESSION_FINISHED_IT2ME', tab_index, windex),
576 msg='Disconnecting it2me session from the client side failed')
577
578 def DisconnectMe2Me(self, confirmation=True, tab_index=1, windex=0):
579 """Disconnects from the Chromoting me2me session on the client side."""
580 self.assertTrue(
581 self._ExecuteAndWaitForMode(
582 'remoting.disconnect();',
583 'CLIENT_SESSION_FINISHED_ME2ME', tab_index, windex),
584 msg='Disconnecting me2me session from the client side failed')
585
586 if confirmation:
587 self.assertTrue(
588 self._ExecuteAndWaitForMode(
589 'document.getElementById("client-finished-me2me-button")'
590 '.click();', 'HOME', tab_index, windex),
591 msg='Failed to dismiss session finished dialog')
592
593 def ReconnectMe2Me(self, pin='111111', tab_index=1, windex=0):
594 """Reconnects the me2me session."""
595 self._ExecuteJavascript(
596 'document.getElementById("client-reconnect-button").click();',
597 tab_index, windex)
598
599 # pyauto _GetResultFromJSONRequest throws JSONInterfaceError after
600 # a long time out if WaitUntil is called right after click.
601 time.sleep(2)
602
603 # If cannot detect that pin-form appears, retry one more time.
604 for _ in range(1, 3):
605 pin_form_exposed = self._WaitForJavascriptCondition(
606 'document.getElementById("client-dialog")'
607 '.childNodes[9].hidden == false',
608 tab_index, windex, 1)
609 if pin_form_exposed:
610 break
611
612 self._ExecuteJavascript(
613 'document.getElementById("pin-entry").value = "' + pin + '";',
614 tab_index, windex)
615 self.assertTrue(
616 self._ExecuteAndWaitForMode(
617 'document.getElementById("pin-form").childNodes[5].click();',
618 'IN_SESSION', tab_index, windex),
619 msg='Session was not started when reconnecting')
OLDNEW
« no previous file with comments | « chrome/test/pyautolib/chromoting_key.p12 ('k') | chrome/test/pyautolib/dom_mutation_observer.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698