summaryrefslogtreecommitdiffstats
path: root/chrome/test/pyautolib
diff options
context:
space:
mode:
authornirnimesh@chromium.org <nirnimesh@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-23 17:14:01 +0000
committernirnimesh@chromium.org <nirnimesh@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-23 17:14:01 +0000
commit3f82de6e5ce07ebdb8490fb9cbffb6a0a02ae7a7 (patch)
tree08ed6e47882065879d99624c01348fa8f7f046e4 /chrome/test/pyautolib
parentf9204f0406b921905380f7e385bfdd41fb23a401 (diff)
downloadchromium_src-3f82de6e5ce07ebdb8490fb9cbffb6a0a02ae7a7.zip
chromium_src-3f82de6e5ce07ebdb8490fb9cbffb6a0a02ae7a7.tar.gz
chromium_src-3f82de6e5ce07ebdb8490fb9cbffb6a0a02ae7a7.tar.bz2
Fix PyAuto crash when a script has multiple tests.
This CL better maps C++ UITestSuite to python suite and C++ UITestBase to python testcase. All one-time initializations go in the suite while testcases are re-entrant now -- this is what fixes the crash. Also: - Cmdline flags to pyauto script (verbose, wait for attaching to debugger) - Establish the setup of sys.path, so that it's setup correctly and tests don't have to worry about it - Create facitlites for PYAUTO_TESTS files inside script dirs (say chrome/test/functional) which defines the tests to run. - Restructure such that pyauto scripts can be run standalone as well as using the pyauto.py script (like unittest.py). For example, a test could be fired in any of the below ways: # Run tests in a module ('bookmarks') python pyauto_functional.py bookmarks # Run tests in a test case ('bookmarks.BookmarksTest') python pyauto_functional.py bookmarks.BookmarksTest # Run a test ('bookmarks.BookmarksTest.testBasics') python pyauto_functional.py bookmarks.BookmarksTest.testBasics # Run directly from the test script python bookmarks.py python bookmarks.py bookmarks python bookmarks.py bookmarks.BookmarksTest python bookmarks.py bookmarks.BookmarksTest.testBasics BUG=32292 TEST=python chrome/test/functional/bookmarks.py Review URL: http://codereview.chromium.org/1126003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@42350 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/test/pyautolib')
-rw-r--r--chrome/test/pyautolib/PYAUTO_TESTS17
-rw-r--r--chrome/test/pyautolib/bookmark_model.py6
-rw-r--r--chrome/test/pyautolib/pyauto.py229
-rw-r--r--chrome/test/pyautolib/pyautolib.cc96
-rw-r--r--chrome/test/pyautolib/pyautolib.h29
-rw-r--r--chrome/test/pyautolib/pyautolib.i15
6 files changed, 319 insertions, 73 deletions
diff --git a/chrome/test/pyautolib/PYAUTO_TESTS b/chrome/test/pyautolib/PYAUTO_TESTS
new file mode 100644
index 0000000..dd43331
--- /dev/null
+++ b/chrome/test/pyautolib/PYAUTO_TESTS
@@ -0,0 +1,17 @@
+# Copyright (c) 2010 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.
+
+{
+ 'all': [
+ ],
+
+ 'win': [
+ ],
+
+ 'mac': [
+ ],
+
+ 'linux': [
+ ],
+}
diff --git a/chrome/test/pyautolib/bookmark_model.py b/chrome/test/pyautolib/bookmark_model.py
index cc43f73..e201ccf 100644
--- a/chrome/test/pyautolib/bookmark_model.py
+++ b/chrome/test/pyautolib/bookmark_model.py
@@ -9,13 +9,9 @@
Obtain one of these from PyUITestSuite::GetBookmarkModel() call.
"""
-# TODO(jrg): establish a standard path for pyauto tests.
-# This "adjustment" assumes we live in "src/chrome/test/pyautolib".
import os
-import sys
-sys.path.append(os.path.join(os.path.dirname(__file__), 'third_party'))
-
import simplejson as json
+import sys
class BookmarkModel(object):
diff --git a/chrome/test/pyautolib/pyauto.py b/chrome/test/pyautolib/pyauto.py
index 7ddca87..7f9efc8 100644
--- a/chrome/test/pyautolib/pyauto.py
+++ b/chrome/test/pyautolib/pyauto.py
@@ -11,16 +11,31 @@ For complete documentation on the functionality available,
run pydoc on this file.
Ref: http://dev.chromium.org/developers/pyauto
+
+
+Include the following in your PyAuto test script to make it run standalone.
+
+from pyauto import Main
+
+if __name__ == '__main__':
+ Main()
+
+This script can be used as an executable to fire off other scripts, similar
+to unittest.py
+ python pyauto.py test_script
"""
+import logging
+import optparse
import os
+import re
import sys
+import types
import unittest
-import bookmark_model
-
def _LocateBinDirs():
+ """Setup a few dirs where we expect to find dependency libraries."""
script_dir = os.path.dirname(__file__)
chrome_src = os.path.join(script_dir, os.pardir, os.pardir, os.pardir)
@@ -36,7 +51,10 @@ def _LocateBinDirs():
'cygwin': [ os.path.join(chrome_src, 'chrome', 'Debug'),
os.path.join(chrome_src, 'chrome', 'Release')],
}
- sys.path += bin_dirs.get(sys.platform, [])
+ deps_dirs = [ os.path.join(script_dir, os.pardir,
+ os.pardir, os.pardir, 'third_party'),
+ ]
+ sys.path += bin_dirs.get(sys.platform, []) + deps_dirs
_LocateBinDirs()
@@ -49,15 +67,18 @@ except ImportError:
print >>sys.stderr, "Could not locate built libraries. Did you build?"
raise
+# Should go after sys.path is set appropriately
+import bookmark_model
+
-class PyUITest(pyautolib.PyUITestSuite, unittest.TestCase):
+class PyUITest(pyautolib.PyUITestBase, unittest.TestCase):
"""Base class for UI Test Cases in Python.
A browser is created before executing each test, and is destroyed after
each test irrespective of whether the test passed or failed.
You should derive from this class and create methods with 'test' prefix,
- and use methods inherited from PyUITestSuite (the C++ side).
+ and use methods inherited from PyUITestBase (the C++ side).
Example:
@@ -65,7 +86,7 @@ class PyUITest(pyautolib.PyUITestSuite, unittest.TestCase):
def testNavigation(self):
self.NavigateToURL("http://www.google.com")
- self.assertTrue("Google" == self.GetActiveTabTitle())
+ self.assertEqual("Google", self.GetActiveTabTitle())
"""
def __init__(self, methodName='runTest', **kwargs):
@@ -73,7 +94,7 @@ class PyUITest(pyautolib.PyUITestSuite, unittest.TestCase):
When redefining __init__ in a derived class, make sure that:
o you make a call this __init__
- o __init__ takes methodName as a arg. this is mandated by unittest module
+ o __init__ takes methodName as an arg. this is mandated by unittest module
Args:
methodName: the default method name. Internal use by unittest module
@@ -81,37 +102,32 @@ class PyUITest(pyautolib.PyUITestSuite, unittest.TestCase):
(The rest of the args can be in any order. They can even be skipped in
which case the defaults will be used.)
- extra_chrome_flags: additional flags to pass when launching chrome.
- Defaults to None
clear_profile: If True, clean the profile dir before use. Defaults to True
homepage: the home page. Defaults to "about:blank"
"""
# Fetch provided keyword args, or fill in defaults.
- extra_chrome_flags = kwargs.get('extra_chrome_flags')
clear_profile = kwargs.get('clear_profile', True)
homepage = kwargs.get('homepage', 'about:blank')
- args = sys.argv
- if extra_chrome_flags:
- args.append('--extra-chrome-flags=%s' % extra_chrome_flags)
- pyautolib.PyUITestSuite.__init__(self, args, clear_profile, homepage)
+ pyautolib.PyUITestBase.__init__(self, clear_profile, homepage)
# Figure out path to chromium binaries
browser_dir = os.path.normpath(os.path.dirname(pyautolib.__file__))
- os.environ['PATH'] = browser_dir + os.pathsep + os.environ['PATH']
self.Initialize(pyautolib.FilePath(browser_dir))
unittest.TestCase.__init__(self, methodName)
def __del__(self):
- pyautolib.PyUITestSuite.__del__(self)
+ pyautolib.PyUITestBase.__del__(self)
- def run(self, result=None):
- """The main run method.
+ def setUp(self):
+ """Override this method to launch browser differently.
- We override this method to make calls to the setup steps in PyUITestSuite.
+ Can be used to prevent launching the browser window by default in case a
+ test wants to do some additional setup before firing browser.
"""
- self.SetUp() # Open a browser window
- unittest.TestCase.run(self, result)
- self.TearDown() # Destroy the browser window
+ self.SetUp() # Fire browser
+
+ def tearDown(self):
+ self.TearDown() # Destroy browser
def GetBookmarkModel(self):
"""Return the bookmark model as a BookmarkModel object.
@@ -120,3 +136,172 @@ class PyUITest(pyautolib.PyUITestSuite, unittest.TestCase):
does not get updated as the bookmark model changes.
"""
return bookmark_model.BookmarkModel(self._GetBookmarksAsJSON())
+
+
+class PyUITestSuite(pyautolib.PyUITestSuiteBase, unittest.TestSuite):
+ """Base TestSuite for PyAuto UI tests."""
+
+ def __init__(self, args):
+ pyautolib.PyUITestSuiteBase.__init__(self, args)
+
+ # Figure out path to chromium binaries
+ browser_dir = os.path.normpath(os.path.dirname(pyautolib.__file__))
+ logging.debug('Loading pyauto libs from %s', browser_dir)
+ self.Initialize(pyautolib.FilePath(browser_dir))
+ os.environ['PATH'] = browser_dir + os.pathsep + os.environ['PATH']
+
+ unittest.TestSuite.__init__(self)
+
+ def __del__(self):
+ # python unittest module is setup such that the suite gets deleted before
+ # the test cases, which is odd because our test cases depend on
+ # initializtions like exitmanager, autorelease pool provided by the
+ # suite. Forcibly delete the test cases before the suite.
+ del self._tests
+ pyautolib.PyUITestSuiteBase.__del__(self)
+
+
+# Implementation inspired from unittest.main()
+class Main(object):
+ """Main program for running PyAuto tests."""
+
+ _options, _args = None, None
+ _tests_filename = 'PYAUTO_TESTS'
+ _platform_map = {
+ 'win32': 'win',
+ 'darwin': 'mac',
+ 'linux2': 'linux',
+ }
+
+ def __init__(self):
+ self._ParseArgs()
+ self._Run()
+
+ def _ParseArgs(self):
+ """Parse command line args."""
+ parser = optparse.OptionParser()
+ parser.add_option(
+ '-v', '--verbose', action='store_true', default=False,
+ help='Make PyAuto verbose.')
+ parser.add_option(
+ '-D', '--wait-for-debugger', action='store_true', default=False,
+ help='Block PyAuto on startup for attaching debugger.')
+ parser.add_option(
+ '', '--ui-test-flags', type='string', default='',
+ help='Flags passed to the UI test suite. Refer ui_test.h for options')
+ parser.add_option(
+ '', '--list-missing-tests', action='store_true', default=False,
+ help='Print a list of tests not included in PYAUTO_TESTS, and exit')
+
+ self._options, self._args = parser.parse_args()
+
+ # Setup logging
+ if self._options.verbose:
+ logging.basicConfig(level=logging.DEBUG,
+ format='%(asctime)s %(levelname)-8s %(message)s')
+ if self._options.list_missing_tests:
+ self._ListMissingTests()
+ sys.exit(0)
+
+ def TestsDir(self):
+ """Returns the path to dir containing tests.
+
+ This is typically the dir containing the tests description file.
+ This method should be overridden by derived class to point to other dirs
+ if needed.
+ """
+ return os.path.dirname(__file__)
+
+ def _ListMissingTests(self):
+ """Print tests missing from PYAUTO_TESTS."""
+ def _GetTestsFrom(module_string):
+ try:
+ module = __import__(module_string)
+ except ImportError: # Probably just a test script
+ return [module_string]
+ tests = []
+ for name in dir(module):
+ obj = getattr(module, name)
+ if (isinstance(obj, (type, types.ClassType)) and
+ issubclass(obj, PyUITest) and obj != PyUITest):
+ tests += [module_string + "." + obj.__name__ + "." + x for x in \
+ filter(lambda x: x.startswith('test'), dir(obj))]
+ return tests
+ # Fetch tests from all test scripts
+ all_test_files = filter(lambda x: x.endswith('.py'),
+ os.listdir(self.TestsDir()))
+ all_tests_modules = [os.path.splitext(x)[0] for x in all_test_files]
+ all_tests = reduce(lambda x, y: x + y,
+ map(_GetTestsFrom, all_tests_modules))
+ # Fetch tests included by PYAUTO_TESTS
+ pyauto_tests_file = os.path.join(self.TestsDir(), self._tests_filename)
+ pyauto_tests = reduce(lambda x, y: x + y,
+ map(_GetTestsFrom,
+ self._GetTestNamesFrom(pyauto_tests_file)))
+ for a_test in all_tests:
+ if a_test not in pyauto_tests:
+ print a_test
+
+ def _HasTestCases(self, module_string):
+ """Determines if we have any PyUITest test case classes in the module
+ identified by |module_string|."""
+ module = __import__(module_string)
+ for name in dir(module):
+ obj = getattr(module, name)
+ if (isinstance(obj, (type, types.ClassType)) and
+ issubclass(obj, PyUITest)):
+ return True
+ return False
+
+ def _LoadTests(self, args):
+ """Returns a suite of tests loaded from the given args.
+
+ The given args can be either a module (ex: module1) or a testcase
+ (ex: module2.MyTestCase) or a test (ex: module1.MyTestCase.testX)
+ If empty, the tests in the already imported modules are loaded.
+
+ Args:
+ args: [module1, module2, module3.testcase, module4.testcase.testX]
+ These modules or test cases or tests should be importable
+ """
+ if not args: # Load tests ourselves
+ if self._HasTestCases('__main__'): # we are running a test script
+ args.append('__main__') # run the test cases found in it
+ else: # run tests from the test description file
+ pyauto_tests_file = os.path.join(self.TestsDir(), self._tests_filename)
+ logging.debug("Reading %s", pyauto_tests_file)
+ if not os.path.exists(pyauto_tests_file):
+ logging.warn("%s missing. Cannot load tests." % pyauto_tests_file)
+ else:
+ args = self._GetTestNamesFrom(pyauto_tests_file)
+ logging.debug("Loading tests from %s", args)
+ loaded_tests = unittest.defaultTestLoader.loadTestsFromNames(args)
+ return loaded_tests
+
+ def _GetTestNamesFrom(self, filename):
+ contents = open(filename).read()
+ modules = eval(contents, {'__builtins__': None}, None)
+ args = modules.get('all', []) + \
+ modules.get(self._platform_map[sys.platform], [])
+ return args
+
+ def _Run(self):
+ """Run the tests."""
+ if self._options.wait_for_debugger:
+ raw_input('Attach debugger to process %s and hit <enter> ' % os.getpid())
+
+ pyauto_suite = PyUITestSuite(re.split('\s+', self._options.ui_test_flags))
+ loaded_tests = self._LoadTests(self._args)
+ pyauto_suite.addTests(loaded_tests)
+ verbosity = 1
+ if self._options.verbose:
+ verbosity = 2
+ result = unittest.TextTestRunner(verbosity=verbosity).run(pyauto_suite)
+ del loaded_tests # Need to destroy test cases before the suite
+ del pyauto_suite
+ sys.exit(not result.wasSuccessful())
+
+
+if __name__ == '__main__':
+ Main()
+
diff --git a/chrome/test/pyautolib/pyautolib.cc b/chrome/test/pyautolib/pyautolib.cc
index 14e0c8e..a26b8eb 100644
--- a/chrome/test/pyautolib/pyautolib.cc
+++ b/chrome/test/pyautolib/pyautolib.cc
@@ -9,56 +9,80 @@
#include "chrome/test/pyautolib/pyautolib.h"
#include "googleurl/src/gurl.h"
-PyUITestSuite::PyUITestSuite(
- int argc, char** argv, bool clear_profile, std::wstring homepage)
- : UITestSuite(argc, argv),
- UITestBase() {
+
+// PyUITestSuiteBase
+PyUITestSuiteBase::PyUITestSuiteBase(int argc, char** argv)
+ : UITestSuite(argc, argv) {
+}
+
+PyUITestSuiteBase::~PyUITestSuiteBase() {
+ pool_.Recycle();
+ Shutdown();
+}
+
+void PyUITestSuiteBase::Initialize(const FilePath& browser_dir) {
+ SetBrowserDirectory(browser_dir);
+ UITestSuite::Initialize();
+}
+
+// PyUITestBase
+PyUITestBase::PyUITestBase(bool clear_profile, std::wstring homepage)
+ : UITestBase() {
set_clear_profile(clear_profile);
set_homepage(homepage);
+ message_loop_ = GetSharedMessageLoop(MessageLoop::TYPE_DEFAULT);
+}
+
+PyUITestBase::~PyUITestBase() {
}
-PyUITestSuite::~PyUITestSuite() {
- UITestSuite::Shutdown();
+// static, refer .h for why it needs to be static
+MessageLoop* PyUITestBase::message_loop_ = NULL;
+
+// static
+MessageLoop* PyUITestBase::GetSharedMessageLoop(
+ MessageLoop::Type msg_loop_type) {
+ if (!message_loop_) // Create a shared instance of MessageLoop
+ message_loop_ = new MessageLoop(msg_loop_type);
+ return message_loop_;
}
-void PyUITestSuite::Initialize(const FilePath& browser_dir) {
- UITestSuite::SetBrowserDirectory(browser_dir);
+void PyUITestBase::Initialize(const FilePath& browser_dir) {
UITestBase::SetBrowserDirectory(browser_dir);
- UITestSuite::Initialize();
}
-void PyUITestSuite::SetUp() {
+void PyUITestBase::SetUp() {
UITestBase::SetUp();
}
-void PyUITestSuite::TearDown() {
+void PyUITestBase::TearDown() {
UITestBase::TearDown();
}
-void PyUITestSuite::NavigateToURL(const char* url_string) {
+void PyUITestBase::NavigateToURL(const char* url_string) {
GURL url(url_string);
UITestBase::NavigateToURL(url);
}
-void PyUITestSuite::NavigateToURL(
+void PyUITestBase::NavigateToURL(
const char* url_string, int window_index, int tab_index) {
GURL url(url_string);
UITestBase::NavigateToURL(url, window_index, tab_index);
}
-bool PyUITestSuite::AppendTab(const GURL& tab_url, int window_index) {
+bool PyUITestBase::AppendTab(const GURL& tab_url, int window_index) {
scoped_refptr<BrowserProxy> browser_proxy =
automation()->GetBrowserWindow(window_index);
return browser_proxy->AppendTab(tab_url);
}
-bool PyUITestSuite::ApplyAccelerator(int id, int window_index) {
+bool PyUITestBase::ApplyAccelerator(int id, int window_index) {
scoped_refptr<BrowserProxy> browser_proxy =
automation()->GetBrowserWindow(window_index);
return browser_proxy->ApplyAccelerator(id);
}
-bool PyUITestSuite::RunCommand(int browser_command, int window_index){
+bool PyUITestBase::RunCommand(int browser_command, int window_index) {
scoped_refptr<BrowserProxy> browser_proxy =
automation()->GetBrowserWindow(window_index);
EXPECT_TRUE(browser_proxy.get());
@@ -67,20 +91,20 @@ bool PyUITestSuite::RunCommand(int browser_command, int window_index){
return browser_proxy->RunCommand(browser_command);
}
-bool PyUITestSuite::ActivateTab(int tab_index, int window_index) {
+bool PyUITestBase::ActivateTab(int tab_index, int window_index) {
scoped_refptr<BrowserProxy> browser_proxy =
automation()->GetBrowserWindow(window_index);
return browser_proxy->ActivateTab(tab_index);
}
-void PyUITestSuite::SetDownloadShelfVisible(bool is_visible, int window_index) {
+void PyUITestBase::SetDownloadShelfVisible(bool is_visible, int window_index) {
scoped_refptr<BrowserProxy> browser_proxy =
automation()->GetBrowserWindow(window_index);
ASSERT_TRUE(browser_proxy.get());
EXPECT_TRUE(browser_proxy->SetShelfVisible(is_visible));
}
-bool PyUITestSuite::IsDownloadShelfVisible(int window_index) {
+bool PyUITestBase::IsDownloadShelfVisible(int window_index) {
scoped_refptr<BrowserProxy> browser_proxy =
automation()->GetBrowserWindow(window_index);
EXPECT_TRUE(browser_proxy.get());
@@ -91,22 +115,22 @@ bool PyUITestSuite::IsDownloadShelfVisible(int window_index) {
return visible;
}
-int PyUITestSuite::GetTabCount(int window_index) {
+int PyUITestBase::GetTabCount(int window_index) {
return UITestBase::GetTabCount(window_index);
}
-GURL PyUITestSuite::GetActiveTabURL(int window_index) {
+GURL PyUITestBase::GetActiveTabURL(int window_index) {
return UITestBase::GetActiveTabURL(window_index);
}
-void PyUITestSuite::OpenFindInPage(int window_index) {
+void PyUITestBase::OpenFindInPage(int window_index) {
scoped_refptr<BrowserProxy> browser_proxy =
automation()->GetBrowserWindow(window_index);
ASSERT_TRUE(browser_proxy.get());
EXPECT_TRUE(browser_proxy->OpenFindInPage());
}
-bool PyUITestSuite::IsFindInPageVisible(int window_index) {
+bool PyUITestBase::IsFindInPageVisible(int window_index) {
scoped_refptr<BrowserProxy> browser_proxy =
automation()->GetBrowserWindow(window_index);
EXPECT_TRUE(browser_proxy.get());
@@ -117,7 +141,7 @@ bool PyUITestSuite::IsFindInPageVisible(int window_index) {
return is_visible;
}
-FilePath PyUITestSuite::GetDownloadDirectory() {
+FilePath PyUITestBase::GetDownloadDirectory() {
FilePath download_dir;
scoped_refptr<TabProxy> tab_proxy(GetActiveTab());
EXPECT_TRUE(tab_proxy.get());
@@ -127,15 +151,15 @@ FilePath PyUITestSuite::GetDownloadDirectory() {
return download_dir;
}
-bool PyUITestSuite::OpenNewBrowserWindow(bool show) {
+bool PyUITestBase::OpenNewBrowserWindow(bool show) {
return automation()->OpenNewBrowserWindow(Browser::TYPE_NORMAL, show);
}
-bool PyUITestSuite::InstallExtension(const FilePath& crx_file) {
+bool PyUITestBase::InstallExtension(const FilePath& crx_file) {
return automation()->InstallExtension(crx_file);
}
-bool PyUITestSuite::GetBookmarkBarVisibility() {
+bool PyUITestBase::GetBookmarkBarVisibility() {
scoped_refptr<BrowserProxy> browser_proxy =
automation()->GetBrowserWindow(0); // Window doesn't matter.
EXPECT_TRUE(browser_proxy.get());
@@ -148,7 +172,7 @@ bool PyUITestSuite::GetBookmarkBarVisibility() {
return visible;
}
-bool PyUITestSuite::WaitForBookmarkBarVisibilityChange(bool wait_for_open) {
+bool PyUITestBase::WaitForBookmarkBarVisibilityChange(bool wait_for_open) {
scoped_refptr<BrowserProxy> browser_proxy =
automation()->GetBrowserWindow(0); // Window doesn't matter.
EXPECT_TRUE(browser_proxy.get());
@@ -163,7 +187,7 @@ bool PyUITestSuite::WaitForBookmarkBarVisibilityChange(bool wait_for_open) {
return completed;
}
-std::string PyUITestSuite::_GetBookmarksAsJSON() {
+std::string PyUITestBase::_GetBookmarksAsJSON() {
scoped_refptr<BrowserProxy> browser_proxy =
automation()->GetBrowserWindow(0); // Window doesn't matter.
EXPECT_TRUE(browser_proxy.get());
@@ -175,7 +199,7 @@ std::string PyUITestSuite::_GetBookmarksAsJSON() {
return s;
}
-bool PyUITestSuite::AddBookmarkGroup(std::wstring& parent_id, int index,
+bool PyUITestBase::AddBookmarkGroup(std::wstring& parent_id, int index,
std::wstring& title) {
scoped_refptr<BrowserProxy> browser_proxy =
automation()->GetBrowserWindow(0); // Window doesn't matter.
@@ -187,7 +211,7 @@ bool PyUITestSuite::AddBookmarkGroup(std::wstring& parent_id, int index,
index, title);
}
-bool PyUITestSuite::AddBookmarkURL(std::wstring& parent_id, int index,
+bool PyUITestBase::AddBookmarkURL(std::wstring& parent_id, int index,
std::wstring& title, std::wstring& url) {
scoped_refptr<BrowserProxy> browser_proxy =
automation()->GetBrowserWindow(0); // Window doesn't matter.
@@ -200,8 +224,8 @@ bool PyUITestSuite::AddBookmarkURL(std::wstring& parent_id, int index,
GURL(WideToUTF16(url)));
}
-bool PyUITestSuite::ReparentBookmark(std::wstring& id, std::wstring& new_parent_id,
- int index) {
+bool PyUITestBase::ReparentBookmark(
+ std::wstring& id, std::wstring& new_parent_id, int index) {
scoped_refptr<BrowserProxy> browser_proxy =
automation()->GetBrowserWindow(0); // Window doesn't matter.
EXPECT_TRUE(browser_proxy.get());
@@ -214,7 +238,7 @@ bool PyUITestSuite::ReparentBookmark(std::wstring& id, std::wstring& new_parent_
index);
}
-bool PyUITestSuite::SetBookmarkTitle(std::wstring& id, std::wstring& title) {
+bool PyUITestBase::SetBookmarkTitle(std::wstring& id, std::wstring& title) {
scoped_refptr<BrowserProxy> browser_proxy =
automation()->GetBrowserWindow(0); // Window doesn't matter.
EXPECT_TRUE(browser_proxy.get());
@@ -225,7 +249,7 @@ bool PyUITestSuite::SetBookmarkTitle(std::wstring& id, std::wstring& title) {
title);
}
-bool PyUITestSuite::SetBookmarkURL(std::wstring& id, std::wstring& url) {
+bool PyUITestBase::SetBookmarkURL(std::wstring& id, std::wstring& url) {
scoped_refptr<BrowserProxy> browser_proxy =
automation()->GetBrowserWindow(0); // Window doesn't matter.
EXPECT_TRUE(browser_proxy.get());
@@ -236,7 +260,7 @@ bool PyUITestSuite::SetBookmarkURL(std::wstring& id, std::wstring& url) {
GURL(WideToUTF16(url)));
}
-bool PyUITestSuite::RemoveBookmark(std::wstring& id) {
+bool PyUITestBase::RemoveBookmark(std::wstring& id) {
scoped_refptr<BrowserProxy> browser_proxy =
automation()->GetBrowserWindow(0); // Window doesn't matter.
EXPECT_TRUE(browser_proxy.get());
diff --git a/chrome/test/pyautolib/pyautolib.h b/chrome/test/pyautolib/pyautolib.h
index 7e87171..2d14834 100644
--- a/chrome/test/pyautolib/pyautolib.h
+++ b/chrome/test/pyautolib/pyautolib.h
@@ -8,6 +8,7 @@
#ifndef CHROME_TEST_PYAUTOLIB_PYAUTOLIB_H_
#define CHROME_TEST_PYAUTOLIB_PYAUTOLIB_H_
+#include "base/message_loop.h"
#include "base/scoped_nsautorelease_pool.h"
#include "chrome/test/ui/ui_test.h"
#include "chrome/test/ui/ui_test_suite.h"
@@ -19,19 +20,27 @@
// all methods in python just for the sake of providing default args. This
// seems cumbersome and unwanted.
-// TODO(nirnimesh): separate out the UITestSuite and UITestBase parts
-// crbug.com/32292
+// Test Suite for Pyauto tests. All one-time initializations go here.
+class PyUITestSuiteBase : public UITestSuite {
+ public:
+ PyUITestSuiteBase(int argc, char** argv);
+ ~PyUITestSuiteBase();
+
+ void Initialize(const FilePath& browser_dir);
+
+ private:
+ base::ScopedNSAutoreleasePool pool_;
+};
// The primary class that interfaces with Automation Proxy.
// This class is accessed from python using swig.
-class PyUITestSuite : public UITestSuite, public UITestBase {
+class PyUITestBase : public UITestBase {
public:
// Only public methods are accessible from swig.
// Constructor. Lookup pyauto.py for doc on these args.
- PyUITestSuite(int argc, char** argv, bool clear_profile,
- std::wstring homepage);
- ~PyUITestSuite();
+ PyUITestBase(bool clear_profile, std::wstring homepage);
+ ~PyUITestBase();
// Initialize the setup. Should be called before launching the browser.
// |browser_dir| is the path to dir containing chromium binaries.
@@ -128,7 +137,13 @@ class PyUITestSuite : public UITestSuite, public UITestBase {
bool RemoveBookmark(std::wstring& id);
private:
- base::ScopedNSAutoreleasePool pool_;
+ // Enables PostTask to main thread.
+ // Should be shared across multiple instances of PyUITestBase so that this
+ // class is re-entrant and multiple instances can be created.
+ // This is necessary since python's unittest module creates instances of
+ // TestCase at load time itself.
+ static MessageLoop* GetSharedMessageLoop(MessageLoop::Type msg_loop_type);
+ static MessageLoop* message_loop_;
};
#endif // CHROME_TEST_PYAUTOLIB_PYAUTOLIB_H_
diff --git a/chrome/test/pyautolib/pyautolib.i b/chrome/test/pyautolib/pyautolib.i
index 51755bb..009832a 100644
--- a/chrome/test/pyautolib/pyautolib.i
+++ b/chrome/test/pyautolib/pyautolib.i
@@ -77,10 +77,19 @@ class FilePath {
explicit FilePath(const StringType& path);
};
-class PyUITestSuite {
+class PyUITestSuiteBase {
public:
- PyUITestSuite(int argc, char** argv, bool clear_profile,
- std::wstring homepage);
+ %feature("docstring", "Create the suite.") PyUITestSuiteBase;
+ PyUITestSuiteBase(int argc, char** argv);
+ ~PyUITestSuiteBase();
+
+ %feature("docstring", "Initialize from the path to browser dir.") Initialize;
+ void Initialize(const FilePath& browser_dir);
+};
+
+class PyUITestBase {
+ public:
+ PyUITestBase(bool clear_profile, std::wstring homepage);
%feature("docstring", "Initialize the entire setup. Should be called "
"before launching the browser. For internal use.") Initialize;