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