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 contains the basic set of sanity tests run on the | |
Nirnimesh
2011/11/09 23:54:05
Break this up into one-line of title
(then a blank
wud
2011/11/10 23:35:19
Done.
| |
8 Quasar extension (http://go/quasar). | |
Nirnimesh
2011/11/09 23:54:05
Create a page on dev.chromium.org and link it here
wud
2011/11/10 23:35:19
Linked to public extension page instead.
| |
9 """ | |
10 | |
11 import glob | |
12 import logging | |
13 import os | |
14 import random | |
15 import sys | |
16 import time | |
17 import tempfile | |
frankf
2011/11/10 00:20:18
not alpha. Please run gpylint.
wud
2011/11/10 23:35:19
Done.
| |
18 import traceback | |
19 import urllib2 | |
20 | |
21 import quasar_base_test | |
22 import pyauto_quasar | |
23 import pyauto | |
24 | |
25 class TestInstall(quasar_base_test.BaseTest): | |
26 """Test for Google Talk Chrome Extension.""" | |
27 | |
28 def Debug(self, text): | |
Nirnimesh
2011/11/09 23:54:05
Since this blocks, rename to something clearer?
Pr
wud
2011/11/10 23:35:19
Done.
| |
29 """Pause execution with debug output.""" | |
30 if not isinstance(text, basestring): | |
Nirnimesh
2011/11/09 23:54:05
I don't think this check is necessary.
text = str(
wud
2011/11/10 23:35:19
good point. :)
| |
31 text = str(text) | |
32 raw_input('--------------------> ' + text.encode("utf-8")) | |
33 | |
34 def _OpenRoster(self): | |
35 """Download Talk extension and open the roster.""" | |
36 | |
37 # Download and install the extension. | |
Nirnimesh
2011/11/09 23:54:05
comment is redundant
wud
2011/11/10 23:35:19
Done.
| |
38 self.DownloadAndInstall() | |
39 | |
40 # Wait for the background view to load. | |
41 extension = self.GetExtensionInfo() | |
42 background_view = self.WaitUntilExtensionViewLoaded( | |
43 extension_id = extension['id'], | |
44 view_type = 'EXTENSION_BACKGROUND_PAGE') | |
45 self.assertTrue(background_view, | |
46 'Failed to get background view: views = %s.' % | |
Nirnimesh
2011/11/09 23:54:05
it's customary to use named args wherever possible
| |
47 self.GetBrowserInfo()['extension_views']) | |
48 | |
49 # Wait for the custom QTest hook to load. | |
50 self.WaitUntilResult(True, | |
51 lambda: self.RunInBackground('Boolean(QTest)'), | |
52 'Timed out waiting for QTest.handleBrowserAction function') | |
53 | |
54 # Run hook to simluate clicking the browser action icon. | |
55 # TODO(wud): replace after click BA icon is supported. | |
frankf
2011/11/10 00:20:18
Is there a reason you don't start the app from the
wud
2011/11/10 23:35:19
Our extension is not on the new tab page.
frankf
2011/12/05 20:34:57
Browser action hook is now implemented: http://src
| |
56 result = self.RunInBackground('QTest.handleBrowserAction()') | |
57 self.assertTrue('ok' == result, | |
Nirnimesh
2011/11/09 23:54:05
use assertEqual('ok', result, msg='...')
wud
2011/11/10 23:35:19
Done.
| |
58 'Call to QTest.handleBrowserAction failed.') | |
59 | |
60 # Wait for viewer window to open. | |
61 self.assertTrue(self.WaitUntil(lambda: bool(self.GetViewerInfo())), | |
62 'Timed out waiting for viewer.html to open') | |
63 | |
64 # Wait for viewer window to load the sign-in page. | |
65 self.WaitUntilCondition( | |
66 lambda: self.RunInViewer('window.location.href', | |
67 '//iframe[1]'), | |
68 lambda url: url and '/qsignin' in url, | |
69 'Timed out waiting for /qsignin page') | |
70 | |
71 def _SignIn(self): | |
72 """Download the extension, open the roster, and sign in""" | |
73 | |
74 # Open the roster. | |
75 self._OpenRoster() | |
76 | |
77 # Wait for /qsignin's BODY. | |
78 self.WaitUntilResult(True, | |
79 lambda: self.RunInViewer( | |
80 'Boolean($BODY())', '//iframe[1]'), | |
81 'Timed out waiting for document.body in /qsignin page.') | |
82 | |
83 # Wait for the "Sign In" link. | |
84 self.WaitUntilResult(True, | |
85 lambda: self.RunInViewer( | |
86 'Boolean($FindByText($BODY(), "Sign In"))', '//iframe[1]'), | |
87 'Timed out waiting for "Sign In" link in DOM.') | |
88 | |
89 # Click the "Sign In" link. | |
90 self.assertTrue(self.RunInViewer( | |
91 '$Click($FindByText($BODY(), "Sign In"))', '//iframe[1]')) | |
92 | |
93 # Wait for the login page to open. | |
94 self.assertTrue(self.WaitUntil(lambda: bool(self.GetLoginPageInfo())), | |
95 'Timed out waiting for login page to open') | |
96 | |
97 # Wait for the login page's form element. | |
98 self.WaitUntilResult(True, | |
99 lambda: self.RunInLoginPage('Boolean(document.forms[0])'), | |
100 'Timed out waiting for document.forms[0]') | |
101 | |
102 # Fill and submit the login form. | |
103 self.RunInLoginPage( | |
104 'document.forms[0].Email.value="quasar.test.1@gmail.com"') | |
105 self.RunInLoginPage('document.forms[0].Passwd.value="stablechat"') | |
106 self.RunInLoginPage('document.forms[0].submit() || true') | |
107 | |
108 def RunBasicFunctionalityTest(self): | |
109 """Run tests for basic functionality in Quasar.""" | |
110 | |
111 # Install the extension, open the viewer, and sign in. | |
112 self._SignIn() | |
113 | |
114 # Wait for the roster container iframe. | |
115 self.WaitUntilResult(True, | |
116 lambda: self.RunInViewer('Boolean(window.frames[0])'), | |
117 'Timed out waiting for roster container iframe') | |
118 | |
119 # Wait for the roster iframe. | |
120 self.WaitUntilResult(True, | |
121 lambda: self.RunInViewer('Boolean(window.frames[0])', '//iframe[1]'), | |
122 'Timed out waiting for roster iframe') | |
123 | |
124 # Wait for the roster iframe to load. | |
125 self.WaitUntilCondition( | |
126 lambda: self.RunInRoster('window.location.href'), | |
127 lambda url: url and '/notifierclient' in url, | |
128 'Timed out waiting for /notifierclient url') | |
129 | |
130 # Wait for "Search contacts..." to appear in the roster. | |
131 self.WaitUntilCondition( | |
132 lambda: self.RunInRoster('window.document.body.innerHTML'), | |
133 lambda html: html and 'Search contacts...' in html, | |
134 'Timed out waiting for search contacts text in roster DOM.') | |
135 | |
136 # Wait for "chatpinger@appspot.com" to appear in the roster. | |
137 self.WaitUntilResult(True, | |
138 lambda: self.RunInRoster( | |
139 'Boolean($FindByText($BODY(), "chatpinger@appspot.com"))'), | |
140 'Timed out waiting for chatpinger@appspot.com in roster DOM.') | |
141 | |
142 # TODO(wud): fix issue where mole doesn't open when clicked too quickly. | |
143 time.sleep(1) | |
frankf
2011/11/10 00:20:18
Fix?
wud
2011/11/10 23:35:19
Still not yet. This doesn't seem to happen outside
| |
144 | |
145 # Click "chatpinger@appspot.com" to open a chat mole. | |
146 self.RunInRoster('$Click($FindByText($BODY(), "chatpinger@appspot.com"))') | |
147 | |
148 # Wait for chat mole to open. | |
149 self.assertTrue(self.WaitUntil(lambda: bool(self.GetMoleInfo())), | |
150 'Timed out waiting for mole window to open') | |
151 | |
152 # Wait for chat mole to load. | |
153 self.WaitUntilResult(True, | |
154 lambda: self.RunInMole('Boolean(window.location.href)'), | |
155 'Timed out waiting for mole window location') | |
156 | |
157 # Wait for the chat mole's input textarea to load. | |
158 self.WaitUntilResult(True, | |
159 lambda: self.RunInMole( | |
160 'Boolean($FindByTagName($BODY(), "textarea", 0))'), | |
161 'Timed out waiting for mole textarea') | |
162 | |
163 # Type /ping in the mole's input widget. | |
164 self.assertTrue(self.RunInMole( | |
165 '$Type($FindByTagName($BODY(), "textarea", 0), "/ping")'), | |
166 'Error typing in mole textarea') | |
167 | |
168 # Type ENTER in the mole's input widget. | |
169 self.assertTrue(self.RunInMole( | |
170 '$Press($FindByTagName($BODY(),"textarea",0), $KEYS.ENTER)'), | |
171 'Error sending ENTER in mole textarea') | |
172 | |
173 # Wait for chat input to clear. | |
174 self.WaitUntilResult(True, | |
175 lambda: self.RunInMole( | |
176 'Boolean($FindByTagName($BODY(),"textarea",0).value=="")'), | |
177 'Timed out waiting for textarea to clear after ENTER') | |
178 | |
179 # Wait for /ping to appear in the chat history. | |
180 self.WaitUntilCondition( | |
181 lambda: self.RunInMole('window.document.body.innerHTML'), | |
182 lambda html: html and '/ping' in html, | |
183 'Timed out waiting for /ping to appear in mole DOM') | |
184 | |
185 # Wait for the echo "Ping!" to appear in the chat history. | |
186 self.WaitUntilCondition( | |
187 lambda: self.RunInMole('window.document.body.innerHTML'), | |
188 lambda html: html and 'Ping!' in html, | |
189 'Timed out waiting for "Ping!" reply to appear in mole DOM') | |
190 | |
191 # Request a ping in 7 seconds. | |
192 self.assertTrue(self.RunInMole( | |
193 '$Type($FindByTagName($BODY(),"textarea",0), "/ping 7")'), | |
194 'Error typing "ping /7" in mole textarea') | |
195 | |
196 # Press Enter in chat input. | |
197 self.assertTrue(self.RunInMole( | |
198 '$Press($FindByTagName($BODY(),"textarea",0), $KEYS.ENTER)'), | |
199 'Error sending ENTER after "ping /7" in mole textarea') | |
200 | |
201 # Briefly show mole for visual examination. | |
202 # Also works around issue where extension may show the first | |
203 # Ping! notification before closing the mole. | |
204 time.sleep(2) | |
205 | |
206 # Press escape to close the mole. | |
207 self.assertTrue(self.RunInMole( | |
208 '$Press($FindByTagName($BODY(),"textarea",0), $KEYS.ESC)'), | |
209 'Error sending ESC after "ping /7" in mole textarea') | |
210 | |
211 # Wait for the mole to close. | |
212 self.WaitUntil( | |
213 lambda: not(bool(self.GetMoleInfo())), | |
214 'Timed out waiting for chatpinger mole to close') | |
215 | |
216 # Wait for a incoming chat toast to appear (requested above). | |
217 self.WaitUntilResult(True, | |
218 lambda: self.RunInBackground('Boolean($VIEW("/toast.html"))'), | |
219 'Timed out waiting for toast') | |
220 | |
221 # Wait for the toast body to exist. | |
222 self.WaitUntilResult(True, | |
223 lambda: self.RunInBackground('Boolean($BODY($VIEW("/toast.html")))'), | |
224 'Timed out waiting for toast body') | |
225 | |
226 # Wait for "Ping!" to appear in the toast. | |
227 self.WaitUntilResult(True, | |
228 lambda: self.RunInBackground( | |
229 'Boolean($FindByText($BODY($VIEW("/toast.html")), "Ping!"))'), | |
230 'Timed out waiting for "Ping!" in toast') | |
231 | |
232 # Click "Ping!" in the toast to open a mole. | |
233 self.assertTrue(self.RunInBackground( | |
234 '$Click($FindByText($BODY($VIEW("/toast.html")), "Ping!"))'), | |
235 'Error clicking "Ping!" in toast') | |
236 | |
237 # Wait for the mole to open. | |
238 self.assertTrue(self.WaitUntil(lambda: bool(self.GetMoleInfo())), | |
239 'Timed out waiting for mole window to open') | |
240 | |
241 # Ensure "chatpinger2@appspot.com" is in the roster. | |
242 self.WaitUntilResult(True, | |
243 lambda: self.RunInRoster( | |
244 'Boolean($FindByText($BODY(), "chatpinger2@appspot.com"))'), | |
245 'Timed out waiting for chatpinger2@appspot.com in roster DOM.') | |
246 | |
247 # Click "chatpinger2@appspot.com" in the roster. | |
248 self.RunInRoster('$Click($FindByText($BODY(), "chatpinger2@appspot.com"))') | |
249 | |
250 # Wait for a second chat mole to open. | |
251 self.assertTrue(self.WaitUntil(lambda: bool(self.GetMoleInfo(1))), | |
252 'Timed out waiting for second mole window to open') | |
253 | |
254 # Disable the extension. | |
255 extension = self.GetExtensionInfo() | |
256 self.SetExtensionStateById(extension['id'], enable=False, | |
257 allow_in_incognito=False) | |
258 extension = self.GetExtensionInfo() | |
259 self.assertFalse(extension['is_enabled']) | |
260 | |
261 # Verify all moles + windows are closed. | |
262 self.assertTrue(self.WaitUntil(lambda: not(bool(self.GetViewerInfo()))), | |
263 'Timed out waiting for viewer.html to close after disabling') | |
264 self.assertTrue(self.WaitUntil(lambda: not(bool(self.GetMoleInfo()))), | |
265 'Timed out waiting for first mole to close after disabling') | |
266 self.assertTrue(self.WaitUntil(lambda: not(bool(self.GetMoleInfo(1)))), | |
267 'Timed out waiting for second mole to close after disabling') | |
268 | |
269 def testBasicFunctionality(self): | |
270 """Run tests for basic functionality in Quasar with retries.""" | |
271 | |
272 tries = 0 | |
273 RETRIES = 5 | |
274 for tries in range(RETRIES): | |
275 print ("Calling RunBasicFunctionalityTest. Try #{0}/{1}" | |
276 .format(tries + 1, RETRIES)) | |
277 try: | |
278 self.RunBasicFunctionalityTest() | |
279 print ("RunBasicFunctionalityTest succeeded. Tries: {0}" | |
280 .format(tries + 1)) | |
281 break | |
282 except Exception as e: | |
283 print "\n*** ERROR in RunBasicFunctionalityTest ***" | |
284 exc_type, exc_value, exc_traceback = sys.exc_info() | |
frankf
2011/11/10 00:20:18
Can you verify this doesn't cause a circular refer
wud
2011/11/10 23:35:19
Done.
| |
285 traceback.print_exception(exc_type, exc_value, exc_traceback) | |
286 print "\n" | |
287 if tries < RETRIES - 1: | |
288 self.NavigateToURL("http://accounts.google.com/Logout"); | |
289 time.sleep(5) | |
frankf
2011/11/10 00:20:18
Why is sleep required here? Are expecting transien
wud
2011/11/10 23:35:19
Not really, removed.
| |
290 print "Retring..." | |
291 else: | |
292 raise | |
293 | |
294 if __name__ == '__main__': | |
295 pyauto_quasar.Main() | |
OLD | NEW |