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