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 """Basic sanity tests for the GTalk extension. | |
7 | |
8 This module contains the basic set of sanity tests run on the | |
9 GTalk extension. | |
10 """ | |
11 | |
12 import logging | |
13 import sys | |
14 import time | |
15 import traceback | |
16 import urllib2 | |
17 import os | |
18 | |
19 import gtalk_base_test | |
20 import pyauto_gtalk # must preceed pyauto | |
21 import pyauto | |
22 | |
23 | |
24 class BasicTest(gtalk_base_test.GTalkBaseTest): | |
25 """Test for Google Talk Chrome Extension.""" | |
26 | |
27 def _OpenRoster(self, gtalk_version): | |
28 """Download Talk extension and open the roster.""" | |
29 | |
30 self.InstallGTalkExtension(gtalk_version) | |
31 | |
32 # Wait for the background view to load. | |
33 extension = self.GetGTalkExtensionInfo() | |
34 background_view = self.WaitUntilExtensionViewLoaded( | |
35 extension_id=extension['id'], | |
36 view_type='EXTENSION_BACKGROUND_PAGE') | |
37 self.assertTrue(background_view, | |
38 msg='Failed to get background view: views = %s.' % | |
39 self.GetBrowserInfo()['extension_views']) | |
40 | |
41 # Click browser action icon | |
42 self.TriggerBrowserActionById(extension['id']) | |
43 | |
44 # Wait for viewer window to open. | |
45 self.assertTrue( | |
46 self.WaitUntil(self.GetViewerInfo), | |
47 msg='Timed out waiting for viewer.html to open.') | |
48 | |
49 # Wait for the sign-in iframe to load. | |
50 self.WaitUntilCondition( | |
51 lambda: self.RunInViewer( | |
52 'window.document.getElementsByTagName("iframe") != null && ' | |
53 'window.document.getElementsByTagName("iframe").length > 0') and | |
54 self.RunInViewer('window.location.href', | |
55 '//iframe[1]'), | |
56 lambda url: url and '/qsignin' in url, | |
57 msg='Timed out waiting for /qsignin page.') | |
58 | |
59 | |
60 def _SignIn(self, gtalk_version): | |
61 """Download the extension, open the roster, and sign in""" | |
62 # Open the roster. | |
63 self._OpenRoster(gtalk_version) | |
64 | |
65 # Wait for /qsignin's BODY. | |
66 self.WaitUntilResult(True, | |
67 lambda: self.RunInViewer( | |
68 'Boolean($BODY())', '//iframe[1]'), | |
69 msg='Timed out waiting for document.body in /qsignin page.') | |
70 | |
71 # Wait for the "Sign In" link. | |
72 self.WaitUntilResult(True, | |
73 lambda: self.RunInViewer( | |
74 'Boolean($FindByText($BODY(), "Sign In"))', '//iframe[1]'), | |
75 msg='Timed out waiting for "Sign In" link in DOM.') | |
76 | |
77 # Click the "Sign In" link. | |
78 self.assertTrue(self.RunInViewer( | |
79 '$Click($FindByText($BODY(), "Sign In"))', '//iframe[1]')) | |
80 | |
81 # Wait for the login page to open. | |
82 self.assertTrue(self.WaitUntil(self.GetLoginPageInfo), | |
83 msg='Timed out waiting for login page to open.') | |
84 | |
85 # Wait for the login page's form element. | |
86 self.WaitUntilResult(True, | |
87 lambda: self.RunInLoginPage('Boolean(document.forms[0])'), | |
88 msg='Timed out waiting for document.forms[0].') | |
89 | |
90 # Fill and submit the login form. | |
91 credentials = self.GetPrivateInfo()['test_google_account'] | |
92 | |
93 self.RunInLoginPage( | |
94 'document.forms[0].Email.value="' + credentials['username'] + '"') | |
95 self.RunInLoginPage( | |
96 'document.forms[0].Passwd.value="' + credentials['password'] + '"') | |
97 self.RunInLoginPage('document.forms[0].submit() || true') | |
98 | |
99 def RunBasicFunctionalityTest(self, gtalk_version): | |
100 """Run tests for basic functionality in GTalk.""" | |
101 | |
102 # Install the extension, open the viewer, and sign in. | |
103 self._SignIn(gtalk_version) | |
104 | |
105 # Wait for the roster container iframe. | |
106 self.WaitUntilResult(True, | |
107 lambda: self.RunInViewer( | |
108 'window.document.getElementById("popoutRoster") != null'), | |
109 msg='Timed out waiting for roster container iframe.') | |
110 | |
111 self.WaitUntilResult(True, | |
112 lambda: self.RunInViewer('Boolean(window.frames[0])', '//iframe[1]'), | |
113 msg='Timed out waiting for roster iframe.') | |
114 | |
115 # Wait for the roster iframe to load. | |
116 self.WaitUntilCondition( | |
117 lambda: self.RunInRoster('window.location.href'), | |
118 lambda url: url and '/frame' in url, | |
119 msg='Timed out waiting for /frame in url.') | |
120 | |
121 self.WaitUntilResult(True, | |
122 lambda: self.RunInRoster( | |
123 'Boolean($FindByText($BODY(), "Send a message to..."))'), | |
124 msg='Timed out waiting for "Send a message to..." label in roster DOM.') | |
125 | |
126 # Wait for "chatpinger@appspot.com" to appear in the roster. | |
127 self.WaitUntilResult(True, | |
128 lambda: self.RunInRoster( | |
129 'Boolean($FindByText($BODY(), "chatpinger@appspot.com"))'), | |
130 msg='Timed out waiting for chatpinger@appspot.com in roster DOM.') | |
131 | |
132 # Works around for issue where mole doesn't open when clicked too quickly. | |
133 time.sleep(1) | |
134 | |
135 # Click "chatpinger@appspot.com" to open a chat mole. | |
136 self.RunInRoster('$Click($FindByText($BODY(), "chatpinger@appspot.com"))') | |
137 | |
138 # Wait until ready to check whether mole is open(temporary work around). | |
139 time.sleep(1) | |
140 | |
141 # Wait for chat mole to open. | |
142 self.assertTrue(self.WaitUntil(self.GetMoleInfo), | |
143 msg='Timed out waiting for mole window to open.') | |
144 | |
145 self.WaitUntilResult(True, | |
146 lambda: self.RunInViewer( | |
147 'window.document.getElementsByTagName("iframe") != null'), | |
148 msg='Timed out waiting for iframes to load.') | |
149 | |
150 # Wait for chat mole to load. | |
151 self.WaitUntilResult(True, | |
152 lambda: self.RunInMole('Boolean(window.location.href)'), | |
153 msg='Timed out waiting for mole window location.') | |
154 | |
155 # Wait for the chat mole's input textarea to load. | |
156 self.WaitUntilResult(True, | |
157 lambda: self.RunInMole( | |
158 'Boolean($FindByTagName($BODY(), "textarea", 0))'), | |
159 msg='Timed out waiting for mole textarea.') | |
160 | |
161 # Type /ping in the mole's input widget. | |
162 self.assertTrue(self.RunInMole( | |
163 '$Type($FindByTagName($BODY(), "textarea", 0), "/ping")'), | |
164 msg='Error typing in mole textarea.') | |
165 | |
166 # Type ENTER in the mole's input widget. | |
167 self.assertTrue(self.RunInMole( | |
168 '$Press($FindByTagName($BODY(),"textarea",0), $KEYS.ENTER)'), | |
169 msg='Error sending ENTER in mole textarea.') | |
170 | |
171 # Wait for chat input to clear. | |
172 self.WaitUntilResult(True, | |
173 lambda: self.RunInMole( | |
174 'Boolean($FindByTagName($BODY(),"textarea",0).value=="")'), | |
175 msg='Timed out waiting for textarea to clear after ENTER.') | |
176 | |
177 # Wait for /ping to appear in the chat history. | |
178 self.WaitUntilCondition( | |
179 lambda: self.RunInMole('window.document.body.innerHTML'), | |
180 lambda html: html and '/ping' in html, | |
181 msg='Timed out waiting for /ping to appear in mole DOM.') | |
182 | |
183 # Wait for the echo "Ping!" to appear in the chat history. | |
184 self.WaitUntilCondition( | |
185 lambda: self.RunInMole('window.document.body.innerHTML'), | |
186 lambda html: html and 'Ping!' in html, | |
187 msg='Timed out waiting for "Ping!" reply to appear in mole DOM.') | |
188 | |
189 # Request a ping in 7 seconds. | |
190 self.assertTrue(self.RunInMole( | |
191 '$Type($FindByTagName($BODY(),"textarea",0), "/ping 7")'), | |
192 msg='Error typing "ping /7" in mole textarea.') | |
193 | |
194 # Press Enter in chat input. | |
195 self.assertTrue(self.RunInMole( | |
196 '$Press($FindByTagName($BODY(),"textarea",0), $KEYS.ENTER)'), | |
197 msg='Error sending ENTER after "ping /7" in mole textarea.') | |
198 | |
199 # Briefly show mole for visual examination. | |
200 # Also works around issue where extension may show the first | |
201 # Ping! notification before closing the mole. | |
202 time.sleep(2) | |
203 | |
204 # Press escape to close the mole. | |
205 self.assertTrue(self.RunInMole( | |
206 '$Press($FindByTagName($BODY(),"textarea",0), $KEYS.ESC)'), | |
207 msg='Error sending ESC after "ping /7" in mole textarea.') | |
208 | |
209 # Wait for the mole to close. | |
210 self.assertTrue(self.WaitUntil( | |
211 lambda: not(bool(self.GetMoleInfo()))), | |
212 msg='Timed out waiting for chatpinger mole to close.') | |
213 | |
214 # Ensure "chatpinger2@appspot.com" is in the roster. | |
215 self.WaitUntilResult(True, | |
216 lambda: self.RunInRoster( | |
217 'Boolean($FindByText($BODY(), "chatpinger2@appspot.com"))'), | |
218 msg='Timed out waiting for chatpinger2@appspot.com in roster DOM.') | |
219 | |
220 # Click "chatpinger2@appspot.com" in the roster. | |
221 self.RunInRoster('$Click($FindByText($BODY(), "chatpinger2@appspot.com"))') | |
222 | |
223 self.WaitUntilResult(True, | |
224 lambda: self.RunInViewer( | |
225 'window.document.getElementsByTagName("iframe") != null'), | |
226 msg='Timed out waiting for iframes to load.') | |
227 | |
228 # Wait for a second chat mole to open. | |
229 time.sleep(1) | |
230 self.assertTrue(self.WaitUntil(lambda: bool(self.GetMoleInfo(1))), | |
231 msg='Timed out waiting for second mole window to open.') | |
232 | |
233 # Wait for mole content to load | |
234 self.WaitUntilCondition( | |
235 lambda: self.RunInMole('window.document.body.innerHTML', 1), | |
236 lambda html: html and 'Ping!' in html, | |
237 msg='Timed out waiting for Ping! to appear in mole DOM.') | |
238 | |
239 # Disable the extension. | |
240 extension = self.GetGTalkExtensionInfo() | |
241 self.SetExtensionStateById(extension['id'], enable=False, | |
242 allow_in_incognito=False) | |
243 extension = self.GetGTalkExtensionInfo() | |
244 self.assertFalse(extension['is_enabled']) | |
245 | |
246 # Verify all moles + windows are closed. | |
247 self.assertTrue(self.WaitUntil(lambda: not(bool(self.GetViewerInfo()))), | |
248 msg='Timed out waiting for viewer.html to close after disabling.') | |
249 self.assertTrue(self.WaitUntil(lambda: not(bool(self.GetMoleInfo()))), | |
250 msg='Timed out waiting for first mole to close after disabling.') | |
251 self.assertTrue(self.WaitUntil(lambda: not(bool(self.GetMoleInfo(1)))), | |
252 msg='Timed out waiting for second mole to close after disabling.') | |
253 | |
254 def _GetCurrentGtalkVersion(self): | |
255 """Read current gtalk extension version from file.""" | |
256 return self._GetGtalkVersion('current_version') | |
257 | |
258 def _GetRCGtalkVersion(self): | |
259 """Read RC gtalk extension version from file""" | |
260 return self._GetGtalkVersion('rc_version') | |
261 | |
262 def _GetGtalkVersion(self, version_type): | |
263 """Read gtalk version from file""" | |
264 version_path = os.path.abspath( | |
265 os.path.join(self.DataDir(), 'extensions', | |
266 'gtalk', version_type)) | |
267 self.assertTrue( | |
268 os.path.exists(version_path), | |
269 msg='Failed to find version ' + version_path) | |
270 with open(version_path) as version_file: | |
271 return version_file.read() | |
272 | |
273 def _TestBasicFunctionality(self, version): | |
274 """Run tests for basic functionality in GTalk with retries.""" | |
275 | |
276 # Since this test goes against prod servers, we'll retry to mitigate | |
277 # flakiness due to network issues. | |
278 RETRIES = 5 | |
279 for tries in range(RETRIES): | |
280 logging.info('Calling RunBasicFunctionalityTest on %s. Try #%s/%s' | |
281 % (version, tries + 1, RETRIES)) | |
282 try: | |
283 self.RunBasicFunctionalityTest(version) | |
284 logging.info('RunBasicFunctionalityTest on %s succeeded. Tries: %s' | |
285 % (version, tries + 1)) | |
286 break | |
287 except Exception as e: | |
288 logging.info("\n*** ERROR in RunBasicFunctionalityTest ***") | |
289 exc_type, exc_value, exc_traceback = sys.exc_info() | |
290 traceback.print_exception(exc_type, exc_value, exc_traceback) | |
291 logging.info("\n") | |
292 if tries < RETRIES - 1: | |
293 self.NavigateToURL('http://accounts.google.com/Logout') | |
294 logging.info('Closing all moles.') | |
295 self.RunInAllMoles( | |
296 '$Press($FindByTagName($BODY(),"textarea",0), $KEYS.ESC)') | |
297 logging.info('Retrying...') | |
298 else: | |
299 raise | |
300 | |
301 def testCurrentVersion(self): | |
302 """Run basic functionality test on current version of gtalk extension""" | |
303 version = self._GetCurrentGtalkVersion() | |
304 self._TestBasicFunctionality(version) | |
305 | |
306 def testRCVersion(self): | |
307 """Run basic functionality test on RC version of gtalk extension""" | |
308 version = self._GetRCGtalkVersion() | |
309 self._TestBasicFunctionality(version) | |
310 | |
311 if __name__ == '__main__': | |
312 pyauto_gtalk.Main() | |
OLD | NEW |