Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 #!/usr/bin/python | |
| 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
| 3 # Use of this source code is governed by a BSD-style license that can be | |
| 4 # found in the LICENSE file. | |
| 5 | |
| 6 """Basic sanity tests for the GTalk extension (http://go/quasar) | |
| 7 | |
| 8 This module contains the basic set of sanity tests run on the | |
| 9 GTalk extension: | |
| 10 https://chrome.google.com/webstore/detail/nckgahadagoaajjgafhacjanaoiihapd | |
| 11 """ | |
| 12 | |
| 13 import logging | |
| 14 import sys | |
| 15 import time | |
| 16 import traceback | |
| 17 import urllib2 | |
| 18 | |
| 19 import gtalk_base_test | |
| 20 import pyauto_functional | |
|
Nirnimesh
2011/12/13 20:03:25
this script need not know about pyauto_functional.
wud
2011/12/13 20:54:08
Done.
| |
| 21 import pyauto_gtalk # must preceed pyauto | |
| 22 import pyauto | |
| 23 | |
| 24 | |
| 25 class BasicTest(gtalk_base_test.GTalkBaseTest): | |
| 26 """Test for Google Talk Chrome Extension.""" | |
| 27 | |
| 28 def Prompt(self, text): | |
| 29 """Pause execution with debug output. | |
| 30 | |
| 31 Args: | |
| 32 text: The debug output. | |
| 33 """ | |
| 34 text = str(text) | |
| 35 raw_input('--------------------> ' + text.encode('utf-8')) | |
| 36 | |
| 37 def _OpenRoster(self): | |
| 38 """Download Talk extension and open the roster.""" | |
| 39 | |
| 40 self.InstallGTalkExtension() | |
| 41 | |
| 42 # Wait for the background view to load. | |
| 43 extension = self.GetGTalkExtensionInfo() | |
| 44 background_view = self.WaitUntilExtensionViewLoaded( | |
| 45 extension_id=extension['id'], | |
| 46 view_type='EXTENSION_BACKGROUND_PAGE') | |
| 47 self.assertTrue(background_view, | |
| 48 msg='Failed to get background view: views = %s.' % | |
| 49 self.GetBrowserInfo()['extension_views']) | |
| 50 | |
| 51 # Wait for the custom QTest hook to load. | |
| 52 self.WaitUntilResult(True, | |
| 53 lambda: self.RunInBackground('Boolean(QTest)'), | |
| 54 msg='Timed out waiting for QTest.handleBrowserAction function') | |
| 55 | |
| 56 # Run hook to simluate clicking the browser action icon. | |
| 57 # TODO(wud): replace after click BA icon is supported. | |
| 58 # See http://crbug.com/97342. | |
|
Nirnimesh
2011/12/13 20:03:25
Thanks to Frank, this issue has been fixed.
(you c
wud
2011/12/13 20:54:08
Thanks, updated comments. I'll take you up on your
| |
| 59 result = self.RunInBackground('QTest.handleBrowserAction()') | |
| 60 self.assertEqual('ok', result, | |
| 61 msg='Call to QTest.handleBrowserAction failed.') | |
| 62 | |
| 63 # Wait for viewer window to open. | |
| 64 self.assertTrue(self.WaitUntil(self.GetViewerInfo), | |
| 65 msg='Timed out waiting for viewer.html to open') | |
| 66 | |
| 67 # Wait for viewer window to load the sign-in page. | |
| 68 self.WaitUntilCondition( | |
| 69 lambda: self.RunInViewer('window.location.href', | |
| 70 '//iframe[1]'), | |
| 71 lambda url: url and '/qsignin' in url, | |
| 72 msg='Timed out waiting for /qsignin page') | |
| 73 | |
| 74 def _SignIn(self): | |
| 75 """Download the extension, open the roster, and sign in""" | |
| 76 | |
| 77 # Open the roster. | |
| 78 self._OpenRoster() | |
| 79 | |
| 80 # Wait for /qsignin's BODY. | |
| 81 self.WaitUntilResult(True, | |
| 82 lambda: self.RunInViewer( | |
| 83 'Boolean($BODY())', '//iframe[1]'), | |
| 84 msg='Timed out waiting for document.body in /qsignin page.') | |
| 85 | |
| 86 # Wait for the "Sign In" link. | |
| 87 self.WaitUntilResult(True, | |
| 88 lambda: self.RunInViewer( | |
| 89 'Boolean($FindByText($BODY(), "Sign In"))', '//iframe[1]'), | |
| 90 msg='Timed out waiting for "Sign In" link in DOM.') | |
| 91 | |
| 92 # Click the "Sign In" link. | |
| 93 self.assertTrue(self.RunInViewer( | |
| 94 '$Click($FindByText($BODY(), "Sign In"))', '//iframe[1]')) | |
| 95 | |
| 96 # Wait for the login page to open. | |
| 97 self.assertTrue(self.WaitUntil(self.GetLoginPageInfo), | |
| 98 msg='Timed out waiting for login page to open') | |
| 99 | |
| 100 # Wait for the login page's form element. | |
| 101 self.WaitUntilResult(True, | |
| 102 lambda: self.RunInLoginPage('Boolean(document.forms[0])'), | |
| 103 msg='Timed out waiting for document.forms[0]') | |
| 104 | |
| 105 # Fill and submit the login form. | |
| 106 self.RunInLoginPage( | |
| 107 'document.forms[0].Email.value="quasar.test.1@gmail.com"') | |
| 108 self.RunInLoginPage('document.forms[0].Passwd.value="stablechat"') | |
| 109 self.RunInLoginPage('document.forms[0].submit() || true') | |
| 110 | |
| 111 def RunBasicFunctionalityTest(self): | |
| 112 """Run tests for basic functionality in GTalk.""" | |
| 113 | |
| 114 # Install the extension, open the viewer, and sign in. | |
| 115 self._SignIn() | |
| 116 | |
| 117 # Wait for the roster container iframe. | |
| 118 self.WaitUntilResult(True, | |
| 119 lambda: self.RunInViewer('Boolean(window.frames[0])'), | |
| 120 msg='Timed out waiting for roster container iframe') | |
| 121 | |
| 122 # Wait for the roster iframe. | |
| 123 self.WaitUntilResult(True, | |
| 124 lambda: self.RunInViewer('Boolean(window.frames[0])', '//iframe[1]'), | |
| 125 msg='Timed out waiting for roster iframe') | |
| 126 | |
| 127 # Wait for the roster iframe to load. | |
| 128 self.WaitUntilCondition( | |
| 129 lambda: self.RunInRoster('window.location.href'), | |
| 130 lambda url: url and '/notifierclient' in url, | |
| 131 msg='Timed out waiting for /notifierclient url') | |
| 132 | |
| 133 # Wait for "Search contacts..." to appear in the roster. | |
| 134 self.WaitUntilCondition( | |
| 135 lambda: self.RunInRoster('window.document.body.innerHTML'), | |
| 136 lambda html: html and 'Search contacts...' in html, | |
| 137 msg='Timed out waiting for search contacts text in roster DOM.') | |
| 138 | |
| 139 # Wait for "chatpinger@appspot.com" to appear in the roster. | |
| 140 self.WaitUntilResult(True, | |
| 141 lambda: self.RunInRoster( | |
| 142 'Boolean($FindByText($BODY(), "chatpinger@appspot.com"))'), | |
| 143 msg='Timed out waiting for chatpinger@appspot.com in roster DOM.') | |
| 144 | |
| 145 # TODO(wud): fix issue where mole doesn't open when clicked too quickly. | |
| 146 time.sleep(1) | |
| 147 | |
| 148 # Click "chatpinger@appspot.com" to open a chat mole. | |
| 149 self.RunInRoster('$Click($FindByText($BODY(), "chatpinger@appspot.com"))') | |
| 150 | |
| 151 # Wait for chat mole to open. | |
| 152 self.assertTrue(self.WaitUntil(self.GetMoleInfo), | |
| 153 msg='Timed out waiting for mole window to open') | |
| 154 | |
| 155 # Wait for chat mole to load. | |
| 156 self.WaitUntilResult(True, | |
| 157 lambda: self.RunInMole('Boolean(window.location.href)'), | |
| 158 msg='Timed out waiting for mole window location') | |
| 159 | |
| 160 # Wait for the chat mole's input textarea to load. | |
| 161 self.WaitUntilResult(True, | |
| 162 lambda: self.RunInMole( | |
| 163 'Boolean($FindByTagName($BODY(), "textarea", 0))'), | |
| 164 msg='Timed out waiting for mole textarea') | |
| 165 | |
| 166 # Type /ping in the mole's input widget. | |
| 167 self.assertTrue(self.RunInMole( | |
| 168 '$Type($FindByTagName($BODY(), "textarea", 0), "/ping")'), | |
| 169 msg='Error typing in mole textarea') | |
| 170 | |
| 171 # Type ENTER in the mole's input widget. | |
| 172 self.assertTrue(self.RunInMole( | |
| 173 '$Press($FindByTagName($BODY(),"textarea",0), $KEYS.ENTER)'), | |
| 174 msg='Error sending ENTER in mole textarea') | |
| 175 | |
| 176 # Wait for chat input to clear. | |
| 177 self.WaitUntilResult(True, | |
| 178 lambda: self.RunInMole( | |
| 179 'Boolean($FindByTagName($BODY(),"textarea",0).value=="")'), | |
| 180 msg='Timed out waiting for textarea to clear after ENTER') | |
| 181 | |
| 182 # Wait for /ping to appear in the chat history. | |
| 183 self.WaitUntilCondition( | |
| 184 lambda: self.RunInMole('window.document.body.innerHTML'), | |
| 185 lambda html: html and '/ping' in html, | |
| 186 msg='Timed out waiting for /ping to appear in mole DOM') | |
| 187 | |
| 188 # Wait for the echo "Ping!" to appear in the chat history. | |
| 189 self.WaitUntilCondition( | |
| 190 lambda: self.RunInMole('window.document.body.innerHTML'), | |
| 191 lambda html: html and 'Ping!' in html, | |
| 192 msg='Timed out waiting for "Ping!" reply to appear in mole DOM') | |
| 193 | |
| 194 # Request a ping in 7 seconds. | |
| 195 self.assertTrue(self.RunInMole( | |
| 196 '$Type($FindByTagName($BODY(),"textarea",0), "/ping 7")'), | |
| 197 msg='Error typing "ping /7" in mole textarea') | |
| 198 | |
| 199 # Press Enter in chat input. | |
| 200 self.assertTrue(self.RunInMole( | |
| 201 '$Press($FindByTagName($BODY(),"textarea",0), $KEYS.ENTER)'), | |
| 202 msg='Error sending ENTER after "ping /7" in mole textarea') | |
| 203 | |
| 204 # Briefly show mole for visual examination. | |
| 205 # Also works around issue where extension may show the first | |
| 206 # Ping! notification before closing the mole. | |
| 207 time.sleep(2) | |
| 208 | |
| 209 # Press escape to close the mole. | |
| 210 self.assertTrue(self.RunInMole( | |
| 211 '$Press($FindByTagName($BODY(),"textarea",0), $KEYS.ESC)'), | |
| 212 msg='Error sending ESC after "ping /7" in mole textarea') | |
| 213 | |
| 214 # Wait for the mole to close. | |
| 215 self.assertTrue(self.WaitUntil( | |
| 216 lambda: not(bool(self.GetMoleInfo()))), | |
| 217 msg='Timed out waiting for chatpinger mole to close') | |
| 218 | |
| 219 # Wait for a incoming chat toast to appear (requested above). | |
| 220 self.WaitUntilResult(True, | |
| 221 lambda: self.RunInBackground('Boolean($VIEW("/toast.html"))'), | |
| 222 msg='Timed out waiting for toast') | |
| 223 | |
| 224 # Wait for the toast body to exist. | |
| 225 self.WaitUntilResult(True, | |
| 226 lambda: self.RunInBackground('Boolean($BODY($VIEW("/toast.html")))'), | |
| 227 msg='Timed out waiting for toast body') | |
| 228 | |
| 229 # Wait for "Ping!" to appear in the toast. | |
| 230 self.WaitUntilResult(True, | |
| 231 lambda: self.RunInBackground( | |
| 232 'Boolean($FindByText($BODY($VIEW("/toast.html")), "Ping!"))'), | |
| 233 msg='Timed out waiting for "Ping!" in toast') | |
| 234 | |
| 235 # Click "Ping!" in the toast to open a mole. | |
| 236 self.assertTrue(self.RunInBackground( | |
| 237 '$Click($FindByText($BODY($VIEW("/toast.html")), "Ping!"))'), | |
| 238 msg='Error clicking "Ping!" in toast') | |
| 239 | |
| 240 # Wait for the mole to open. | |
| 241 self.assertTrue(self.WaitUntil(self.GetMoleInfo), | |
| 242 msg='Timed out waiting for mole window to open') | |
| 243 | |
| 244 # Ensure "chatpinger2@appspot.com" is in the roster. | |
| 245 self.WaitUntilResult(True, | |
| 246 lambda: self.RunInRoster( | |
| 247 'Boolean($FindByText($BODY(), "chatpinger2@appspot.com"))'), | |
| 248 msg='Timed out waiting for chatpinger2@appspot.com in roster DOM.') | |
| 249 | |
| 250 # Click "chatpinger2@appspot.com" in the roster. | |
| 251 self.RunInRoster('$Click($FindByText($BODY(), "chatpinger2@appspot.com"))') | |
| 252 | |
| 253 # Wait for a second chat mole to open. | |
| 254 self.assertTrue(self.WaitUntil(lambda: bool(self.GetMoleInfo(1))), | |
| 255 msg='Timed out waiting for second mole window to open') | |
| 256 | |
| 257 # Disable the extension. | |
| 258 extension = self.GetGTalkExtensionInfo() | |
| 259 self.SetExtensionStateById(extension['id'], enable=False, | |
| 260 allow_in_incognito=False) | |
| 261 extension = self.GetGTalkExtensionInfo() | |
| 262 self.assertFalse(extension['is_enabled']) | |
| 263 | |
| 264 # Verify all moles + windows are closed. | |
| 265 self.assertTrue(self.WaitUntil(lambda: not(bool(self.GetViewerInfo()))), | |
| 266 msg='Timed out waiting for viewer.html to close after disabling') | |
| 267 self.assertTrue(self.WaitUntil(lambda: not(bool(self.GetMoleInfo()))), | |
| 268 msg='Timed out waiting for first mole to close after disabling') | |
| 269 self.assertTrue(self.WaitUntil(lambda: not(bool(self.GetMoleInfo(1)))), | |
| 270 msg='Timed out waiting for second mole to close after disabling') | |
| 271 | |
| 272 def testBasicFunctionality(self): | |
| 273 """Run tests for basic functionality in GTalk with retries.""" | |
| 274 | |
| 275 # Since this test goes against prod servers, we'll retry to mitigate | |
| 276 # flakiness due to network issues. | |
| 277 tries = 0 | |
| 278 RETRIES = 5 | |
| 279 for tries in range(RETRIES): | |
| 280 logging.info('Calling RunBasicFunctionalityTest. Try #{0}/{1}' | |
|
Nirnimesh
2011/12/13 20:03:25
Why not use the more commonly used form for string
wud
2011/12/13 20:54:08
Thanks, done.
On 2011/12/13 20:03:25, Nirnimesh w
| |
| 281 .format(tries + 1, RETRIES)) | |
| 282 try: | |
| 283 self.RunBasicFunctionalityTest() | |
| 284 logging.info('RunBasicFunctionalityTest succeeded. Tries: {0}' | |
| 285 .format(tries + 1)) | |
| 286 break | |
| 287 except Exception as e: | |
| 288 logging.info("\n*** ERROR in RunBasicFunctionalityTest ***") | |
| 289 exc_type, exc_value, exc_traceback = sys.exc_info() | |
| 290 traceback.print_exception(exc_type, exc_value, exc_traceback) | |
| 291 logging.info("\n") | |
| 292 if tries < RETRIES - 1: | |
| 293 self.NavigateToURL('http://accounts.google.com/Logout') | |
| 294 logging.info('Retrying...') | |
| 295 else: | |
| 296 raise | |
| 297 | |
| 298 | |
| 299 if __name__ == '__main__': | |
| 300 pyauto_functional.Main() | |
| OLD | NEW |