Chromium Code Reviews| Index: chrome/test/functional/gtalk/test_basic.py |
| =================================================================== |
| --- chrome/test/functional/gtalk/test_basic.py (revision 0) |
| +++ chrome/test/functional/gtalk/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. |
| + |
| +"""Basic sanity tests for the GTalk extension (http://go/quasar) |
| + |
| +This module contains the basic set of sanity tests run on the |
| +GTalk extension: |
| +https://chrome.google.com/webstore/detail/nckgahadagoaajjgafhacjanaoiihapd |
| +""" |
| + |
| +import logging |
| +import sys |
| +import time |
| +import traceback |
| +import urllib2 |
| + |
| +import gtalk_base_test |
| +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.
|
| +import pyauto |
| + |
| + |
| +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.
|
| + """Test for Google Talk Chrome Extension.""" |
| + |
| + def Prompt(self, text): |
| + """Pause execution with debug output. |
| + |
| + Args: |
| + text: The debug output. |
| + """ |
| + text = str(text) |
| + raw_input('--------------------> ' + text.encode('utf-8')) |
| + |
| + def _OpenRoster(self): |
| + """Download Talk extension and open the roster.""" |
| + |
| + self.InstallGTalkExtension() |
| + |
| + # Wait for the background view to load. |
| + extension = self.GetGTalkExtensionInfo() |
| + background_view = self.WaitUntilExtensionViewLoaded( |
| + 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.
|
| + view_type = 'EXTENSION_BACKGROUND_PAGE') |
| + self.assertTrue(background_view, |
| + msg='Failed to get background view: views = %s.' % |
| + self.GetBrowserInfo()['extension_views']) |
| + |
| + # Wait for the custom QTest hook to load. |
| + self.WaitUntilResult(True, |
| + lambda: self.RunInBackground('Boolean(QTest)'), |
| + msg='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. |
|
Nirnimesh
2011/11/11 01:01:21
Reference crbug.com/97342
wud
2011/11/17 21:17:53
Done.
|
| + result = self.RunInBackground('QTest.handleBrowserAction()') |
| + self.assertEqual('ok', result, |
| + msg='Call to QTest.handleBrowserAction failed.') |
| + |
| + # Wait for viewer window to open. |
| + 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.
|
| + msg='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, |
| + msg='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]'), |
| + msg='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]'), |
| + msg='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())), |
| + msg='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])'), |
| + msg='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 GTalk.""" |
| + |
| + # 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])'), |
| + msg='Timed out waiting for roster container iframe') |
| + |
| + # Wait for the roster iframe. |
| + self.WaitUntilResult(True, |
| + lambda: self.RunInViewer('Boolean(window.frames[0])', '//iframe[1]'), |
| + msg='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, |
| + msg='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, |
| + msg='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"))'), |
| + msg='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) |
| + |
| + # 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())), |
| + msg='Timed out waiting for mole window to open') |
| + |
| + # Wait for chat mole to load. |
| + self.WaitUntilResult(True, |
| + lambda: self.RunInMole('Boolean(window.location.href)'), |
| + msg='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))'), |
| + msg='Timed out waiting for mole textarea') |
| + |
| + # Type /ping in the mole's input widget. |
| + self.assertTrue(self.RunInMole( |
| + '$Type($FindByTagName($BODY(), "textarea", 0), "/ping")'), |
| + msg='Error typing in mole textarea') |
| + |
| + # Type ENTER in the mole's input widget. |
| + self.assertTrue(self.RunInMole( |
| + '$Press($FindByTagName($BODY(),"textarea",0), $KEYS.ENTER)'), |
| + msg='Error sending ENTER in mole textarea') |
| + |
| + # Wait for chat input to clear. |
| + self.WaitUntilResult(True, |
| + lambda: self.RunInMole( |
| + 'Boolean($FindByTagName($BODY(),"textarea",0).value=="")'), |
| + msg='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, |
| + msg='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, |
| + msg='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")'), |
| + msg='Error typing "ping /7" in mole textarea') |
| + |
| + # Press Enter in chat input. |
| + self.assertTrue(self.RunInMole( |
| + '$Press($FindByTagName($BODY(),"textarea",0), $KEYS.ENTER)'), |
| + msg='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)'), |
| + msg='Error sending ESC after "ping /7" in mole textarea') |
| + |
| + # Wait for the mole to close. |
| + self.assertTrue(self.WaitUntil( |
| + lambda: not(bool(self.GetMoleInfo()))), |
| + msg='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"))'), |
| + msg='Timed out waiting for toast') |
| + |
| + # Wait for the toast body to exist. |
| + self.WaitUntilResult(True, |
| + lambda: self.RunInBackground('Boolean($BODY($VIEW("/toast.html")))'), |
| + msg='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!"))'), |
| + msg='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!"))'), |
| + msg='Error clicking "Ping!" in toast') |
| + |
| + # Wait for the mole to open. |
| + self.assertTrue(self.WaitUntil(lambda: bool(self.GetMoleInfo())), |
| + msg='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"))'), |
| + msg='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))), |
| + msg='Timed out waiting for second mole window to open') |
| + |
| + # Disable the extension. |
| + extension = self.GetGTalkExtensionInfo() |
| + self.SetExtensionStateById(extension['id'], enable=False, |
| + allow_in_incognito=False) |
| + extension = self.GetGTalkExtensionInfo() |
| + self.assertFalse(extension['is_enabled']) |
| + |
| + # Verify all moles + windows are closed. |
| + self.assertTrue(self.WaitUntil(lambda: not(bool(self.GetViewerInfo()))), |
| + msg='Timed out waiting for viewer.html to close after disabling') |
| + self.assertTrue(self.WaitUntil(lambda: not(bool(self.GetMoleInfo()))), |
| + msg='Timed out waiting for first mole to close after disabling') |
| + self.assertTrue(self.WaitUntil(lambda: not(bool(self.GetMoleInfo(1)))), |
| + msg='Timed out waiting for second mole to close after disabling') |
| + |
| + def testBasicFunctionality(self): |
| + """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.
|
| + |
| + tries = 0 |
| + RETRIES = 5 |
| + for tries in range(RETRIES): |
| + logging.info('Calling RunBasicFunctionalityTest. Try #{0}/{1}' |
| + .format(tries + 1, RETRIES)) |
| + try: |
| + self.RunBasicFunctionalityTest() |
| + logging.info('RunBasicFunctionalityTest succeeded. Tries: {0}' |
| + .format(tries + 1)) |
| + break |
| + except Exception as e: |
| + logging.info("\n*** ERROR in RunBasicFunctionalityTest ***") |
| + exc_type, exc_value, exc_traceback = sys.exc_info() |
| + traceback.print_exception(exc_type, exc_value, exc_traceback) |
| + logging.info("\n") |
| + if tries < RETRIES - 1: |
| + self.NavigateToURL('http://accounts.google.com/Logout') |
| + logging.info('Retring...') |
|
Nirnimesh
2011/11/11 01:01:21
Retrying
wud
2011/11/17 21:17:53
Done.
|
| + else: |
| + raise |
| + |
|
Nirnimesh
2011/11/11 01:01:21
leave another blank line here
wud
2011/11/17 21:17:53
Done.
|
| +if __name__ == '__main__': |
| + pyauto_gtalk.Main() |