Index: chrome/test/functional/quasar/test_basic.py |
=================================================================== |
--- chrome/test/functional/quasar/test_basic.py (revision 0) |
+++ chrome/test/functional/quasar/test_basic.py (revision 0) |
@@ -0,0 +1,295 @@ |
+#!/usr/bin/python |
+# Copyright (c) 2011 The Chromium Authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+ |
+""" |
+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.
|
+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.
|
+""" |
+ |
+import glob |
+import logging |
+import os |
+import random |
+import sys |
+import time |
+import tempfile |
frankf
2011/11/10 00:20:18
not alpha. Please run gpylint.
wud
2011/11/10 23:35:19
Done.
|
+import traceback |
+import urllib2 |
+ |
+import quasar_base_test |
+import pyauto_quasar |
+import pyauto |
+ |
+class TestInstall(quasar_base_test.BaseTest): |
+ """Test for Google Talk Chrome Extension.""" |
+ |
+ 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.
|
+ """Pause execution with debug output.""" |
+ 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. :)
|
+ text = str(text) |
+ raw_input('--------------------> ' + text.encode("utf-8")) |
+ |
+ def _OpenRoster(self): |
+ """Download Talk extension and open the roster.""" |
+ |
+ # Download and install the extension. |
Nirnimesh
2011/11/09 23:54:05
comment is redundant
wud
2011/11/10 23:35:19
Done.
|
+ self.DownloadAndInstall() |
+ |
+ # Wait for the background view to load. |
+ extension = self.GetExtensionInfo() |
+ background_view = self.WaitUntilExtensionViewLoaded( |
+ extension_id = extension['id'], |
+ view_type = 'EXTENSION_BACKGROUND_PAGE') |
+ self.assertTrue(background_view, |
+ 'Failed to get background view: views = %s.' % |
Nirnimesh
2011/11/09 23:54:05
it's customary to use named args wherever possible
|
+ self.GetBrowserInfo()['extension_views']) |
+ |
+ # Wait for the custom QTest hook to load. |
+ self.WaitUntilResult(True, |
+ lambda: self.RunInBackground('Boolean(QTest)'), |
+ 'Timed out waiting for QTest.handleBrowserAction function') |
+ |
+ # Run hook to simluate clicking the browser action icon. |
+ # 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
|
+ result = self.RunInBackground('QTest.handleBrowserAction()') |
+ self.assertTrue('ok' == result, |
Nirnimesh
2011/11/09 23:54:05
use assertEqual('ok', result, msg='...')
wud
2011/11/10 23:35:19
Done.
|
+ 'Call to QTest.handleBrowserAction failed.') |
+ |
+ # Wait for viewer window to open. |
+ self.assertTrue(self.WaitUntil(lambda: bool(self.GetViewerInfo())), |
+ 'Timed out waiting for viewer.html to open') |
+ |
+ # Wait for viewer window to load the sign-in page. |
+ self.WaitUntilCondition( |
+ lambda: self.RunInViewer('window.location.href', |
+ '//iframe[1]'), |
+ lambda url: url and '/qsignin' in url, |
+ 'Timed out waiting for /qsignin page') |
+ |
+ def _SignIn(self): |
+ """Download the extension, open the roster, and sign in""" |
+ |
+ # Open the roster. |
+ self._OpenRoster() |
+ |
+ # Wait for /qsignin's BODY. |
+ self.WaitUntilResult(True, |
+ lambda: self.RunInViewer( |
+ 'Boolean($BODY())', '//iframe[1]'), |
+ 'Timed out waiting for document.body in /qsignin page.') |
+ |
+ # Wait for the "Sign In" link. |
+ self.WaitUntilResult(True, |
+ lambda: self.RunInViewer( |
+ 'Boolean($FindByText($BODY(), "Sign In"))', '//iframe[1]'), |
+ 'Timed out waiting for "Sign In" link in DOM.') |
+ |
+ # Click the "Sign In" link. |
+ self.assertTrue(self.RunInViewer( |
+ '$Click($FindByText($BODY(), "Sign In"))', '//iframe[1]')) |
+ |
+ # Wait for the login page to open. |
+ self.assertTrue(self.WaitUntil(lambda: bool(self.GetLoginPageInfo())), |
+ 'Timed out waiting for login page to open') |
+ |
+ # Wait for the login page's form element. |
+ self.WaitUntilResult(True, |
+ lambda: self.RunInLoginPage('Boolean(document.forms[0])'), |
+ 'Timed out waiting for document.forms[0]') |
+ |
+ # Fill and submit the login form. |
+ self.RunInLoginPage( |
+ 'document.forms[0].Email.value="quasar.test.1@gmail.com"') |
+ self.RunInLoginPage('document.forms[0].Passwd.value="stablechat"') |
+ self.RunInLoginPage('document.forms[0].submit() || true') |
+ |
+ def RunBasicFunctionalityTest(self): |
+ """Run tests for basic functionality in Quasar.""" |
+ |
+ # Install the extension, open the viewer, and sign in. |
+ self._SignIn() |
+ |
+ # Wait for the roster container iframe. |
+ self.WaitUntilResult(True, |
+ lambda: self.RunInViewer('Boolean(window.frames[0])'), |
+ 'Timed out waiting for roster container iframe') |
+ |
+ # Wait for the roster iframe. |
+ self.WaitUntilResult(True, |
+ lambda: self.RunInViewer('Boolean(window.frames[0])', '//iframe[1]'), |
+ 'Timed out waiting for roster iframe') |
+ |
+ # Wait for the roster iframe to load. |
+ self.WaitUntilCondition( |
+ lambda: self.RunInRoster('window.location.href'), |
+ lambda url: url and '/notifierclient' in url, |
+ 'Timed out waiting for /notifierclient url') |
+ |
+ # Wait for "Search contacts..." to appear in the roster. |
+ self.WaitUntilCondition( |
+ lambda: self.RunInRoster('window.document.body.innerHTML'), |
+ lambda html: html and 'Search contacts...' in html, |
+ 'Timed out waiting for search contacts text in roster DOM.') |
+ |
+ # Wait for "chatpinger@appspot.com" to appear in the roster. |
+ self.WaitUntilResult(True, |
+ lambda: self.RunInRoster( |
+ 'Boolean($FindByText($BODY(), "chatpinger@appspot.com"))'), |
+ 'Timed out waiting for chatpinger@appspot.com in roster DOM.') |
+ |
+ # TODO(wud): fix issue where mole doesn't open when clicked too quickly. |
+ 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
|
+ |
+ # Click "chatpinger@appspot.com" to open a chat mole. |
+ self.RunInRoster('$Click($FindByText($BODY(), "chatpinger@appspot.com"))') |
+ |
+ # Wait for chat mole to open. |
+ self.assertTrue(self.WaitUntil(lambda: bool(self.GetMoleInfo())), |
+ 'Timed out waiting for mole window to open') |
+ |
+ # Wait for chat mole to load. |
+ self.WaitUntilResult(True, |
+ lambda: self.RunInMole('Boolean(window.location.href)'), |
+ 'Timed out waiting for mole window location') |
+ |
+ # Wait for the chat mole's input textarea to load. |
+ self.WaitUntilResult(True, |
+ lambda: self.RunInMole( |
+ 'Boolean($FindByTagName($BODY(), "textarea", 0))'), |
+ 'Timed out waiting for mole textarea') |
+ |
+ # Type /ping in the mole's input widget. |
+ self.assertTrue(self.RunInMole( |
+ '$Type($FindByTagName($BODY(), "textarea", 0), "/ping")'), |
+ 'Error typing in mole textarea') |
+ |
+ # Type ENTER in the mole's input widget. |
+ self.assertTrue(self.RunInMole( |
+ '$Press($FindByTagName($BODY(),"textarea",0), $KEYS.ENTER)'), |
+ 'Error sending ENTER in mole textarea') |
+ |
+ # Wait for chat input to clear. |
+ self.WaitUntilResult(True, |
+ lambda: self.RunInMole( |
+ 'Boolean($FindByTagName($BODY(),"textarea",0).value=="")'), |
+ 'Timed out waiting for textarea to clear after ENTER') |
+ |
+ # Wait for /ping to appear in the chat history. |
+ self.WaitUntilCondition( |
+ lambda: self.RunInMole('window.document.body.innerHTML'), |
+ lambda html: html and '/ping' in html, |
+ 'Timed out waiting for /ping to appear in mole DOM') |
+ |
+ # Wait for the echo "Ping!" to appear in the chat history. |
+ self.WaitUntilCondition( |
+ lambda: self.RunInMole('window.document.body.innerHTML'), |
+ lambda html: html and 'Ping!' in html, |
+ 'Timed out waiting for "Ping!" reply to appear in mole DOM') |
+ |
+ # Request a ping in 7 seconds. |
+ self.assertTrue(self.RunInMole( |
+ '$Type($FindByTagName($BODY(),"textarea",0), "/ping 7")'), |
+ 'Error typing "ping /7" in mole textarea') |
+ |
+ # Press Enter in chat input. |
+ self.assertTrue(self.RunInMole( |
+ '$Press($FindByTagName($BODY(),"textarea",0), $KEYS.ENTER)'), |
+ 'Error sending ENTER after "ping /7" in mole textarea') |
+ |
+ # Briefly show mole for visual examination. |
+ # Also works around issue where extension may show the first |
+ # Ping! notification before closing the mole. |
+ time.sleep(2) |
+ |
+ # Press escape to close the mole. |
+ self.assertTrue(self.RunInMole( |
+ '$Press($FindByTagName($BODY(),"textarea",0), $KEYS.ESC)'), |
+ 'Error sending ESC after "ping /7" in mole textarea') |
+ |
+ # Wait for the mole to close. |
+ self.WaitUntil( |
+ lambda: not(bool(self.GetMoleInfo())), |
+ 'Timed out waiting for chatpinger mole to close') |
+ |
+ # Wait for a incoming chat toast to appear (requested above). |
+ self.WaitUntilResult(True, |
+ lambda: self.RunInBackground('Boolean($VIEW("/toast.html"))'), |
+ 'Timed out waiting for toast') |
+ |
+ # Wait for the toast body to exist. |
+ self.WaitUntilResult(True, |
+ lambda: self.RunInBackground('Boolean($BODY($VIEW("/toast.html")))'), |
+ 'Timed out waiting for toast body') |
+ |
+ # Wait for "Ping!" to appear in the toast. |
+ self.WaitUntilResult(True, |
+ lambda: self.RunInBackground( |
+ 'Boolean($FindByText($BODY($VIEW("/toast.html")), "Ping!"))'), |
+ 'Timed out waiting for "Ping!" in toast') |
+ |
+ # Click "Ping!" in the toast to open a mole. |
+ self.assertTrue(self.RunInBackground( |
+ '$Click($FindByText($BODY($VIEW("/toast.html")), "Ping!"))'), |
+ 'Error clicking "Ping!" in toast') |
+ |
+ # Wait for the mole to open. |
+ self.assertTrue(self.WaitUntil(lambda: bool(self.GetMoleInfo())), |
+ 'Timed out waiting for mole window to open') |
+ |
+ # Ensure "chatpinger2@appspot.com" is in the roster. |
+ self.WaitUntilResult(True, |
+ lambda: self.RunInRoster( |
+ 'Boolean($FindByText($BODY(), "chatpinger2@appspot.com"))'), |
+ 'Timed out waiting for chatpinger2@appspot.com in roster DOM.') |
+ |
+ # Click "chatpinger2@appspot.com" in the roster. |
+ self.RunInRoster('$Click($FindByText($BODY(), "chatpinger2@appspot.com"))') |
+ |
+ # Wait for a second chat mole to open. |
+ self.assertTrue(self.WaitUntil(lambda: bool(self.GetMoleInfo(1))), |
+ 'Timed out waiting for second mole window to open') |
+ |
+ # Disable the extension. |
+ extension = self.GetExtensionInfo() |
+ self.SetExtensionStateById(extension['id'], enable=False, |
+ allow_in_incognito=False) |
+ extension = self.GetExtensionInfo() |
+ self.assertFalse(extension['is_enabled']) |
+ |
+ # Verify all moles + windows are closed. |
+ self.assertTrue(self.WaitUntil(lambda: not(bool(self.GetViewerInfo()))), |
+ 'Timed out waiting for viewer.html to close after disabling') |
+ self.assertTrue(self.WaitUntil(lambda: not(bool(self.GetMoleInfo()))), |
+ 'Timed out waiting for first mole to close after disabling') |
+ self.assertTrue(self.WaitUntil(lambda: not(bool(self.GetMoleInfo(1)))), |
+ 'Timed out waiting for second mole to close after disabling') |
+ |
+ def testBasicFunctionality(self): |
+ """Run tests for basic functionality in Quasar with retries.""" |
+ |
+ tries = 0 |
+ RETRIES = 5 |
+ for tries in range(RETRIES): |
+ print ("Calling RunBasicFunctionalityTest. Try #{0}/{1}" |
+ .format(tries + 1, RETRIES)) |
+ try: |
+ self.RunBasicFunctionalityTest() |
+ print ("RunBasicFunctionalityTest succeeded. Tries: {0}" |
+ .format(tries + 1)) |
+ break |
+ except Exception as e: |
+ print "\n*** ERROR in RunBasicFunctionalityTest ***" |
+ 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.
|
+ traceback.print_exception(exc_type, exc_value, exc_traceback) |
+ print "\n" |
+ if tries < RETRIES - 1: |
+ self.NavigateToURL("http://accounts.google.com/Logout"); |
+ 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.
|
+ print "Retring..." |
+ else: |
+ raise |
+ |
+if __name__ == '__main__': |
+ pyauto_quasar.Main() |