Chromium Code Reviews| Index: chrome/test/functional/quasar/quasar_base_test.py |
| =================================================================== |
| --- chrome/test/functional/quasar/quasar_base_test.py (revision 0) |
| +++ chrome/test/functional/quasar/quasar_base_test.py (revision 0) |
| @@ -0,0 +1,184 @@ |
| +#!/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. |
| + |
| +""" |
| +This module has the base test class for Quasar tests, contain a set of |
| +common utilities used by unittest for querying and manipulating Quasar-- |
| +the Google Talk Chrome Extension (http//go/quasar) |
| +""" |
| + |
| +import os |
| +import random |
| +import sys |
| +import tempfile |
| +import urllib2 |
| + |
| +import pyauto_quasar |
| +import pyauto |
| + |
|
Nirnimesh
2011/11/09 23:54:05
need 2 blank lines at global scope
wud
2011/11/10 23:35:19
Done, here and elsewhere.
|
| +class BaseTest(pyauto.PyUITest): |
|
Nirnimesh
2011/11/09 23:54:05
BaseTest is too generic. Rename to QuasarBaseTest
wud
2011/11/10 23:35:19
Done.
|
| + """Base test class for testing Quasar.""" |
| + |
| + def DownloadAndInstall(self): |
| + """Download and install the Quasar extension.""" |
| + self.Uninstall() |
| + |
| + url = 'http://www.corp.google.com/~wud/pyauto/quasar.crx' |
|
Nirnimesh
2011/11/09 23:54:05
It might be better to checkin the extension somewh
wud
2011/11/10 23:35:19
Good idea! Done.
|
| + tempdir = tempfile.mkdtemp() |
| + localfile = os.path.join(tempdir, 'quasar.crx') |
| + self._DownloadFile(url, localfile) |
| + self.assertTrue(os.path.exists(localfile), |
| + 'Failed to download Quasar extension') |
|
frankf
2011/12/05 20:34:57
nit: period at end of msg, also in other places.
|
| + |
| + self.InstallExtension(os.path.abspath(localfile), False) |
| + extension = self.GetExtensionInfo() |
| + self.assertTrue(extension, 'Failed to install Quasar extension') |
|
frankf
2011/12/05 20:34:57
You no longer need to explicitly test for this as
|
| + self.assertTrue(extension['is_enabled'], 'Quasar extension is disabled') |
| + |
| + def Uninstall(self): |
|
Nirnimesh
2011/11/09 23:54:05
I recommend renaming to make it explicit what is g
wud
2011/11/10 23:35:19
Done. Ended up renaming everything to "GTalk" inst
wud
2011/11/10 23:35:19
Done.
|
| + """Uninstall the Quasar extension (if exists)""" |
| + extension = self.GetExtensionInfo() |
| + if extension: |
|
Nirnimesh
2011/11/09 23:54:05
merge with previous line
wud
2011/11/10 23:35:19
Done.
|
| + self.UninstallExtensionById(extension['id']) |
| + |
| + def GetExtensionInfo(self): |
|
Nirnimesh
2011/11/09 23:54:05
This sounds very close to the pyauto call GetExten
wud
2011/11/10 23:35:19
Done.
|
| + """Get the data object about the Quasar extension.""" |
| + info = None |
|
Nirnimesh
2011/11/09 23:54:05
48-54 can be written as:
extensions = [x for x in
wud
2011/11/10 23:35:19
Thanks, much cleaner!
|
| + for ext in self.GetExtensionsInfo(): |
| + if ext['name'] == 'Google Talk': |
| + self.assertTrue(info == None, |
|
Nirnimesh
2011/11/09 23:54:05
are you sure you want to assert in this getter?
I
wud
2011/11/10 23:35:19
Just want to ensure at most one Talk extension is
|
| + 'More than 1 Google Talk Extension installed') |
| + info = ext |
| + return info; |
|
Nirnimesh
2011/11/09 23:54:05
remove ;
wud
2011/11/10 23:35:19
Done.
|
| + |
| + def RunInMole(self, js, mole_index = 0): |
|
Nirnimesh
2011/11/09 23:54:05
remove space around =
(Repeat elsewhere)
wud
2011/11/10 23:35:19
Done. Here and elsewhere.
|
| + """Execute javascript in a chat mole.""" |
|
Nirnimesh
2011/11/09 23:54:05
Explain args
wud
2011/11/10 23:35:19
Done. Here and elsewhere.
|
| + return self._RunInTab(self.GetMoleInfo(mole_index), js) |
| + |
| + def RunInRoster(self, js): |
| + """Execute javascript in the chat roster.""" |
| + return self._RunInTab(self.GetViewerInfo(), js, '//iframe[1]\n//iframe[1]') |
| + |
| + def RunInLoginPage(self, js, xpath = ''): |
| + """Execute javascript in the gaia login popup.""" |
| + return self._RunInTab(self.GetLoginPageInfo(), js, xpath) |
| + |
| + def RunInViewer(self, js, xpath = ''): |
| + """Execute javascript in the Quasar viewer window.""" |
| + return self._RunInTab(self.GetViewerInfo(), js, xpath) |
| + |
| + def RunInBackground(self, js, xpath = '', expected = None): |
| + """Execute javascript in the Quasar background window.""" |
| + 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.""" |
| + return self._GetTabInfo('/pmole?', mole_index) |
| + |
| + def GetViewerInfo(self): |
| + """Get the data object about the Quasar viewer dialog.""" |
| + extension = self.GetExtensionInfo() |
| + 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 Quasar 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, error): |
| + """Loop func until a condition matches is satified""" |
| + return self.assertTrue(self.WaitUntil( |
| + lambda: result == func()), error) |
| + |
| + def WaitUntilCondition(self, func, matches, error): |
| + """Loop func until a condition matches is satified""" |
| + return self.assertTrue(self.WaitUntil( |
|
Nirnimesh
2011/11/09 23:54:05
assertTrue does not return
You want to return the
wud
2011/11/10 23:35:19
Removed return value. It felt cleaner to me to use
|
| + lambda: matches(func())), error) |
| + |
| + def _WrapJs(self, statement): |
| + """Wrap the javascript to be executed.""" |
| + return 'window.domAutomationController.send(' + \ |
| + '(function(){' + self._GetInjectedJs() + \ |
| + 'try{return ' + statement + '}' + \ |
| + 'catch(e){return "JS_ERROR: " + e}})())' |
| + |
| + def _RunInTab(self, tab, js, xpath = ''): |
| + """Execute javascript in a given tab.""" |
| + if not tab: |
| + print "Tab not found: %s" % tab |
|
Nirnimesh
2011/11/09 23:54:05
use logging.info / logging.debug instead of print
wud
2011/11/10 23:35:19
Done.
|
| + return False |
| + print "Run in tab: " + js |
| + try: |
|
Nirnimesh
2011/11/09 23:54:05
WHy?
wud
2011/11/10 23:35:19
Sometimes, the test would throw a JSONInterfaceErr
|
| + value = self.ExecuteJavascriptInTab(self._WrapJs(js), |
| + windex = tab['windex'], |
| + frame_xpath = xpath) |
| + except Exception as e: |
| + print "Error running JS: %s" % js |
| + value = False |
| + self._LogRun(js, value) |
| + return value |
| + |
| + def _LogRun(self, js, value): |
| + """Log a particular run.""" |
| + out = value |
| + if not isinstance(value, basestring): |
|
frankf
2011/12/05 20:34:57
don't need the if statement.
|
| + out = str(value) |
| + out = out[:300] |
| + out = out.replace("\n", "") |
| + out = out.replace("\r", "") |
| + print js + " ===> " + out.encode("utf-8") |
|
Nirnimesh
2011/11/09 23:54:05
prefer ' over "
(Repeat elsewhere)
wud
2011/11/10 23:35:19
Done.
|
| + |
| + def _GetTabInfo(self, url_query, index = 0): |
|
Nirnimesh
2011/11/09 23:54:05
rename |index| to |windex| (window index)
wud
2011/11/10 23:35:19
actually, i don't think "index" corresponds to the
|
| + """Get the data object for a given tab.""" |
| + windows = self.GetBrowserInfo()['windows'] |
| + i = 0 |
| + for win in windows: |
|
Nirnimesh
2011/11/09 23:54:05
you can directly get all tabs for the given window
wud
2011/11/10 23:35:19
Done.
|
| + for tab in win['tabs']: |
| + if tab['url'] and url_query in tab['url']: |
| + tab['windex'] = win['index'] |
| + if (i == index): |
|
Nirnimesh
2011/11/09 23:54:05
remove parens
wud
2011/11/10 23:35:19
Done.
|
| + return tab |
| + i = i + 1 |
| + return None; |
|
Nirnimesh
2011/11/09 23:54:05
remove ;
wud
2011/11/10 23:35:19
Done.
|
| + |
| + def _DownloadFile(self, url, filename): |
|
Nirnimesh
2011/11/09 23:54:05
this is the same as urllib.urlretrieve
wud
2011/11/10 23:35:19
removed.
|
| + """Download a file.""" |
|
Nirnimesh
2011/11/09 23:54:05
Explain args
(Repeat elsewhere for all non-trivial
wud
2011/11/10 23:35:19
Done.
|
| + # NOTE(wud): Using the pyauto download file API currently produces a |
|
Nirnimesh
2011/11/09 23:54:05
NOTE(wud) -> Note
wud
2011/11/10 23:35:19
removed.
|
| + # "install extension" prompt without a hook I can find to click it, so |
| + # we download the extension file using urllib2 instead. |
| + u = urllib2.urlopen(url) |
| + localFile = open(filename, 'w') |
| + localFile.write(u.read()) |
| + localFile.close() |
| + return True |
| + |
| + def _GetInjectedJs(self): |
| + """Get the javascript to inject in the execution environment.""" |
| + if self.injectedJs_ == None: |
| + jsfile = open(os.path.dirname(__file__) + '/jsutils.js', 'r') |
|
Nirnimesh
2011/11/09 23:54:05
the 2nd arg is redundant
wud
2011/11/10 23:35:19
Done.
|
| + js = jsfile.read() |
| + jsfile.close() |
| + self.injectedJs_ = js |
| + return self.injectedJs_ |
| + |
| + def action_max_timeout_ms(self): |
| + return 30000; |
| + |
| + def __init__(self, methodName='runTest'): |
| + pyauto.PyUITest.__init__(self, methodName) |
| + self.injectedJs_ = None |
|
Nirnimesh
2011/11/09 23:54:05
use varnames_with_underscores
Prefix _
wud
2011/11/10 23:35:19
Done.
|