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 """Basic sanity tests for the GTalk extension (http://go/quasar) | |
7 | |
8 This module contains the basic set of sanity tests run on the | |
9 GTalk extension: | |
10 https://chrome.google.com/webstore/detail/nckgahadagoaajjgafhacjanaoiihapd | |
11 """ | |
12 | |
13 import logging | |
14 import sys | |
15 import time | |
16 import traceback | |
17 import urllib2 | |
18 | |
19 import gtalk_base_test | |
20 import pyauto_functional | |
Nirnimesh
2011/12/13 20:03:25
this script need not know about pyauto_functional.
wud
2011/12/13 20:54:08
Done.
| |
21 import pyauto_gtalk # must preceed pyauto | |
22 import pyauto | |
23 | |
24 | |
25 class BasicTest(gtalk_base_test.GTalkBaseTest): | |
26 """Test for Google Talk Chrome Extension.""" | |
27 | |
28 def Prompt(self, text): | |
29 """Pause execution with debug output. | |
30 | |
31 Args: | |
32 text: The debug output. | |
33 """ | |
34 text = str(text) | |
35 raw_input('--------------------> ' + text.encode('utf-8')) | |
36 | |
37 def _OpenRoster(self): | |
38 """Download Talk extension and open the roster.""" | |
39 | |
40 self.InstallGTalkExtension() | |
41 | |
42 # Wait for the background view to load. | |
43 extension = self.GetGTalkExtensionInfo() | |
44 background_view = self.WaitUntilExtensionViewLoaded( | |
45 extension_id=extension['id'], | |
46 view_type='EXTENSION_BACKGROUND_PAGE') | |
47 self.assertTrue(background_view, | |
48 msg='Failed to get background view: views = %s.' % | |
49 self.GetBrowserInfo()['extension_views']) | |
50 | |
51 # Wait for the custom QTest hook to load. | |
52 self.WaitUntilResult(True, | |
53 lambda: self.RunInBackground('Boolean(QTest)'), | |
54 msg='Timed out waiting for QTest.handleBrowserAction function') | |
55 | |
56 # Run hook to simluate clicking the browser action icon. | |
57 # TODO(wud): replace after click BA icon is supported. | |
58 # See http://crbug.com/97342. | |
Nirnimesh
2011/12/13 20:03:25
Thanks to Frank, this issue has been fixed.
(you c
wud
2011/12/13 20:54:08
Thanks, updated comments. I'll take you up on your
| |
59 result = self.RunInBackground('QTest.handleBrowserAction()') | |
60 self.assertEqual('ok', result, | |
61 msg='Call to QTest.handleBrowserAction failed.') | |
62 | |
63 # Wait for viewer window to open. | |
64 self.assertTrue(self.WaitUntil(self.GetViewerInfo), | |
65 msg='Timed out waiting for viewer.html to open') | |
66 | |
67 # Wait for viewer window to load the sign-in page. | |
68 self.WaitUntilCondition( | |
69 lambda: self.RunInViewer('window.location.href', | |
70 '//iframe[1]'), | |
71 lambda url: url and '/qsignin' in url, | |
72 msg='Timed out waiting for /qsignin page') | |
73 | |
74 def _SignIn(self): | |
75 """Download the extension, open the roster, and sign in""" | |
76 | |
77 # Open the roster. | |
78 self._OpenRoster() | |
79 | |
80 # Wait for /qsignin's BODY. | |
81 self.WaitUntilResult(True, | |
82 lambda: self.RunInViewer( | |
83 'Boolean($BODY())', '//iframe[1]'), | |
84 msg='Timed out waiting for document.body in /qsignin page.') | |
85 | |
86 # Wait for the "Sign In" link. | |
87 self.WaitUntilResult(True, | |
88 lambda: self.RunInViewer( | |
89 'Boolean($FindByText($BODY(), "Sign In"))', '//iframe[1]'), | |
90 msg='Timed out waiting for "Sign In" link in DOM.') | |
91 | |
92 # Click the "Sign In" link. | |
93 self.assertTrue(self.RunInViewer( | |
94 '$Click($FindByText($BODY(), "Sign In"))', '//iframe[1]')) | |
95 | |
96 # Wait for the login page to open. | |
97 self.assertTrue(self.WaitUntil(self.GetLoginPageInfo), | |
98 msg='Timed out waiting for login page to open') | |
99 | |
100 # Wait for the login page's form element. | |
101 self.WaitUntilResult(True, | |
102 lambda: self.RunInLoginPage('Boolean(document.forms[0])'), | |
103 msg='Timed out waiting for document.forms[0]') | |
104 | |
105 # Fill and submit the login form. | |
106 self.RunInLoginPage( | |
107 'document.forms[0].Email.value="quasar.test.1@gmail.com"') | |
108 self.RunInLoginPage('document.forms[0].Passwd.value="stablechat"') | |
109 self.RunInLoginPage('document.forms[0].submit() || true') | |
110 | |
111 def RunBasicFunctionalityTest(self): | |
112 """Run tests for basic functionality in GTalk.""" | |
113 | |
114 # Install the extension, open the viewer, and sign in. | |
115 self._SignIn() | |
116 | |
117 # Wait for the roster container iframe. | |
118 self.WaitUntilResult(True, | |
119 lambda: self.RunInViewer('Boolean(window.frames[0])'), | |
120 msg='Timed out waiting for roster container iframe') | |
121 | |
122 # Wait for the roster iframe. | |
123 self.WaitUntilResult(True, | |
124 lambda: self.RunInViewer('Boolean(window.frames[0])', '//iframe[1]'), | |
125 msg='Timed out waiting for roster iframe') | |
126 | |
127 # Wait for the roster iframe to load. | |
128 self.WaitUntilCondition( | |
129 lambda: self.RunInRoster('window.location.href'), | |
130 lambda url: url and '/notifierclient' in url, | |
131 msg='Timed out waiting for /notifierclient url') | |
132 | |
133 # Wait for "Search contacts..." to appear in the roster. | |
134 self.WaitUntilCondition( | |
135 lambda: self.RunInRoster('window.document.body.innerHTML'), | |
136 lambda html: html and 'Search contacts...' in html, | |
137 msg='Timed out waiting for search contacts text in roster DOM.') | |
138 | |
139 # Wait for "chatpinger@appspot.com" to appear in the roster. | |
140 self.WaitUntilResult(True, | |
141 lambda: self.RunInRoster( | |
142 'Boolean($FindByText($BODY(), "chatpinger@appspot.com"))'), | |
143 msg='Timed out waiting for chatpinger@appspot.com in roster DOM.') | |
144 | |
145 # TODO(wud): fix issue where mole doesn't open when clicked too quickly. | |
146 time.sleep(1) | |
147 | |
148 # Click "chatpinger@appspot.com" to open a chat mole. | |
149 self.RunInRoster('$Click($FindByText($BODY(), "chatpinger@appspot.com"))') | |
150 | |
151 # Wait for chat mole to open. | |
152 self.assertTrue(self.WaitUntil(self.GetMoleInfo), | |
153 msg='Timed out waiting for mole window to open') | |
154 | |
155 # Wait for chat mole to load. | |
156 self.WaitUntilResult(True, | |
157 lambda: self.RunInMole('Boolean(window.location.href)'), | |
158 msg='Timed out waiting for mole window location') | |
159 | |
160 # Wait for the chat mole's input textarea to load. | |
161 self.WaitUntilResult(True, | |
162 lambda: self.RunInMole( | |
163 'Boolean($FindByTagName($BODY(), "textarea", 0))'), | |
164 msg='Timed out waiting for mole textarea') | |
165 | |
166 # Type /ping in the mole's input widget. | |
167 self.assertTrue(self.RunInMole( | |
168 '$Type($FindByTagName($BODY(), "textarea", 0), "/ping")'), | |
169 msg='Error typing in mole textarea') | |
170 | |
171 # Type ENTER in the mole's input widget. | |
172 self.assertTrue(self.RunInMole( | |
173 '$Press($FindByTagName($BODY(),"textarea",0), $KEYS.ENTER)'), | |
174 msg='Error sending ENTER in mole textarea') | |
175 | |
176 # Wait for chat input to clear. | |
177 self.WaitUntilResult(True, | |
178 lambda: self.RunInMole( | |
179 'Boolean($FindByTagName($BODY(),"textarea",0).value=="")'), | |
180 msg='Timed out waiting for textarea to clear after ENTER') | |
181 | |
182 # Wait for /ping to appear in the chat history. | |
183 self.WaitUntilCondition( | |
184 lambda: self.RunInMole('window.document.body.innerHTML'), | |
185 lambda html: html and '/ping' in html, | |
186 msg='Timed out waiting for /ping to appear in mole DOM') | |
187 | |
188 # Wait for the echo "Ping!" to appear in the chat history. | |
189 self.WaitUntilCondition( | |
190 lambda: self.RunInMole('window.document.body.innerHTML'), | |
191 lambda html: html and 'Ping!' in html, | |
192 msg='Timed out waiting for "Ping!" reply to appear in mole DOM') | |
193 | |
194 # Request a ping in 7 seconds. | |
195 self.assertTrue(self.RunInMole( | |
196 '$Type($FindByTagName($BODY(),"textarea",0), "/ping 7")'), | |
197 msg='Error typing "ping /7" in mole textarea') | |
198 | |
199 # Press Enter in chat input. | |
200 self.assertTrue(self.RunInMole( | |
201 '$Press($FindByTagName($BODY(),"textarea",0), $KEYS.ENTER)'), | |
202 msg='Error sending ENTER after "ping /7" in mole textarea') | |
203 | |
204 # Briefly show mole for visual examination. | |
205 # Also works around issue where extension may show the first | |
206 # Ping! notification before closing the mole. | |
207 time.sleep(2) | |
208 | |
209 # Press escape to close the mole. | |
210 self.assertTrue(self.RunInMole( | |
211 '$Press($FindByTagName($BODY(),"textarea",0), $KEYS.ESC)'), | |
212 msg='Error sending ESC after "ping /7" in mole textarea') | |
213 | |
214 # Wait for the mole to close. | |
215 self.assertTrue(self.WaitUntil( | |
216 lambda: not(bool(self.GetMoleInfo()))), | |
217 msg='Timed out waiting for chatpinger mole to close') | |
218 | |
219 # Wait for a incoming chat toast to appear (requested above). | |
220 self.WaitUntilResult(True, | |
221 lambda: self.RunInBackground('Boolean($VIEW("/toast.html"))'), | |
222 msg='Timed out waiting for toast') | |
223 | |
224 # Wait for the toast body to exist. | |
225 self.WaitUntilResult(True, | |
226 lambda: self.RunInBackground('Boolean($BODY($VIEW("/toast.html")))'), | |
227 msg='Timed out waiting for toast body') | |
228 | |
229 # Wait for "Ping!" to appear in the toast. | |
230 self.WaitUntilResult(True, | |
231 lambda: self.RunInBackground( | |
232 'Boolean($FindByText($BODY($VIEW("/toast.html")), "Ping!"))'), | |
233 msg='Timed out waiting for "Ping!" in toast') | |
234 | |
235 # Click "Ping!" in the toast to open a mole. | |
236 self.assertTrue(self.RunInBackground( | |
237 '$Click($FindByText($BODY($VIEW("/toast.html")), "Ping!"))'), | |
238 msg='Error clicking "Ping!" in toast') | |
239 | |
240 # Wait for the mole to open. | |
241 self.assertTrue(self.WaitUntil(self.GetMoleInfo), | |
242 msg='Timed out waiting for mole window to open') | |
243 | |
244 # Ensure "chatpinger2@appspot.com" is in the roster. | |
245 self.WaitUntilResult(True, | |
246 lambda: self.RunInRoster( | |
247 'Boolean($FindByText($BODY(), "chatpinger2@appspot.com"))'), | |
248 msg='Timed out waiting for chatpinger2@appspot.com in roster DOM.') | |
249 | |
250 # Click "chatpinger2@appspot.com" in the roster. | |
251 self.RunInRoster('$Click($FindByText($BODY(), "chatpinger2@appspot.com"))') | |
252 | |
253 # Wait for a second chat mole to open. | |
254 self.assertTrue(self.WaitUntil(lambda: bool(self.GetMoleInfo(1))), | |
255 msg='Timed out waiting for second mole window to open') | |
256 | |
257 # Disable the extension. | |
258 extension = self.GetGTalkExtensionInfo() | |
259 self.SetExtensionStateById(extension['id'], enable=False, | |
260 allow_in_incognito=False) | |
261 extension = self.GetGTalkExtensionInfo() | |
262 self.assertFalse(extension['is_enabled']) | |
263 | |
264 # Verify all moles + windows are closed. | |
265 self.assertTrue(self.WaitUntil(lambda: not(bool(self.GetViewerInfo()))), | |
266 msg='Timed out waiting for viewer.html to close after disabling') | |
267 self.assertTrue(self.WaitUntil(lambda: not(bool(self.GetMoleInfo()))), | |
268 msg='Timed out waiting for first mole to close after disabling') | |
269 self.assertTrue(self.WaitUntil(lambda: not(bool(self.GetMoleInfo(1)))), | |
270 msg='Timed out waiting for second mole to close after disabling') | |
271 | |
272 def testBasicFunctionality(self): | |
273 """Run tests for basic functionality in GTalk with retries.""" | |
274 | |
275 # Since this test goes against prod servers, we'll retry to mitigate | |
276 # flakiness due to network issues. | |
277 tries = 0 | |
278 RETRIES = 5 | |
279 for tries in range(RETRIES): | |
280 logging.info('Calling RunBasicFunctionalityTest. Try #{0}/{1}' | |
Nirnimesh
2011/12/13 20:03:25
Why not use the more commonly used form for string
wud
2011/12/13 20:54:08
Thanks, done.
On 2011/12/13 20:03:25, Nirnimesh w
| |
281 .format(tries + 1, RETRIES)) | |
282 try: | |
283 self.RunBasicFunctionalityTest() | |
284 logging.info('RunBasicFunctionalityTest succeeded. Tries: {0}' | |
285 .format(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('Retrying...') | |
295 else: | |
296 raise | |
297 | |
298 | |
299 if __name__ == '__main__': | |
300 pyauto_functional.Main() | |
OLD | NEW |