Chromium Code Reviews| 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() |