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 """Base GTalk tests. |
| 7 |
| 8 This module contains a set of common utilities for querying |
| 9 and manipulating the Google Talk Chrome Extension. |
| 10 """ |
| 11 |
| 12 import logging |
| 13 import re |
| 14 import os |
| 15 |
| 16 import pyauto_gtalk |
| 17 import pyauto |
| 18 import pyauto_errors |
| 19 |
| 20 |
| 21 class GTalkBaseTest(pyauto.PyUITest): |
| 22 """Base test class for testing GTalk.""" |
| 23 |
| 24 _injected_js = None |
| 25 |
| 26 def ExtraChromeFlags(self): |
| 27 return pyauto.PyUITest.ExtraChromeFlags(self) + ['--no-sandbox'] |
| 28 |
| 29 def Prompt(self, text): |
| 30 """Pause execution with debug output. |
| 31 |
| 32 Args: |
| 33 text: The debug output. |
| 34 """ |
| 35 text = str(text) |
| 36 raw_input('--------------------> ' + text) |
| 37 |
| 38 def InstallGTalkExtension(self): |
| 39 """Download and install the GTalk extension.""" |
| 40 extension_path = os.path.abspath( |
| 41 os.path.join(self.DataDir(), 'extensions', 'gtalk', 'gtalk.crx')) |
| 42 self.assertTrue( |
| 43 os.path.exists(extension_path), |
| 44 msg='Failed to find GTalk extension: ' + extension_path) |
| 45 |
| 46 self.InstallExtension(extension_path, False) |
| 47 extension = self.GetGTalkExtensionInfo() |
| 48 self.assertTrue(extension, msg='Failed to install GTalk extension.') |
| 49 self.assertTrue(extension['is_enabled'], msg='GTalk extension is disabled.') |
| 50 |
| 51 def UninstallGTalkExtension(self): |
| 52 """Uninstall the GTalk extension (if present)""" |
| 53 extension = self.GetGTalkExtensionInfo() |
| 54 if extension: |
| 55 self.UninstallExtensionById(extension['id']) |
| 56 |
| 57 def GetGTalkExtensionInfo(self): |
| 58 """Get the data object about the GTalk extension.""" |
| 59 extensions = [x for x in self.GetExtensionsInfo() |
| 60 if x['name'] == 'Google Talk'] |
| 61 return extensions[0] if len(extensions) == 1 else None |
| 62 |
| 63 def RunInMole(self, js, mole_index=0): |
| 64 """Execute javascript in a chat mole. |
| 65 |
| 66 Args: |
| 67 js: The javascript to run. |
| 68 mole_index: The index of the mole in which to run the JS. |
| 69 |
| 70 Returns: |
| 71 The resulting value from executing the javascript. |
| 72 """ |
| 73 return self._RunInTab(self.GetMoleInfo(mole_index), js, '//iframe[1]') |
| 74 |
| 75 def RunInRoster(self, js): |
| 76 """Execute javascript in the chat roster. |
| 77 |
| 78 Args: |
| 79 js: The javascript to run. |
| 80 |
| 81 Returns: |
| 82 The resulting value from executing the javascript. |
| 83 """ |
| 84 return self._RunInTab(self.GetViewerInfo(), js, '//iframe[1]\n//iframe[1]') |
| 85 |
| 86 def RunInLoginPage(self, js, xpath=''): |
| 87 """Execute javascript in the gaia login popup. |
| 88 |
| 89 Args: |
| 90 js: The javascript to run. |
| 91 xpath: The xpath to the frame in which to execute the javascript. |
| 92 |
| 93 Returns: |
| 94 The resulting value from executing the javascript. |
| 95 """ |
| 96 return self._RunInTab(self.GetLoginPageInfo(), js, xpath) |
| 97 |
| 98 def RunInViewer(self, js, xpath=''): |
| 99 """Execute javascript in the GTalk viewer window. |
| 100 |
| 101 Args: |
| 102 js: The javascript to run. |
| 103 xpath: The xpath to the frame in which to execute the javascript. |
| 104 |
| 105 Returns: |
| 106 The resulting value from executing the javascript. |
| 107 """ |
| 108 return self._RunInTab(self.GetViewerInfo(), js, xpath) |
| 109 |
| 110 def RunInBackground(self, js, xpath=''): |
| 111 """Execute javascript in the GTalk viewer window. |
| 112 |
| 113 Args: |
| 114 js: The javascript to run. |
| 115 xpath: The xpath to the frame in which to execute the javascript. |
| 116 |
| 117 Returns: |
| 118 The resulting value from executing the javascript. |
| 119 """ |
| 120 background_view = self.GetBackgroundInfo() |
| 121 value = self.ExecuteJavascriptInRenderView( |
| 122 self._WrapJs(js), background_view['view']) |
| 123 self._LogRun(js, value) |
| 124 return value |
| 125 |
| 126 def GetMoleInfo(self, mole_index=0): |
| 127 """Get the data object about a given chat mole. |
| 128 |
| 129 Args: |
| 130 mole_index: The index of the mole to retrieve. |
| 131 |
| 132 Returns: |
| 133 Data object describing mole. |
| 134 """ |
| 135 extension = self.GetGTalkExtensionInfo() |
| 136 return self._GetTabInfo( |
| 137 'chrome-extension://%s/panel.html' % extension['id'], |
| 138 mole_index) |
| 139 |
| 140 def GetViewerInfo(self): |
| 141 """Get the data object about the GTalk viewer dialog.""" |
| 142 extension = self.GetGTalkExtensionInfo() |
| 143 return self._GetTabInfo( |
| 144 'chrome-extension://%s/viewer.html' % extension['id']) |
| 145 |
| 146 def GetLoginPageInfo(self): |
| 147 """Get the data object about the gaia login popup.""" |
| 148 return self._GetTabInfo('https://accounts.google.com/ServiceLogin?') |
| 149 |
| 150 def GetBackgroundInfo(self): |
| 151 """Get the data object about the GTalk background page.""" |
| 152 extension_views = self.GetBrowserInfo()['extension_views'] |
| 153 for extension_view in extension_views: |
| 154 if 'Google Talk' in extension_view['name'] and \ |
| 155 'EXTENSION_BACKGROUND_PAGE' == extension_view['view_type']: |
| 156 return extension_view |
| 157 return None |
| 158 |
| 159 def WaitUntilResult(self, result, func, msg): |
| 160 """Loop func until a condition matches is satified. |
| 161 |
| 162 Args: |
| 163 result: Value of func() at which to stop. |
| 164 func: Function to run at each iteration. |
| 165 msg: Error to print upon timing out. |
| 166 """ |
| 167 assert callable(func) |
| 168 self.assertTrue(self.WaitUntil( |
| 169 lambda: func(), expect_retval=result), msg=msg) |
| 170 |
| 171 def WaitUntilCondition(self, func, matches, msg): |
| 172 """Loop func until condition matches is satified. |
| 173 |
| 174 Args: |
| 175 func: Function to run at each iteration. |
| 176 matches: Funtion to evalute output and determine whether to stop. |
| 177 msg: Error to print upon timing out. |
| 178 """ |
| 179 assert callable(func) |
| 180 assert callable(matches) |
| 181 self.assertTrue(self.WaitUntil( |
| 182 lambda: matches(func())), msg=msg) |
| 183 |
| 184 def _WrapJs(self, statement): |
| 185 """Wrap the javascript to be executed. |
| 186 |
| 187 Args: |
| 188 statement: The piece of javascript to wrap. |
| 189 |
| 190 Returns: |
| 191 The wrapped javascript. |
| 192 """ |
| 193 return """ |
| 194 window.domAutomationController.send( |
| 195 (function(){ |
| 196 %s |
| 197 try{return %s} |
| 198 catch(e){return "JS_ERROR: " + e}})()) |
| 199 """ % (self._GetInjectedJs(), statement) |
| 200 |
| 201 def _RunInTab(self, tab, js, xpath=''): |
| 202 """Execute javascript in a given tab. |
| 203 |
| 204 Args: |
| 205 tab: The data object for the Chrome window tab returned by |
| 206 _GetTabInfo. |
| 207 js: The javascript to run. |
| 208 xpath: The xpath to the frame in which to execute the javascript. |
| 209 |
| 210 Returns: |
| 211 The resulting value from executing the javascript. |
| 212 """ |
| 213 if not tab: |
| 214 logging.debug('Tab not found: %s' % tab) |
| 215 return False |
| 216 logging.info('Run in tab: %s' % js) |
| 217 |
| 218 value = self.ExecuteJavascript( |
| 219 self._WrapJs(js), |
| 220 windex = tab['windex'], |
| 221 frame_xpath = xpath) |
| 222 self._LogRun(js, value) |
| 223 return value |
| 224 |
| 225 def _LogRun(self, js, value): |
| 226 """Log a particular run. |
| 227 |
| 228 Args: |
| 229 js: The javascript statement executed. |
| 230 value: The return value for the execution. |
| 231 """ |
| 232 # works around UnicodeEncodeError: 'ascii' codec can't encode... |
| 233 out = value |
| 234 if not isinstance(value, basestring): |
| 235 out = str(value) |
| 236 out = re.sub('\s', ';', out[:300]) |
| 237 logging.info(js + ' ===> ' + out.encode('utf-8')) |
| 238 |
| 239 def _GetTabInfo(self, url_query, index=0): |
| 240 """Get the data object for a given tab. |
| 241 |
| 242 Args: |
| 243 url_query: The substring of the URL to search for. |
| 244 index: The index within the list of matches to return. |
| 245 |
| 246 Returns: |
| 247 The data object for the tab. |
| 248 """ |
| 249 windows = self.GetBrowserInfo()['windows'] |
| 250 i = 0 |
| 251 for win in windows: |
| 252 for tab in win['tabs']: |
| 253 if tab['url'] and url_query in tab['url']: |
| 254 # Store reference to windex used in _RunInTab. |
| 255 tab['windex'] = win['index'] |
| 256 if i == index: |
| 257 return tab |
| 258 i = i + 1 |
| 259 return None |
| 260 |
| 261 def _GetInjectedJs(self): |
| 262 """Get the javascript to inject in the execution environment.""" |
| 263 if self._injected_js is None: |
| 264 self._injected_js = open( |
| 265 os.path.join(os.path.dirname(__file__), 'jsutils.js')).read() |
| 266 return self._injected_js |
OLD | NEW |