| OLD | NEW |
| (Empty) |
| 1 #!/usr/bin/env python | |
| 2 # Copyright (c) 2012 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. | |
| 7 | |
| 8 This module contains the basic set of sanity tests run on the | |
| 9 GTalk extension. | |
| 10 """ | |
| 11 | |
| 12 import logging | |
| 13 import sys | |
| 14 import time | |
| 15 import traceback | |
| 16 import urllib2 | |
| 17 import os | |
| 18 | |
| 19 import gtalk_base_test | |
| 20 import pyauto_gtalk # must preceed pyauto | |
| 21 import pyauto | |
| 22 | |
| 23 | |
| 24 class BasicTest(gtalk_base_test.GTalkBaseTest): | |
| 25 """Test for Google Talk Chrome Extension.""" | |
| 26 | |
| 27 def _OpenRoster(self, gtalk_version): | |
| 28 """Download Talk extension and open the roster.""" | |
| 29 | |
| 30 self.InstallGTalkExtension(gtalk_version) | |
| 31 | |
| 32 # Wait for the background view to load. | |
| 33 extension = self.GetGTalkExtensionInfo() | |
| 34 background_view = self.WaitUntilExtensionViewLoaded( | |
| 35 extension_id=extension['id'], | |
| 36 view_type='EXTENSION_BACKGROUND_PAGE') | |
| 37 self.assertTrue(background_view, | |
| 38 msg='Failed to get background view: views = %s.' % | |
| 39 self.GetBrowserInfo()['extension_views']) | |
| 40 | |
| 41 # Click browser action icon | |
| 42 self.TriggerBrowserActionById(extension['id']) | |
| 43 | |
| 44 # Wait for viewer window to open. | |
| 45 self.assertTrue( | |
| 46 self.WaitUntil(self.GetViewerInfo), | |
| 47 msg='Timed out waiting for viewer.html to open.') | |
| 48 | |
| 49 # Wait for the sign-in iframe to load. | |
| 50 self.WaitUntilCondition( | |
| 51 lambda: self.RunInViewer( | |
| 52 'window.document.getElementsByTagName("iframe") != null && ' | |
| 53 'window.document.getElementsByTagName("iframe").length > 0') and | |
| 54 self.RunInViewer('window.location.href', | |
| 55 '//iframe[1]'), | |
| 56 lambda url: url and '/qsignin' in url, | |
| 57 msg='Timed out waiting for /qsignin page.') | |
| 58 | |
| 59 | |
| 60 def _SignIn(self, gtalk_version): | |
| 61 """Download the extension, open the roster, and sign in""" | |
| 62 # Open the roster. | |
| 63 self._OpenRoster(gtalk_version) | |
| 64 | |
| 65 # Wait for /qsignin's BODY. | |
| 66 self.WaitUntilResult(True, | |
| 67 lambda: self.RunInViewer( | |
| 68 'Boolean($BODY())', '//iframe[1]'), | |
| 69 msg='Timed out waiting for document.body in /qsignin page.') | |
| 70 | |
| 71 # Wait for the "Sign In" link. | |
| 72 self.WaitUntilResult(True, | |
| 73 lambda: self.RunInViewer( | |
| 74 'Boolean($FindByText($BODY(), "Sign In"))', '//iframe[1]'), | |
| 75 msg='Timed out waiting for "Sign In" link in DOM.') | |
| 76 | |
| 77 # Click the "Sign In" link. | |
| 78 self.assertTrue(self.RunInViewer( | |
| 79 '$Click($FindByText($BODY(), "Sign In"))', '//iframe[1]')) | |
| 80 | |
| 81 # Wait for the login page to open. | |
| 82 self.assertTrue(self.WaitUntil(self.GetLoginPageInfo), | |
| 83 msg='Timed out waiting for login page to open.') | |
| 84 | |
| 85 # Wait for the login page's form element. | |
| 86 self.WaitUntilResult(True, | |
| 87 lambda: self.RunInLoginPage('Boolean(document.forms[0])'), | |
| 88 msg='Timed out waiting for document.forms[0].') | |
| 89 | |
| 90 # Fill and submit the login form. | |
| 91 credentials = self.GetPrivateInfo()['test_google_account'] | |
| 92 | |
| 93 self.RunInLoginPage( | |
| 94 'document.forms[0].Email.value="' + credentials['username'] + '"') | |
| 95 self.RunInLoginPage( | |
| 96 'document.forms[0].Passwd.value="' + credentials['password'] + '"') | |
| 97 self.RunInLoginPage('document.forms[0].submit() || true') | |
| 98 | |
| 99 def RunBasicFunctionalityTest(self, gtalk_version): | |
| 100 """Run tests for basic functionality in GTalk.""" | |
| 101 | |
| 102 # Install the extension, open the viewer, and sign in. | |
| 103 self._SignIn(gtalk_version) | |
| 104 | |
| 105 # Wait for the roster container iframe. | |
| 106 self.WaitUntilResult(True, | |
| 107 lambda: self.RunInViewer( | |
| 108 'window.document.getElementById("popoutRoster") != null'), | |
| 109 msg='Timed out waiting for roster container iframe.') | |
| 110 | |
| 111 self.WaitUntilResult(True, | |
| 112 lambda: self.RunInViewer('Boolean(window.frames[0])', '//iframe[1]'), | |
| 113 msg='Timed out waiting for roster iframe.') | |
| 114 | |
| 115 # Wait for the roster iframe to load. | |
| 116 self.WaitUntilCondition( | |
| 117 lambda: self.RunInRoster('window.location.href'), | |
| 118 lambda url: url and '/frame' in url, | |
| 119 msg='Timed out waiting for /frame in url.') | |
| 120 | |
| 121 self.WaitUntilResult(True, | |
| 122 lambda: self.RunInRoster( | |
| 123 'Boolean($FindByText($BODY(), "Send a message to..."))'), | |
| 124 msg='Timed out waiting for "Send a message to..." label in roster DOM.') | |
| 125 | |
| 126 # Wait for "chatpinger@appspot.com" to appear in the roster. | |
| 127 self.WaitUntilResult(True, | |
| 128 lambda: self.RunInRoster( | |
| 129 'Boolean($FindByText($BODY(), "chatpinger@appspot.com"))'), | |
| 130 msg='Timed out waiting for chatpinger@appspot.com in roster DOM.') | |
| 131 | |
| 132 # Works around for issue where mole doesn't open when clicked too quickly. | |
| 133 time.sleep(1) | |
| 134 | |
| 135 # Click "chatpinger@appspot.com" to open a chat mole. | |
| 136 self.RunInRoster('$Click($FindByText($BODY(), "chatpinger@appspot.com"))') | |
| 137 | |
| 138 # Wait until ready to check whether mole is open(temporary work around). | |
| 139 time.sleep(1) | |
| 140 | |
| 141 # Wait for chat mole to open. | |
| 142 self.assertTrue(self.WaitUntil(self.GetMoleInfo), | |
| 143 msg='Timed out waiting for mole window to open.') | |
| 144 | |
| 145 self.WaitUntilResult(True, | |
| 146 lambda: self.RunInViewer( | |
| 147 'window.document.getElementsByTagName("iframe") != null'), | |
| 148 msg='Timed out waiting for iframes to load.') | |
| 149 | |
| 150 # Wait for chat mole to load. | |
| 151 self.WaitUntilResult(True, | |
| 152 lambda: self.RunInMole('Boolean(window.location.href)'), | |
| 153 msg='Timed out waiting for mole window location.') | |
| 154 | |
| 155 # Wait for the chat mole's input textarea to load. | |
| 156 self.WaitUntilResult(True, | |
| 157 lambda: self.RunInMole( | |
| 158 'Boolean($FindByTagName($BODY(), "textarea", 0))'), | |
| 159 msg='Timed out waiting for mole textarea.') | |
| 160 | |
| 161 # Type /ping in the mole's input widget. | |
| 162 self.assertTrue(self.RunInMole( | |
| 163 '$Type($FindByTagName($BODY(), "textarea", 0), "/ping")'), | |
| 164 msg='Error typing in mole textarea.') | |
| 165 | |
| 166 # Type ENTER in the mole's input widget. | |
| 167 self.assertTrue(self.RunInMole( | |
| 168 '$Press($FindByTagName($BODY(),"textarea",0), $KEYS.ENTER)'), | |
| 169 msg='Error sending ENTER in mole textarea.') | |
| 170 | |
| 171 # Wait for chat input to clear. | |
| 172 self.WaitUntilResult(True, | |
| 173 lambda: self.RunInMole( | |
| 174 'Boolean($FindByTagName($BODY(),"textarea",0).value=="")'), | |
| 175 msg='Timed out waiting for textarea to clear after ENTER.') | |
| 176 | |
| 177 # Wait for /ping to appear in the chat history. | |
| 178 self.WaitUntilCondition( | |
| 179 lambda: self.RunInMole('window.document.body.innerHTML'), | |
| 180 lambda html: html and '/ping' in html, | |
| 181 msg='Timed out waiting for /ping to appear in mole DOM.') | |
| 182 | |
| 183 # Wait for the echo "Ping!" to appear in the chat history. | |
| 184 self.WaitUntilCondition( | |
| 185 lambda: self.RunInMole('window.document.body.innerHTML'), | |
| 186 lambda html: html and 'Ping!' in html, | |
| 187 msg='Timed out waiting for "Ping!" reply to appear in mole DOM.') | |
| 188 | |
| 189 # Request a ping in 7 seconds. | |
| 190 self.assertTrue(self.RunInMole( | |
| 191 '$Type($FindByTagName($BODY(),"textarea",0), "/ping 7")'), | |
| 192 msg='Error typing "ping /7" in mole textarea.') | |
| 193 | |
| 194 # Press Enter in chat input. | |
| 195 self.assertTrue(self.RunInMole( | |
| 196 '$Press($FindByTagName($BODY(),"textarea",0), $KEYS.ENTER)'), | |
| 197 msg='Error sending ENTER after "ping /7" in mole textarea.') | |
| 198 | |
| 199 # Briefly show mole for visual examination. | |
| 200 # Also works around issue where extension may show the first | |
| 201 # Ping! notification before closing the mole. | |
| 202 time.sleep(2) | |
| 203 | |
| 204 # Press escape to close the mole. | |
| 205 self.assertTrue(self.RunInMole( | |
| 206 '$Press($FindByTagName($BODY(),"textarea",0), $KEYS.ESC)'), | |
| 207 msg='Error sending ESC after "ping /7" in mole textarea.') | |
| 208 | |
| 209 # Wait for the mole to close. | |
| 210 self.assertTrue(self.WaitUntil( | |
| 211 lambda: not(bool(self.GetMoleInfo()))), | |
| 212 msg='Timed out waiting for chatpinger mole to close.') | |
| 213 | |
| 214 # Ensure "chatpinger2@appspot.com" is in the roster. | |
| 215 self.WaitUntilResult(True, | |
| 216 lambda: self.RunInRoster( | |
| 217 'Boolean($FindByText($BODY(), "chatpinger2@appspot.com"))'), | |
| 218 msg='Timed out waiting for chatpinger2@appspot.com in roster DOM.') | |
| 219 | |
| 220 # Click "chatpinger2@appspot.com" in the roster. | |
| 221 self.RunInRoster('$Click($FindByText($BODY(), "chatpinger2@appspot.com"))') | |
| 222 | |
| 223 self.WaitUntilResult(True, | |
| 224 lambda: self.RunInViewer( | |
| 225 'window.document.getElementsByTagName("iframe") != null'), | |
| 226 msg='Timed out waiting for iframes to load.') | |
| 227 | |
| 228 # Wait for a second chat mole to open. | |
| 229 time.sleep(1) | |
| 230 self.assertTrue(self.WaitUntil(lambda: bool(self.GetMoleInfo(1))), | |
| 231 msg='Timed out waiting for second mole window to open.') | |
| 232 | |
| 233 # Wait for mole content to load | |
| 234 self.WaitUntilCondition( | |
| 235 lambda: self.RunInMole('window.document.body.innerHTML', 1), | |
| 236 lambda html: html and 'Ping!' in html, | |
| 237 msg='Timed out waiting for Ping! to appear in mole DOM.') | |
| 238 | |
| 239 # Disable the extension. | |
| 240 extension = self.GetGTalkExtensionInfo() | |
| 241 self.SetExtensionStateById(extension['id'], enable=False, | |
| 242 allow_in_incognito=False) | |
| 243 extension = self.GetGTalkExtensionInfo() | |
| 244 self.assertFalse(extension['is_enabled']) | |
| 245 | |
| 246 # Verify all moles + windows are closed. | |
| 247 self.assertTrue(self.WaitUntil(lambda: not(bool(self.GetViewerInfo()))), | |
| 248 msg='Timed out waiting for viewer.html to close after disabling.') | |
| 249 self.assertTrue(self.WaitUntil(lambda: not(bool(self.GetMoleInfo()))), | |
| 250 msg='Timed out waiting for first mole to close after disabling.') | |
| 251 self.assertTrue(self.WaitUntil(lambda: not(bool(self.GetMoleInfo(1)))), | |
| 252 msg='Timed out waiting for second mole to close after disabling.') | |
| 253 | |
| 254 def _GetCurrentGtalkVersion(self): | |
| 255 """Read current gtalk extension version from file.""" | |
| 256 return self._GetGtalkVersion('current_version') | |
| 257 | |
| 258 def _GetRCGtalkVersion(self): | |
| 259 """Read RC gtalk extension version from file""" | |
| 260 return self._GetGtalkVersion('rc_version') | |
| 261 | |
| 262 def _GetGtalkVersion(self, version_type): | |
| 263 """Read gtalk version from file""" | |
| 264 version_path = os.path.abspath( | |
| 265 os.path.join(self.DataDir(), 'extensions', | |
| 266 'gtalk', version_type)) | |
| 267 self.assertTrue( | |
| 268 os.path.exists(version_path), | |
| 269 msg='Failed to find version ' + version_path) | |
| 270 with open(version_path) as version_file: | |
| 271 return version_file.read() | |
| 272 | |
| 273 def _TestBasicFunctionality(self, version): | |
| 274 """Run tests for basic functionality in GTalk with retries.""" | |
| 275 | |
| 276 # Since this test goes against prod servers, we'll retry to mitigate | |
| 277 # flakiness due to network issues. | |
| 278 RETRIES = 5 | |
| 279 for tries in range(RETRIES): | |
| 280 logging.info('Calling RunBasicFunctionalityTest on %s. Try #%s/%s' | |
| 281 % (version, tries + 1, RETRIES)) | |
| 282 try: | |
| 283 self.RunBasicFunctionalityTest(version) | |
| 284 logging.info('RunBasicFunctionalityTest on %s succeeded. Tries: %s' | |
| 285 % (version, 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('Closing all moles.') | |
| 295 self.RunInAllMoles( | |
| 296 '$Press($FindByTagName($BODY(),"textarea",0), $KEYS.ESC)') | |
| 297 logging.info('Retrying...') | |
| 298 else: | |
| 299 raise | |
| 300 | |
| 301 def testCurrentVersion(self): | |
| 302 """Run basic functionality test on current version of gtalk extension""" | |
| 303 version = self._GetCurrentGtalkVersion() | |
| 304 self._TestBasicFunctionality(version) | |
| 305 | |
| 306 def testRCVersion(self): | |
| 307 """Run basic functionality test on RC version of gtalk extension""" | |
| 308 version = self._GetRCGtalkVersion() | |
| 309 self._TestBasicFunctionality(version) | |
| 310 | |
| 311 if __name__ == '__main__': | |
| 312 pyauto_gtalk.Main() | |
| OLD | NEW |