Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6438)

Unified Diff: chrome/test/functional/quasar/test_basic.py

Issue 8477044: Introduce Pyauto tests for Quasar (Google Talk Extension). (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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()

Powered by Google App Engine
This is Rietveld 408576698