Chromium Code Reviews| Index: chrome/test/functional/gtalk/gtalk_base_test.py |
| =================================================================== |
| --- chrome/test/functional/gtalk/gtalk_base_test.py (revision 0) |
| +++ chrome/test/functional/gtalk/gtalk_base_test.py (revision 0) |
| @@ -0,0 +1,259 @@ |
| +#!/usr/bin/python |
| +# Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| +# Use of this source code is governed by a BSD-style license that can be |
| +# found in the LICENSE file. |
| + |
| +"""The base test class for GTalk tests. |
| + |
| +This module contains a set of common utilities used by unittest for querying |
| +and manipulating the Google Talk Chrome Extension (http//go/quasar) |
| +""" |
| + |
| +import logging |
| +import os |
| +import random |
|
Nirnimesh
2011/11/11 01:01:21
unused
wud
2011/11/17 21:17:53
Done.
|
| +import sys |
|
Nirnimesh
2011/11/11 01:01:21
unused
wud
2011/11/17 21:17:53
Done.
|
| +import tempfile |
|
Nirnimesh
2011/11/11 01:01:21
unused
wud
2011/11/17 21:17:53
Done.
|
| +import urllib2 |
|
Nirnimesh
2011/11/11 01:01:21
unused
wud
2011/11/17 21:17:53
Done.
|
| + |
| +import pyauto_gtalk # must preceed pyauto |
|
Nirnimesh
2011/11/11 01:01:21
leave another space before #
wud
2011/11/17 21:17:53
Done.
|
| +import pyauto |
| +import pyauto_errors |
| + |
| + |
| +class GTalkBaseTest(pyauto.PyUITest): |
| + """Base test class for testing GTalk.""" |
| + |
|
Nirnimesh
2011/11/11 01:01:21
you should define
_injected_js = None
here. And t
wud
2011/11/17 21:17:53
Ah, thanks!
|
| + def InstallGTalkExtension(self): |
| + """Download and install the GTalk extension.""" |
| + self.UninstallGTalkExtension() |
| + |
| + extension_path = os.path.abspath( |
| + os.path.join(self.DataDir(), 'extensions', 'quasar', 'quasar.crx')) |
|
Nirnimesh
2011/11/11 01:01:21
change dirname to gtalk?
wud
2011/11/17 21:17:53
Done.
|
| + self.assertTrue(os.path.exists(extension_path), |
| + 'Failed to find GTalk extension') |
|
Nirnimesh
2011/11/11 01:01:21
Use named params: msg='...'
Also, it would be nice
wud
2011/11/17 21:17:53
Done.
|
| + |
| + self.InstallExtension(extension_path, False) |
| + extension = self.GetGTalkExtensionInfo() |
| + self.assertTrue(extension, 'Failed to install GTalk extension') |
|
Nirnimesh
2011/11/11 01:01:21
msg='Failed to...'
(repeat everywhere else)
wud
2011/11/17 21:17:53
Done.
|
| + self.assertTrue(extension['is_enabled'], 'GTalk extension is disabled') |
| + |
| + def UninstallGTalkExtension(self): |
| + """Uninstall the GTalk extension (if exists)""" |
|
Nirnimesh
2011/11/11 01:01:21
exists -> present
wud
2011/11/17 21:17:53
Done.
|
| + extension = self.GetGTalkExtensionInfo() |
| + if extension: self.UninstallExtensionById(extension['id']) |
|
Nirnimesh
2011/11/11 01:01:21
move self.UninstallExtensionById(extension['id'])
wud
2011/11/17 21:17:53
Done.
|
| + |
| + def GetGTalkExtensionInfo(self): |
| + """Get the data object about the GTalk extension.""" |
| + extensions = [x for x in self.GetExtensionsInfo() |
| + if x['name'] == 'Google Talk'] |
| + return extensions[0] if len(extensions) == 1 else None |
| + |
| + def RunInMole(self, js, mole_index=0): |
| + """Execute javascript in a chat mole. |
| + |
| + Args: |
| + js: The javascript to run. |
| + mole_index: The index of the mole in which to run the JS. |
| + |
| + Returns: |
| + The resulting value from executing the javascript. |
| + """ |
| + return self._RunInTab(self.GetMoleInfo(mole_index), js) |
| + |
| + def RunInRoster(self, js): |
| + """Execute javascript in the chat roster. |
| + |
| + Args: |
| + js: The javascript to run. |
| + |
| + Returns: |
| + The resulting value from executing the javascript. |
| + """ |
| + return self._RunInTab(self.GetViewerInfo(), js, '//iframe[1]\n//iframe[1]') |
| + |
| + def RunInLoginPage(self, js, xpath=''): |
| + """Execute javascript in the gaia login popup. |
| + |
| + Args: |
| + js: The javascript to run. |
| + xpath: The xpath to the frame in which to execute the javascript. |
| + |
| + Returns: |
| + The resulting value from executing the javascript. |
| + """ |
| + return self._RunInTab(self.GetLoginPageInfo(), js, xpath) |
| + |
| + def RunInViewer(self, js, xpath=''): |
| + """Execute javascript in the GTalk viewer window. |
| + |
| + Args: |
| + js: The javascript to run. |
| + xpath: The xpath to the frame in which to execute the javascript. |
| + |
| + Returns: |
| + The resulting value from executing the javascript. |
| + """ |
| + return self._RunInTab(self.GetViewerInfo(), js, xpath) |
| + |
| + def RunInBackground(self, js, xpath=''): |
| + """Execute javascript in the GTalk viewer window. |
| + |
| + Args: |
| + js: The javascript to run. |
| + xpath: The xpath to the frame in which to execute the javascript. |
| + |
| + Returns: |
| + The resulting value from executing the javascript. |
| + """ |
| + background_view = self.GetBackgroundInfo() |
| + value = self.ExecuteJavascriptInRenderView( |
| + self._WrapJs(js), background_view['view']) |
| + self._LogRun(js, value) |
| + return value |
| + |
| + def GetMoleInfo(self, mole_index=0): |
| + """Get the data object about a given chat mole. |
| + |
| + Args: |
| + mole_index: The index of the mole to retrieve. |
| + |
| + Returns: |
| + Data object describing mole. |
| + """ |
| + return self._GetTabInfo('/pmole?', mole_index) |
| + |
| + def GetViewerInfo(self): |
| + """Get the data object about the GTalk viewer dialog.""" |
| + extension = self.GetGTalkExtensionInfo() |
| + return self._GetTabInfo( |
| + 'chrome-extension://' + extension['id'] + '/viewer.html') |
| + |
| + def GetLoginPageInfo(self): |
| + """Get the data object about the gaia login popup.""" |
| + return self._GetTabInfo('https://accounts.google.com/ServiceLogin?') |
| + |
| + def GetBackgroundInfo(self): |
| + """Get the data object about the GTalk background page.""" |
| + extension_views = self.GetBrowserInfo()['extension_views'] |
| + for extension_view in extension_views: |
| + if 'Google Talk' in extension_view['name'] and \ |
| + 'EXTENSION_BACKGROUND_PAGE' == extension_view['view_type']: |
| + return extension_view |
| + return None; |
| + |
| + def WaitUntilResult(self, result, func, msg): |
| + """Loop func until a condition matches is satified. |
| + |
| + Args: |
| + result: Value of func() at which to stop. |
| + func: Function to run at each iteration. |
| + msg: Error to print upon timing out. |
| + """ |
| + self.assertTrue(self.WaitUntil( |
|
Nirnimesh
2011/11/11 01:01:21
This is better written as:
self.assertTrue(self.Wa
wud
2011/11/17 21:17:53
Thanks.
|
| + lambda: result == func()), msg) |
| + |
| + def WaitUntilCondition(self, func, matches, msg): |
| + """Loop func until condition matches is satified. |
| + |
| + Args: |
| + func: Function to run at each iteration. |
| + matches: Funtion to evalute output and determine whether to stop. |
| + msg: Error to print upon timing out. |
| + """ |
|
Nirnimesh
2011/11/11 01:01:21
assert callable(matches)
wud
2011/11/17 21:17:53
Done. Also added for func.
|
| + self.assertTrue(self.WaitUntil( |
| + lambda: matches(func())), msg) |
| + |
| + def _WrapJs(self, statement): |
| + """Wrap the javascript to be executed. |
| + |
| + Args: |
| + statement: The piece of javascript to wrap. |
| + |
| + Returns: |
| + The wrapped javascript. |
| + """ |
| + return 'window.domAutomationController.send(' + \ |
|
Nirnimesh
2011/11/11 01:01:21
this will look cleaner as a heredoc.
return """
wud
2011/11/17 21:17:53
Thanks. Didn't know about heredoc.
|
| + '(function(){' + self._GetInjectedJs() + \ |
| + 'try{return ' + statement + '}' + \ |
| + 'catch(e){return "JS_ERROR: " + e}})())' |
| + |
| + def _RunInTab(self, tab, js, xpath=''): |
| + """Execute javascript in a given tab. |
| + |
| + Args: |
| + tab: The data object for the tab. |
|
frankf
2011/11/11 01:35:03
more descriptive variable name.
wud
2011/11/17 21:17:53
Updated description. The variable name "tab", refe
|
| + js: The javascript to run. |
| + xpath: The xpath to the frame in which to execute the javascript. |
| + |
| + Returns: |
| + The resulting value from executing the javascript. |
| + """ |
| + if not tab: |
| + logging.debug("Tab not found: %s" % tab) |
|
frankf
2011/11/11 01:35:03
Be consistent with quotes (All ' or all ")
wud
2011/11/17 21:17:53
Done.
|
| + return False |
| + logging.info("Run in tab: " + js) |
| + |
| + # Catch any JSONInterfaceError thrown while running. |
| + try: |
| + value = self.ExecuteJavascriptInTab(self._WrapJs(js), |
| + windex = tab['windex'], |
| + frame_xpath = xpath) |
| + except pyauto_error.JSONInterfaceError as e: |
|
Nirnimesh
2011/11/11 01:01:21
It's not a good idea to catch this. This represent
wud
2011/11/17 21:17:53
In some cases (e.g., I believe when an expected el
Nirnimesh
2011/11/30 23:57:36
Such an issue is actually a symptom of js error. Y
|
| + logging.debug("Error running JS: %s" % js) |
| + value = False |
| + self._LogRun(js, value) |
| + return value |
| + |
| + def _LogRun(self, js, value): |
| + """Log a particular run. |
| + |
| + Args: |
| + js: The javascript statement executed. |
| + value: The return value for the execution. |
| + """ |
| + out = value |
| + if not isinstance(value, basestring): |
|
Nirnimesh
2011/11/11 01:01:21
not necessary. out = str(value) will work regardle
wud
2011/11/17 21:17:53
Done.
|
| + out = str(value) |
| + out = out[:300] |
|
Nirnimesh
2011/11/11 01:01:21
218-220 can be:
re.sub('\s', '', out[:300])
Also,
wud
2011/11/17 21:17:53
Done.
|
| + out = out.replace("\n", '') |
| + out = out.replace("\r", '') |
| + logging.info(js + ' ===> ' + out.encode('utf-8')) |
| + |
| + def _GetTabInfo(self, url_query, index=0): |
| + """Get the data object for a given tab. |
| + |
| + Args: |
| + url_query: The substring of the URL to search for. |
| + index: The index within the list of matches to return. |
| + |
| + Returns: |
| + The data object for the tab. |
| + """ |
| + windows = self.GetBrowserInfo()['windows'] |
| + i = 0 |
| + for win in windows: |
| + for tab in win['tabs']: |
| + if tab['url'] and url_query in tab['url']: |
| + tab['windex'] = win['index'] |
|
Nirnimesh
2011/11/11 01:01:21
what is this for?
wud
2011/11/17 21:17:53
A reference to the windex used in _RunInTab.
|
| + if i == index: |
| + return tab |
| + i = i + 1 |
| + return None |
| + |
| + def _GetInjectedJs(self): |
| + """Get the javascript to inject in the execution environment.""" |
| + if self._injected_js == None: |
|
Nirnimesh
2011/11/11 01:01:21
s/==/is/
wud
2011/11/17 21:17:53
Done.
|
| + jsfile = open(os.path.dirname(__file__) + '/jsutils.js') |
|
Nirnimesh
2011/11/11 01:01:21
247-250 can be written as:
self._injected_js = op
wud
2011/11/17 21:17:53
Thanks, done.
|
| + js = jsfile.read() |
| + jsfile.close() |
| + self._injected_js = js |
| + return self._injected_js |
| + |
| + def action_max_timeout_ms(self): |
|
Nirnimesh
2011/11/11 01:01:21
what is this for?
wud
2011/11/17 21:17:53
This is the default timeout used by WaitUntil. Set
Nirnimesh
2011/11/30 23:57:36
I don't think you should override this. This contr
|
| + """Get the default timeout for each WaitUntil command.""" |
| + return 30000; |
| + |
| + def __init__(self, methodName='runTest'): |
| + pyauto.PyUITest.__init__(self, methodName) |
| + self._injected_js = None |