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 """ | |
| 7 This module has the base test class for Quasar tests, contain a set of | |
| 8 common utilities used by unittest for querying and manipulating Quasar-- | |
| 9 the Google Talk Chrome Extension (http//go/quasar) | |
| 10 """ | |
| 11 | |
| 12 import os | |
| 13 import random | |
| 14 import sys | |
| 15 import tempfile | |
| 16 import urllib2 | |
| 17 | |
| 18 import pyauto_quasar | |
| 19 import pyauto | |
| 20 | |
|
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.
| |
| 21 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.
| |
| 22 """Base test class for testing Quasar.""" | |
| 23 | |
| 24 def DownloadAndInstall(self): | |
| 25 """Download and install the Quasar extension.""" | |
| 26 self.Uninstall() | |
| 27 | |
| 28 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.
| |
| 29 tempdir = tempfile.mkdtemp() | |
| 30 localfile = os.path.join(tempdir, 'quasar.crx') | |
| 31 self._DownloadFile(url, localfile) | |
| 32 self.assertTrue(os.path.exists(localfile), | |
| 33 'Failed to download Quasar extension') | |
|
frankf
2011/12/05 20:34:57
nit: period at end of msg, also in other places.
| |
| 34 | |
| 35 self.InstallExtension(os.path.abspath(localfile), False) | |
| 36 extension = self.GetExtensionInfo() | |
| 37 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
| |
| 38 self.assertTrue(extension['is_enabled'], 'Quasar extension is disabled') | |
| 39 | |
| 40 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.
| |
| 41 """Uninstall the Quasar extension (if exists)""" | |
| 42 extension = self.GetExtensionInfo() | |
| 43 if extension: | |
|
Nirnimesh
2011/11/09 23:54:05
merge with previous line
wud
2011/11/10 23:35:19
Done.
| |
| 44 self.UninstallExtensionById(extension['id']) | |
| 45 | |
| 46 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.
| |
| 47 """Get the data object about the Quasar extension.""" | |
| 48 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!
| |
| 49 for ext in self.GetExtensionsInfo(): | |
| 50 if ext['name'] == 'Google Talk': | |
| 51 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
| |
| 52 'More than 1 Google Talk Extension installed') | |
| 53 info = ext | |
| 54 return info; | |
|
Nirnimesh
2011/11/09 23:54:05
remove ;
wud
2011/11/10 23:35:19
Done.
| |
| 55 | |
| 56 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.
| |
| 57 """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.
| |
| 58 return self._RunInTab(self.GetMoleInfo(mole_index), js) | |
| 59 | |
| 60 def RunInRoster(self, js): | |
| 61 """Execute javascript in the chat roster.""" | |
| 62 return self._RunInTab(self.GetViewerInfo(), js, '//iframe[1]\n//iframe[1]') | |
| 63 | |
| 64 def RunInLoginPage(self, js, xpath = ''): | |
| 65 """Execute javascript in the gaia login popup.""" | |
| 66 return self._RunInTab(self.GetLoginPageInfo(), js, xpath) | |
| 67 | |
| 68 def RunInViewer(self, js, xpath = ''): | |
| 69 """Execute javascript in the Quasar viewer window.""" | |
| 70 return self._RunInTab(self.GetViewerInfo(), js, xpath) | |
| 71 | |
| 72 def RunInBackground(self, js, xpath = '', expected = None): | |
| 73 """Execute javascript in the Quasar background window.""" | |
| 74 background_view = self.GetBackgroundInfo() | |
| 75 value = self.ExecuteJavascriptInRenderView( | |
| 76 self._WrapJs(js), background_view['view']) | |
| 77 self._LogRun(js, value) | |
| 78 return value | |
| 79 | |
| 80 def GetMoleInfo(self, mole_index = 0): | |
| 81 """Get the data object about a given chat mole.""" | |
| 82 return self._GetTabInfo('/pmole?', mole_index) | |
| 83 | |
| 84 def GetViewerInfo(self): | |
| 85 """Get the data object about the Quasar viewer dialog.""" | |
| 86 extension = self.GetExtensionInfo() | |
| 87 return self._GetTabInfo( | |
| 88 'chrome-extension://' + extension['id'] + '/viewer.html') | |
| 89 | |
| 90 def GetLoginPageInfo(self): | |
| 91 """Get the data object about the gaia login popup.""" | |
| 92 return self._GetTabInfo('https://accounts.google.com/ServiceLogin?') | |
| 93 | |
| 94 def GetBackgroundInfo(self): | |
| 95 """Get the data object about the Quasar background page.""" | |
| 96 extension_views = self.GetBrowserInfo()['extension_views'] | |
| 97 for extension_view in extension_views: | |
| 98 if 'Google Talk' in extension_view['name'] and \ | |
| 99 'EXTENSION_BACKGROUND_PAGE' == extension_view['view_type']: | |
| 100 return extension_view | |
| 101 return None; | |
| 102 | |
| 103 def WaitUntilResult(self, result, func, error): | |
| 104 """Loop func until a condition matches is satified""" | |
| 105 return self.assertTrue(self.WaitUntil( | |
| 106 lambda: result == func()), error) | |
| 107 | |
| 108 def WaitUntilCondition(self, func, matches, error): | |
| 109 """Loop func until a condition matches is satified""" | |
| 110 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
| |
| 111 lambda: matches(func())), error) | |
| 112 | |
| 113 def _WrapJs(self, statement): | |
| 114 """Wrap the javascript to be executed.""" | |
| 115 return 'window.domAutomationController.send(' + \ | |
| 116 '(function(){' + self._GetInjectedJs() + \ | |
| 117 'try{return ' + statement + '}' + \ | |
| 118 'catch(e){return "JS_ERROR: " + e}})())' | |
| 119 | |
| 120 def _RunInTab(self, tab, js, xpath = ''): | |
| 121 """Execute javascript in a given tab.""" | |
| 122 if not tab: | |
| 123 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.
| |
| 124 return False | |
| 125 print "Run in tab: " + js | |
| 126 try: | |
|
Nirnimesh
2011/11/09 23:54:05
WHy?
wud
2011/11/10 23:35:19
Sometimes, the test would throw a JSONInterfaceErr
| |
| 127 value = self.ExecuteJavascriptInTab(self._WrapJs(js), | |
| 128 windex = tab['windex'], | |
| 129 frame_xpath = xpath) | |
| 130 except Exception as e: | |
| 131 print "Error running JS: %s" % js | |
| 132 value = False | |
| 133 self._LogRun(js, value) | |
| 134 return value | |
| 135 | |
| 136 def _LogRun(self, js, value): | |
| 137 """Log a particular run.""" | |
| 138 out = value | |
| 139 if not isinstance(value, basestring): | |
|
frankf
2011/12/05 20:34:57
don't need the if statement.
| |
| 140 out = str(value) | |
| 141 out = out[:300] | |
| 142 out = out.replace("\n", "") | |
| 143 out = out.replace("\r", "") | |
| 144 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.
| |
| 145 | |
| 146 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
| |
| 147 """Get the data object for a given tab.""" | |
| 148 windows = self.GetBrowserInfo()['windows'] | |
| 149 i = 0 | |
| 150 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.
| |
| 151 for tab in win['tabs']: | |
| 152 if tab['url'] and url_query in tab['url']: | |
| 153 tab['windex'] = win['index'] | |
| 154 if (i == index): | |
|
Nirnimesh
2011/11/09 23:54:05
remove parens
wud
2011/11/10 23:35:19
Done.
| |
| 155 return tab | |
| 156 i = i + 1 | |
| 157 return None; | |
|
Nirnimesh
2011/11/09 23:54:05
remove ;
wud
2011/11/10 23:35:19
Done.
| |
| 158 | |
| 159 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.
| |
| 160 """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.
| |
| 161 # 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.
| |
| 162 # "install extension" prompt without a hook I can find to click it, so | |
| 163 # we download the extension file using urllib2 instead. | |
| 164 u = urllib2.urlopen(url) | |
| 165 localFile = open(filename, 'w') | |
| 166 localFile.write(u.read()) | |
| 167 localFile.close() | |
| 168 return True | |
| 169 | |
| 170 def _GetInjectedJs(self): | |
| 171 """Get the javascript to inject in the execution environment.""" | |
| 172 if self.injectedJs_ == None: | |
| 173 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.
| |
| 174 js = jsfile.read() | |
| 175 jsfile.close() | |
| 176 self.injectedJs_ = js | |
| 177 return self.injectedJs_ | |
| 178 | |
| 179 def action_max_timeout_ms(self): | |
| 180 return 30000; | |
| 181 | |
| 182 def __init__(self, methodName='runTest'): | |
| 183 pyauto.PyUITest.__init__(self, methodName) | |
| 184 self.injectedJs_ = None | |
|
Nirnimesh
2011/11/09 23:54:05
use varnames_with_underscores
Prefix _
wud
2011/11/10 23:35:19
Done.
| |
| OLD | NEW |