diff options
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/automation/automation_provider_observers.cc | 51 | ||||
-rw-r--r-- | chrome/browser/automation/automation_provider_observers.h | 23 | ||||
-rw-r--r-- | chrome/browser/automation/testing_automation_provider.cc | 44 | ||||
-rw-r--r-- | chrome/browser/automation/testing_automation_provider.h | 4 | ||||
-rw-r--r-- | chrome/test/functional/PYAUTO_TESTS | 9 | ||||
-rwxr-xr-x | chrome/test/functional/bookmarks.py | 224 | ||||
-rwxr-xr-x | chrome/test/functional/imports.py | 67 | ||||
-rwxr-xr-x | chrome/test/pyautolib/pyauto.py | 41 | ||||
-rw-r--r-- | chrome/test/pyautolib/pyautolib.cc | 65 | ||||
-rw-r--r-- | chrome/test/pyautolib/pyautolib.h | 22 | ||||
-rw-r--r-- | chrome/test/pyautolib/pyautolib.i | 45 |
11 files changed, 522 insertions, 73 deletions
diff --git a/chrome/browser/automation/automation_provider_observers.cc b/chrome/browser/automation/automation_provider_observers.cc index cf18d7b..c7a494a 100644 --- a/chrome/browser/automation/automation_provider_observers.cc +++ b/chrome/browser/automation/automation_provider_observers.cc @@ -3049,3 +3049,54 @@ void WindowMaximizedObserver::Observe( } #endif // defined(OS_LINUX) +BrowserOpenedWithExistingProfileNotificationObserver:: + BrowserOpenedWithExistingProfileNotificationObserver( + AutomationProvider* automation, + IPC::Message* reply_message, + int num_loads) + : automation_(automation->AsWeakPtr()), + reply_message_(reply_message), + new_window_id_(extension_misc::kUnknownWindowId), + num_loads_(num_loads) { + registrar_.Add(this, chrome::NOTIFICATION_BROWSER_OPENED, + content::NotificationService::AllBrowserContextsAndSources()); + registrar_.Add(this, content::NOTIFICATION_LOAD_STOP, + content::NotificationService::AllBrowserContextsAndSources()); +} + +BrowserOpenedWithExistingProfileNotificationObserver:: + ~BrowserOpenedWithExistingProfileNotificationObserver() { +} + +void BrowserOpenedWithExistingProfileNotificationObserver::Observe( + int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) { + if (!automation_) { + delete this; + return; + } + + if (type == chrome::NOTIFICATION_BROWSER_OPENED) { + // Store the new browser ID and continue waiting for NOTIFICATION_LOAD_STOP. + new_window_id_ = ExtensionTabUtil::GetWindowId( + content::Source<Browser>(source).ptr()); + } else if (type == content::NOTIFICATION_LOAD_STOP) { + // Only consider if the loaded tab is in the new window. + NavigationController* controller = + content::Source<NavigationController>(source).ptr(); + TabContents* tab = TabContents::FromWebContents( + controller->GetWebContents()); + int window_id = tab ? tab->restore_tab_helper()->window_id().id() : -1; + if (window_id == new_window_id_ && --num_loads_ == 0) { + if (automation_) { + AutomationJSONReply(automation_, reply_message_.release()) + .SendSuccess(NULL); + } + delete this; + } + } else { + NOTREACHED(); + } +} + diff --git a/chrome/browser/automation/automation_provider_observers.h b/chrome/browser/automation/automation_provider_observers.h index 12d80f2..d5e31db 100644 --- a/chrome/browser/automation/automation_provider_observers.h +++ b/chrome/browser/automation/automation_provider_observers.h @@ -1952,6 +1952,29 @@ class WindowMaximizedObserver : public content::NotificationObserver { }; #endif // defined(OS_LINUX) +// Wait for a new browser window to get created (for an existing profile). +// Useful when reopening a multi-profile window. +class BrowserOpenedWithExistingProfileNotificationObserver + : public content::NotificationObserver { + public: + BrowserOpenedWithExistingProfileNotificationObserver( + AutomationProvider* automation, + IPC::Message* reply_message, + int num_loads); + virtual ~BrowserOpenedWithExistingProfileNotificationObserver(); + virtual void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details); + private: + content::NotificationRegistrar registrar_; + base::WeakPtr<AutomationProvider> automation_; + scoped_ptr<IPC::Message> reply_message_; + int new_window_id_; + int num_loads_; + + DISALLOW_COPY_AND_ASSIGN( + BrowserOpenedWithExistingProfileNotificationObserver); +}; #endif // CHROME_BROWSER_AUTOMATION_AUTOMATION_PROVIDER_OBSERVERS_H_ diff --git a/chrome/browser/automation/testing_automation_provider.cc b/chrome/browser/automation/testing_automation_provider.cc index 509ff8f..fd51fcd 100644 --- a/chrome/browser/automation/testing_automation_provider.cc +++ b/chrome/browser/automation/testing_automation_provider.cc @@ -115,6 +115,7 @@ #include "chrome/browser/ui/omnibox/omnibox_view.h" #include "chrome/browser/ui/search_engines/keyword_editor_controller.h" #include "chrome/browser/ui/tab_contents/tab_contents.h" +#include "chrome/browser/ui/startup/startup_types.h" #include "chrome/browser/view_type_utils.h" #include "chrome/common/automation_constants.h" #include "chrome/common/automation_events.h" @@ -1201,6 +1202,47 @@ void TestingAutomationProvider::OpenNewBrowserWindowOfType( browser->window()->Show(); } +void TestingAutomationProvider::OpenProfileWindow( + base::DictionaryValue* args, IPC::Message* reply_message) { + ProfileManager* profile_manager = g_browser_process->profile_manager(); + FilePath::StringType path; + if (!args->GetString("path", &path)) { + AutomationJSONReply(this, reply_message).SendError( + "Invalid or missing arg: 'path'"); + return; + } + Profile* profile = profile_manager->GetProfileByPath(FilePath(path)); + if (!profile) { + AutomationJSONReply(this, reply_message).SendError( + StringPrintf("Invalid profile path: %s", path.c_str())); + return; + } + int num_loads; + if (!args->GetInteger("num_loads", &num_loads)) { + AutomationJSONReply(this, reply_message).SendError( + "Invalid or missing arg: 'num_loads'"); + return; + } + Browser* browser = browser::FindTabbedBrowser(profile, false); + if (browser) { + // Already have browser. Need to just activate. + ProfileManager::FindOrCreateNewWindowForProfile( + profile, + browser::startup::IS_NOT_PROCESS_STARTUP, + browser::startup::IS_NOT_FIRST_RUN, + 0); + AutomationJSONReply(this, reply_message).SendSuccess(NULL); + } else { + new BrowserOpenedWithExistingProfileNotificationObserver( + this, reply_message, num_loads); + ProfileManager::FindOrCreateNewWindowForProfile( + profile, + browser::startup::IS_NOT_PROCESS_STARTUP, + browser::startup::IS_NOT_FIRST_RUN, + 0); + } +} + void TestingAutomationProvider::GetWindowForBrowser(int browser_handle, bool* success, int* handle) { @@ -1742,6 +1784,8 @@ void TestingAutomationProvider::SendJSONRequest(int handle, &TestingAutomationProvider::OpenNewBrowserWindowWithNewProfile; handler_map["GetMultiProfileInfo"] = &TestingAutomationProvider::GetMultiProfileInfo; + handler_map["OpenProfileWindow"] = + &TestingAutomationProvider::OpenProfileWindow; handler_map["GetProcessInfo"] = &TestingAutomationProvider::GetProcessInfo; handler_map["GetPolicyDefinitionList"] = diff --git a/chrome/browser/automation/testing_automation_provider.h b/chrome/browser/automation/testing_automation_provider.h index ebe1154..a723303 100644 --- a/chrome/browser/automation/testing_automation_provider.h +++ b/chrome/browser/automation/testing_automation_provider.h @@ -298,6 +298,10 @@ class TestingAutomationProvider : public AutomationProvider, void GetMultiProfileInfo( base::DictionaryValue* args, IPC::Message* reply_message); + // Open a new browser window for an existing profile. + // Uses the JSON interface for input/output. + void OpenProfileWindow( + base::DictionaryValue* args, IPC::Message* reply_message); // Get info about the chromium/chrome in use. // This includes things like version, executable name, executable path. diff --git a/chrome/test/functional/PYAUTO_TESTS b/chrome/test/functional/PYAUTO_TESTS index deb8763..3a26892 100644 --- a/chrome/test/functional/PYAUTO_TESTS +++ b/chrome/test/functional/PYAUTO_TESTS @@ -307,8 +307,15 @@ # So one-click infobar tests do tno apply to chromeos. '-infobars.OneClickInfobarTest', # Multi-profile doesn't apply to chromeos yet. + '-bookmarks.BookmarksTest.testAddBookmarkInMultiProfile', + '-bookmarks.BookmarksTest.testRemoveBookmarksInMultiProfile', + '-bookmarks.BookmarksTest.testEditBookmarksInMultiProfile', + '-bookmarks.BookmarksTest.testAddBookmarksInMultiProfileIncognito', + '-bookmarks.BookmarksTest.testRemoveBookmarksInMultiProfileIncognito', + '-bookmarks.BookmarksTest.testEditBookmarksInMultiProfileIncognito', + '-bookmarks.BookmarksTest.testSearchBookmarksInMultiProfile', '-multiprofile', - '-ntp.NTPTest.testDifferentProfileNotAppearInMostVisited', + '-ntp.NTPTest.testDifferentProfileNotAppearInMostVisited', # These require a custom setup on ChromeOS and have their own suite for # this platform. '-policy', diff --git a/chrome/test/functional/bookmarks.py b/chrome/test/functional/bookmarks.py index a3ee157..25d660a 100755 --- a/chrome/test/functional/bookmarks.py +++ b/chrome/test/functional/bookmarks.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (c) 2011 The Chromium Authors. All rights reserved. +# Copyright (c) 2012 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. @@ -476,6 +476,228 @@ class BookmarksTest(pyauto.PyUITest): lambda: self.FindInPage('GoogleNews', tab_index=0)['match_count'], expect_retval=1)) + def _AddBookmark(self, keyword, url, windex=0): + """Add Bookmark to the page and verify if it is added. + + Args: + keyword: Name for bookmarked url. + url: URL of the page to be bookmarked. + windex: The window index, default is 0. + """ + bookmarks = self.GetBookmarkModel(windex) + bar_id = bookmarks.BookmarkBar()['id'] + self.AddBookmarkURL(bar_id, 0, keyword, url, windex) + self.assertTrue(self.GetBookmarkModel(windex)) + + def _GetProfilePath(self): + """Get profile paths when multiprofile windows are open. + + Returns: + profile: Path for multiprofiles(Default, Profile1, Profile2). + """ + profiles_list = self.GetMultiProfileInfo()['profiles'] + profile1_path = profile2_path = default_path = None + for profile in profiles_list: + if 'Profile 1' in profile['path']: + profile1_path = profile['path'] + elif 'Profile 2' in profile['path']: + profile2_path = profile['path'] + elif 'Default' in profile['path']: + default_path = profile['path'] + return default_path, profile1_path, profile2_path + + def _AssertBookmark(self, keyword, url, windex=0): + """Assert bookmark present. + + Args: + keyword: Name for bookmarked url. + url: URL of the page to be bookmarked. + windex: The window index, default is 0. + """ + bookmarks = self.GetBookmarkModel(windex) + node = bookmarks.FindByTitle(keyword) + self.assertEqual(1, len(node)) + self._VerifyBookmarkURL(node[0], keyword, url) + + def testAddBookmarkInMultiProfile(self): + """Verify adding Bookmarks in multiprofile. + + Adding bookmarks in one profile should not affect other profiles. + """ + # Add 'GoogleNews' as bookmark in profile 1. + self.OpenNewBrowserWindowWithNewProfile() + self._AddBookmark('GoogleNews', 'http://news.google.com/', windex=1) + # Add 'YouTube' as bookmark in profile 2. + self.OpenNewBrowserWindowWithNewProfile() + self._AddBookmark('YouTube', 'http://www.youtube.com/', windex=2) + default_path, profile1_path, profile2_path = self._GetProfilePath() + # Close profile1/profile2 windows. + self.CloseBrowserWindow(2) + self.CloseBrowserWindow(1) + # Launch profile1, verify bookmark 'GoogleNews'. + self.OpenProfileWindow(path=profile1_path) + self._AssertBookmark('GoogleNews', 'http://news.google.com/', windex=1) + # Launch profile1, verify bookmark 'YouTube'. + self.OpenProfileWindow(path=profile2_path) + self._AssertBookmark('YouTube', 'http://www.youtube.com/', windex=2) + + def testRemoveBookmarksInMultiProfile(self): + """Verify removing Bookmarks in multiprofile. + + Removing bookmark in one profile should not affect other profiles. + """ + # Add 'GoogleNews' as bookmark in profile 1. + self.OpenNewBrowserWindowWithNewProfile() + self._AddBookmark('GoogleNews', 'http://news.google.com/', windex=1) + # Confirm, then remove. + self._AssertBookmark('GoogleNews', 'http://news.google.com/', windex=1) + node = self.GetBookmarkModel(1).FindByTitle('GoogleNews') + self.RemoveBookmark(node[0]['id'], 1) + # Add 'GoogleNews' also as bookmark in profile 2. + self.OpenNewBrowserWindowWithNewProfile() + self._AddBookmark('GoogleNews', 'http://news.google.com/', windex=2) + default_path, profile1_path, profile2_path = self._GetProfilePath() + # Close profile1/profile2 windows. + self.CloseBrowserWindow(2) + self.CloseBrowserWindow(1) + # Confirm removal in profile1 + self.OpenProfileWindow(path=profile1_path) + bookmarks = self.GetBookmarkModel(windex=1) + node = bookmarks.FindByTitle('GoogleNews') + self.assertEqual(0, len(node)) + # Verify profile2 still has bookmark. + self.OpenProfileWindow(path=profile2_path) + self._AssertBookmark('GoogleNews', 'http://news.google.com/', windex=2) + + def testEditBookmarksInMultiProfile(self): + """Verify editing Bookmarks in multiprofile. + + Changing bookmark in one profile should not affect other profiles. + """ + # Add 'GoogleNews' as bookmark in profile 1. + self.OpenNewBrowserWindowWithNewProfile() + self._AddBookmark('GoogleNews', 'http://news.google.com/', windex=1) + # Change a title and URL. + bookmarks = self.GetBookmarkModel(windex=1) + nodes = bookmarks.FindByTitle('GoogleNews') + self.assertEqual(1, len(nodes)) + self.SetBookmarkTitle(nodes[0]['id'], 'YouTube', 1) + self.SetBookmarkURL(nodes[0]['id'], 'http://www.youtube.com', 1) + # Add 'GoogleNews' as bookmark in profile 2. + self.OpenNewBrowserWindowWithNewProfile() + self._AddBookmark('GoogleNews', 'http://news.google.com/', windex=2) + default_path, profile1_path, profile2_path = self._GetProfilePath() + # Close profile1/profile2 windows. + self.CloseBrowserWindow(2) + self.CloseBrowserWindow(1) + # Confirm bookmark change in profile1. + self.OpenProfileWindow(path=profile1_path) + self._AssertBookmark('YouTube', 'http://www.youtube.com/', windex=1) + # Confirm profile2 bookmark is still same 'GoogleNews'. + self.OpenProfileWindow(path=profile2_path) + self._AssertBookmark('GoogleNews', 'http://news.google.com/', windex=2) + + def testAddBookmarksInMultiProfileIncognito(self): + """Verify adding Bookmarks for incognito window in multiprofile.""" + # Add 'YouTube' as bookmark in default profile + self._AddBookmark('YouTube', 'http://www.youtube.com/') + # Add 'GoogleNews' as bookmark in profile 1. + self.OpenNewBrowserWindowWithNewProfile() + self._AddBookmark('GoogleNews', 'http://news.google.com/', windex=1) + default_path, profile1_path, profile2_path = self._GetProfilePath() + # Lauch incognito window, add bookmark 'BING' + self.RunCommand(pyauto.IDC_NEW_INCOGNITO_WINDOW) + bar_id = self.GetBookmarkModel(2).BookmarkBar()['id'] + self.AddBookmarkURL(bar_id, 0, 'BING','http://www.bing.com/', 2) + # Close profile1/profile2 windows. + self.CloseBrowserWindow(2) + self.CloseBrowserWindow(1) + # Switch to profile 1, verify 'BING' is not added. + self.OpenProfileWindow(path=profile1_path) + bookmarks = self.GetBookmarkModel(windex=1) + node = bookmarks.FindByTitle('BING') + self.assertEqual(0, len(node)) + + def testRemoveBookmarksInMultiProfileIncognito(self): + """Verify removing Bookmarks in for incognito window in multiprofile.""" + # Add 'GoogleNews' as bookmark in default profile. + self._AddBookmark('GoogleNews', 'http://news.google.com/') + # Add 'GoogleNews' as bookmark in profile 1. + self.OpenNewBrowserWindowWithNewProfile() + self._AddBookmark('GoogleNews', 'http://news.google.com/', windex=1) + # launch incognito + self.RunCommand(pyauto.IDC_NEW_INCOGNITO_WINDOW) + # Confirm, then remove. + self._AssertBookmark('GoogleNews', 'http://news.google.com/', windex=2) + bookmarks = self.GetBookmarkModel(windex=2) + nodes = bookmarks.FindByTitle('GoogleNews') + self.RemoveBookmark(nodes[0]['id'], 2) + default_path, profile1_path, profile2_path = self._GetProfilePath() + # Close profile1/profile2 windows. + self.CloseBrowserWindow(2) + self.CloseBrowserWindow(1) + # Verify profile1 still has bookmark. + self.OpenProfileWindow(path=profile1_path) + bookmarks = self.GetBookmarkModel(windex=1) + node = bookmarks.FindByTitle('GoogleNews') + self.assertEqual(1, len(node)) + + def testEditBookmarksInMultiProfileIncognito(self): + """Verify changing Bookmarks in for incognito window in multiprofile.""" + # Add 'GoogleNews' as bookmark in default profile. + self._AddBookmark('GoogleNews', 'http://news.google.com/') + # Add 'GoogleNews' as bookmark in profile 1. + self.OpenNewBrowserWindowWithNewProfile() + self._AddBookmark('GoogleNews', 'http://news.google.com/', windex=1) + # Launch incognito + self.RunCommand(pyauto.IDC_NEW_INCOGNITO_WINDOW) + # Change a title and URL to 'YouTube'. + bookmarks = self.GetBookmarkModel(windex=2) + nodes = bookmarks.FindByTitle('GoogleNews') + self.assertEqual(1, len(nodes)) + self.SetBookmarkTitle(nodes[0]['id'], 'YouTube', 2) + self.SetBookmarkURL(nodes[0]['id'], 'http://www.youtube.com', 2) + default_path, profile1_path, profile2_path = self._GetProfilePath() + # Close profile1/profile2 windows. + self.CloseBrowserWindow(2) + self.CloseBrowserWindow(1) + # Launch profile1, verify bookmark is same as before. + self.OpenProfileWindow(path=profile1_path) + self._AssertBookmark('GoogleNews', 'http://news.google.com/', windex=1) + # Launch default, verify bookmark is changed to 'YouTube'. + self.OpenProfileWindow(path=default_path) + self._AssertBookmark('YouTube', 'http://www.youtube.com/') + + def testSearchBookmarksInMultiProfile(self): + """Verify user can not search bookmarks in other profile.""" + # Add 'GoogleNews', 'Youtube' as bookmarks in default profile. + self.OpenNewBrowserWindowWithNewProfile() + bookmarks = self.GetBookmarkModel(windex=1) + bar_id = bookmarks.BookmarkBar()['id'] + self.AddBookmarkURL(bar_id, 0, 'GoogleNews', + 'http://news.google.com/', 1) + self.AddBookmarkURL(bar_id, 1, 'YouTube', 'http://www.youtube.com/',1) + # Add 'BING', 'DB' as bookmarks to profile1 + self.OpenNewBrowserWindowWithNewProfile() + bookmarks = self.GetBookmarkModel(windex=2) + bar_id = bookmarks.BookmarkBar()['id'] + self.AddBookmarkURL(bar_id, 0, 'BING', 'http://www.bing.com/', 2) + self.AddBookmarkURL(bar_id, 0, 'DB', 'http://www.oracle.com/', 2) + default_path, profile1_path, profile2_path = self._GetProfilePath() + # Close profile1/profile2 windows. + self.CloseBrowserWindow(2) + self.CloseBrowserWindow(1) + # Search 'BING' in default profile. + self.OpenProfileWindow(path=profile1_path) + bookmarks = self.GetBookmarkModel(windex=1) + node = bookmarks.FindByTitle('BING') + self.assertEqual(0, len(node)) + # Search 'DB' in profile 1. + self.OpenProfileWindow(path=profile2_path) + bookmarks = self.GetBookmarkModel(windex=2) + node = bookmarks.FindByTitle('GoogleNews') + self.assertEqual(0, len(node)) + if __name__ == '__main__': pyauto_functional.Main() diff --git a/chrome/test/functional/imports.py b/chrome/test/functional/imports.py index 6baed36..5cd101a 100755 --- a/chrome/test/functional/imports.py +++ b/chrome/test/functional/imports.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (c) 2011 The Chromium Authors. All rights reserved. +# Copyright (c) 2012 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. @@ -110,15 +110,16 @@ class ImportsTest(pyauto.PyUITest): os.path.join(self.DataDir(), 'import', 'safari', 'mac.zip'), self._safari_profiles_path) - def _CheckForBookmarks(self, bookmark_titles, bookmark_bar): + def _CheckForBookmarks(self, bookmark_titles, bookmark_bar, window_index=0): """Checks that the given bookmarks exist. Args: bookmark_titles: A set of bookmark title strings. bookmark_bar: True if the bookmarks are part of the bookmark bar. False otherwise. + window_index: The window index, default is 0. """ - bookmarks = self.GetBookmarkModel() + bookmarks = self.GetBookmarkModel(window_index) if bookmark_bar: node = bookmarks.BookmarkBar() else: @@ -163,13 +164,13 @@ class ImportsTest(pyauto.PyUITest): self.assertTrue([x for x in passwords if x['username_value'] == username]) def _CheckDefaults(self, bookmarks, history, passwords, home_page, - search_engines): + search_engines, window_index=0): """Checks the defaults for each of the possible import items. All arguments are True if they should be checked, False otherwise.""" if bookmarks: - self._CheckForBookmarks(self._bookmark_bar_items, True) - self._CheckForBookmarks(self._bookmark_folder_items, False) + self._CheckForBookmarks(self._bookmark_bar_items, True, window_index) + self._CheckForBookmarks(self._bookmark_folder_items, False, window_index) if history: self._CheckForHistory(self._history_items) if passwords: @@ -194,15 +195,32 @@ class ImportsTest(pyauto.PyUITest): return True def _ImportFromFirefox(self, bookmarks, history, passwords, home_page, - search_engines): + search_engines, window_index=0): """Verify importing individual Firefox data through preferences""" if not self._CanRunFirefoxTests(): logging.warn('Not running firefox import tests.') return self._SwapFirefoxProfile() - self.ImportSettings('Mozilla Firefox', False, self._to_import) + self.ImportSettings('Mozilla Firefox', False, self._to_import, window_index) self._CheckDefaults(bookmarks, history, passwords, home_page, - search_engines) + search_engines, window_index) + + def _GetProfilePath(self): + """Get profile paths when multiprofile windows are open. + + Returns: + profile: Path for multiprofiles. + """ + profiles_list = self.GetMultiProfileInfo()['profiles'] + profile1_path = profile2_path = default_path = None + for profile in profiles_list: + if profile['path'].find('Profile 1') != -1: + profile1_path = profile['path'] + elif profile['path'].find('Profile 2') != -1: + profile2_path = profile['path'] + elif profile['path'].find('Default') != -1: + default_path = profile['path'] + return default_path, profile1_path, profile2_path # Tests. def testFirefoxImportFromPrefs(self): @@ -331,6 +349,37 @@ class ImportsTest(pyauto.PyUITest): self.assertEqual(num_history_orig, len(self.GetHistoryInfo().History())) self.assertEqual(num_passwords_orig, len(self.GetSavedPasswords())) + def testFireFoxImportBookmarksMultiProfile(self): + """Verify importing Firefox bookmarks through preferences. + + Bookmarks are imported from Firefox through the preferences for multiple + profiles.""" + # Create new profile, import bookmarks from firefox. + self.OpenNewBrowserWindowWithNewProfile() + self._ImportFromFirefox(bookmarks=True, history=False, + passwords=False, home_page=False, + search_engines=False, window_index=1) + # Create new profile, add 'BING', 'DB' as bookmark. + self.OpenNewBrowserWindowWithNewProfile() + bookmarks = self.GetBookmarkModel(2) + bar_id = bookmarks.BookmarkBar()['id'] + self.AddBookmarkURL(bar_id, 0, 'BING', 'http://www.bing.com/', 2) + self.AddBookmarkURL(bar_id, 0, 'DB', 'http://www.oracle.com/', 2) + default_path, profile1_path, profile2_path = self._GetProfilePath() + # Close profile1/profile2 windows. + self.CloseBrowserWindow(2) + self.CloseBrowserWindow(1) + # Launch profile2. + self.OpenProfileWindow(path=profile2_path) + # Verify bookmark imported from firefox 'GoogleNews' in + # profile2 is not present. + bookmarks = self.GetBookmarkModel(1) + node = bookmarks.FindByTitle('GoogleNews') + self.assertEqual(0, len(node)) + # Assert if 'BING' is present. + node = bookmarks.FindByTitle('BING') + self.assertEqual(1, len(node)) + if __name__ == '__main__': pyauto_functional.Main() diff --git a/chrome/test/pyautolib/pyauto.py b/chrome/test/pyautolib/pyauto.py index 0b6fe2f..444234a 100755 --- a/chrome/test/pyautolib/pyauto.py +++ b/chrome/test/pyautolib/pyauto.py @@ -1057,13 +1057,13 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase): raise JSONInterfaceError(ret_dict['error']) return ret_dict - def GetBookmarkModel(self): + def GetBookmarkModel(self, windex=0): """Return the bookmark model as a BookmarkModel object. This is a snapshot of the bookmark model; it is not a proxy and does not get updated as the bookmark model changes. """ - bookmarks_as_json = self._GetBookmarksAsJSON() + bookmarks_as_json = self._GetBookmarksAsJSON(windex) if bookmarks_as_json == None: raise JSONInterfaceError('Could not resolve browser proxy.') return bookmark_model.BookmarkModel(bookmarks_as_json) @@ -2075,6 +2075,7 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase): 'with_ui': with_ui, 'windex': windex, } + if from_webstore: cmd_dict['from_webstore'] = True return self._GetResultFromJSONRequest(cmd_dict, windex=None)['id'] @@ -2608,7 +2609,8 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase): finally: shutil.rmtree(tempdir, ignore_errors=True) - def ImportSettings(self, import_from, first_run, import_items): + def ImportSettings(self, import_from, first_run, + import_items, windex=0): """Import the specified import items from the specified browser. Implements the features available in the "Import Settings" part of the @@ -2629,6 +2631,8 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase): Strings that can be in the list are: HISTORY, FAVORITES, PASSWORDS, SEARCH_ENGINES, HOME_PAGE, ALL (note: COOKIES is not supported by the browser yet) + windex: window index, defaults to 0. + Raises: pyauto_errors.JSONInterfaceError if the automation call returns an error. """ @@ -2638,7 +2642,7 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase): 'first_run': first_run, 'import_items': import_items } - return self._GetResultFromJSONRequest(cmd_dict) + return self._GetResultFromJSONRequest(cmd_dict, windex=windex) def ClearBrowsingData(self, to_remove, time_period): """Clear the specified browsing data. Implements the features available in @@ -2757,7 +2761,7 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase): } self._GetResultFromJSONRequest(cmd_dict, windex=windex) - def SetTheme(self, crx_file_path): + def SetTheme(self, crx_file_path, windex=0): """Installs the given theme synchronously. A theme file is a file with a .crx suffix, like an extension. The theme @@ -2773,7 +2777,7 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase): Raises: pyauto_errors.JSONInterfaceError if the automation call returns an error. """ - return self.InstallExtension(crx_file_path, True) + return self.InstallExtension(crx_file_path, True, windex) def WaitUntilDownloadedThemeSet(self, theme_name): """Waits until the theme has been set. @@ -2805,7 +2809,7 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase): } self._GetResultFromJSONRequest(cmd_dict) - def GetThemeInfo(self): + def GetThemeInfo(self, windex=0): """Get info about theme. This includes info about the theme name, its colors, images, etc. @@ -2831,7 +2835,7 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase): cmd_dict = { 'command': 'GetThemeInfo', } - return self._GetResultFromJSONRequest(cmd_dict) + return self._GetResultFromJSONRequest(cmd_dict, windex=windex) def GetActiveNotifications(self): """Gets a list of the currently active/shown HTML5 notifications. @@ -3945,6 +3949,27 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase): } return self._GetResultFromJSONRequest(cmd_dict, windex=None) + def OpenProfileWindow(self, path, num_loads=1): + """Open browser window for an existing profile. + + This is equivalent to picking a profile from the multi-profile menu. + + Multi-profile should be enabled and the requested profile should already + exist. If a window for the given profile already exists, it'll merely get + activated. Use OpenNewBrowserWindowWithNewProfile() to create a new profile. + + Args: + path: profile path of the profile to be opened. + num_loads: the number of loads to wait for, when a new browser window + is created. Useful when restoring a window with many tabs. + """ + cmd_dict = { # Prepare command for the json interface + 'command': 'OpenProfileWindow', + 'path': path, + 'num_loads': num_loads, + } + return self._GetResultFromJSONRequest(cmd_dict, windex=None) + def GetMultiProfileInfo(self): """Fetch info about all multi-profile users. diff --git a/chrome/test/pyautolib/pyautolib.cc b/chrome/test/pyautolib/pyautolib.cc index 37a3249..fe78c29 100644 --- a/chrome/test/pyautolib/pyautolib.cc +++ b/chrome/test/pyautolib/pyautolib.cc @@ -223,9 +223,10 @@ int PyUITestBase::GetBrowserWindowCount() { return num_windows; } -bool PyUITestBase::GetBookmarkBarState(bool* visible, bool* detached) { - scoped_refptr<BrowserProxy> browser_proxy = - GetBrowserWindow(0); // Window doesn't matter. +bool PyUITestBase::GetBookmarkBarState(bool* visible, + bool* detached, + int window_index) { + scoped_refptr<BrowserProxy> browser_proxy = GetBrowserWindow(window_index); EXPECT_TRUE(browser_proxy.get()); if (!browser_proxy.get()) return false; @@ -254,9 +255,9 @@ bool PyUITestBase::IsBookmarkBarDetached() { return detached; } -bool PyUITestBase::WaitForBookmarkBarVisibilityChange(bool wait_for_open) { - scoped_refptr<BrowserProxy> browser_proxy = - GetBrowserWindow(0); // Window doesn't matter. +bool PyUITestBase::WaitForBookmarkBarVisibilityChange(bool wait_for_open, + int window_index) { + scoped_refptr<BrowserProxy> browser_proxy = GetBrowserWindow(window_index); EXPECT_TRUE(browser_proxy.get()); if (!browser_proxy.get()) return false; @@ -269,9 +270,8 @@ bool PyUITestBase::WaitForBookmarkBarVisibilityChange(bool wait_for_open) { return completed; } -std::string PyUITestBase::_GetBookmarksAsJSON() { - scoped_refptr<BrowserProxy> browser_proxy = - GetBrowserWindow(0); // Window doesn't matter. +std::string PyUITestBase::_GetBookmarksAsJSON(int window_index) { + scoped_refptr<BrowserProxy> browser_proxy = GetBrowserWindow(window_index); EXPECT_TRUE(browser_proxy.get()); if (!browser_proxy.get()) return NULL; @@ -281,10 +281,11 @@ std::string PyUITestBase::_GetBookmarksAsJSON() { return s; } -bool PyUITestBase::AddBookmarkGroup(std::wstring& parent_id, int index, - std::wstring& title) { - scoped_refptr<BrowserProxy> browser_proxy = - GetBrowserWindow(0); // Window doesn't matter. +bool PyUITestBase::AddBookmarkGroup(std::wstring& parent_id, + int index, + std::wstring& title, + int window_index) { + scoped_refptr<BrowserProxy> browser_proxy = GetBrowserWindow(window_index); EXPECT_TRUE(browser_proxy.get()); if (!browser_proxy.get()) return false; @@ -292,10 +293,12 @@ bool PyUITestBase::AddBookmarkGroup(std::wstring& parent_id, int index, return browser_proxy->AddBookmarkGroup(StringToId(parent_id), index, title); } -bool PyUITestBase::AddBookmarkURL(std::wstring& parent_id, int index, - std::wstring& title, std::wstring& url) { - scoped_refptr<BrowserProxy> browser_proxy = - GetBrowserWindow(0); // Window doesn't matter. +bool PyUITestBase::AddBookmarkURL(std::wstring& parent_id, + int index, + std::wstring& title, + std::wstring& url, + int window_index) { + scoped_refptr<BrowserProxy> browser_proxy = GetBrowserWindow(window_index); EXPECT_TRUE(browser_proxy.get()); if (!browser_proxy.get()) return false; @@ -305,10 +308,11 @@ bool PyUITestBase::AddBookmarkURL(std::wstring& parent_id, int index, GURL(WideToUTF8(url))); } -bool PyUITestBase::ReparentBookmark( - std::wstring& id, std::wstring& new_parent_id, int index) { - scoped_refptr<BrowserProxy> browser_proxy = - GetBrowserWindow(0); // Window doesn't matter. +bool PyUITestBase::ReparentBookmark(std::wstring& id, + std::wstring& new_parent_id, + int index, + int window_index) { + scoped_refptr<BrowserProxy> browser_proxy = GetBrowserWindow(window_index); EXPECT_TRUE(browser_proxy.get()); if (!browser_proxy.get()) return false; @@ -318,9 +322,10 @@ bool PyUITestBase::ReparentBookmark( index); } -bool PyUITestBase::SetBookmarkTitle(std::wstring& id, std::wstring& title) { - scoped_refptr<BrowserProxy> browser_proxy = - GetBrowserWindow(0); // Window doesn't matter. +bool PyUITestBase::SetBookmarkTitle(std::wstring& id, + std::wstring& title, + int window_index) { + scoped_refptr<BrowserProxy> browser_proxy = GetBrowserWindow(window_index); EXPECT_TRUE(browser_proxy.get()); if (!browser_proxy.get()) return false; @@ -328,9 +333,10 @@ bool PyUITestBase::SetBookmarkTitle(std::wstring& id, std::wstring& title) { return browser_proxy->SetBookmarkTitle(StringToId(id), title); } -bool PyUITestBase::SetBookmarkURL(std::wstring& id, std::wstring& url) { - scoped_refptr<BrowserProxy> browser_proxy = - GetBrowserWindow(0); // Window doesn't matter. +bool PyUITestBase::SetBookmarkURL(std::wstring& id, + std::wstring& url, + int window_index) { + scoped_refptr<BrowserProxy> browser_proxy = GetBrowserWindow(window_index); EXPECT_TRUE(browser_proxy.get()); if (!browser_proxy.get()) return false; @@ -338,9 +344,8 @@ bool PyUITestBase::SetBookmarkURL(std::wstring& id, std::wstring& url) { return browser_proxy->SetBookmarkURL(StringToId(id), GURL(WideToUTF8(url))); } -bool PyUITestBase::RemoveBookmark(std::wstring& id) { - scoped_refptr<BrowserProxy> browser_proxy = - GetBrowserWindow(0); // Window doesn't matter. +bool PyUITestBase::RemoveBookmark(std::wstring& id, int window_index) { + scoped_refptr<BrowserProxy> browser_proxy = GetBrowserWindow(window_index); EXPECT_TRUE(browser_proxy.get()); if (!browser_proxy.get()) return false; diff --git a/chrome/test/pyautolib/pyautolib.h b/chrome/test/pyautolib/pyautolib.h index 42316b1..8e47776 100644 --- a/chrome/test/pyautolib/pyautolib.h +++ b/chrome/test/pyautolib/pyautolib.h @@ -146,10 +146,11 @@ class PyUITestBase : public UITestBase { // Wait for the bookmark bar animation to complete. // If |wait_for_open| is true, wait for it to open. // If |wait_for_open| is false, wait for it to close. - bool WaitForBookmarkBarVisibilityChange(bool wait_for_open); + bool WaitForBookmarkBarVisibilityChange(bool wait_for_open, + int window_index = 0); // Get the bookmarks as a JSON string. Internal method. - std::string _GetBookmarksAsJSON(); + std::string _GetBookmarksAsJSON(int window_index = 0); // Editing of the bookmark model. Bookmarks are referenced by id. // The id is a std::wstring, not an int64, for convenience, since @@ -159,16 +160,19 @@ class PyUITestBase : public UITestBase { // is unnecessary. URLs are strings and not GURLs for a similar reason. // Bookmark or group (folder) creation: bool AddBookmarkGroup(std::wstring& parent_id, int index, - std::wstring& title); + std::wstring& title, int window_index = 0); bool AddBookmarkURL(std::wstring& parent_id, int index, - std::wstring& title, std::wstring& url); + std::wstring& title, std::wstring& url, + int window_index = 0); // Bookmark editing: bool ReparentBookmark(std::wstring& id, std::wstring& new_parent_id, - int index); - bool SetBookmarkTitle(std::wstring& id, std::wstring& title); - bool SetBookmarkURL(std::wstring& id, std::wstring& url); + int index, int window_index = 0); + bool SetBookmarkTitle(std::wstring& id, std::wstring& title, + int window_index = 0); + bool SetBookmarkURL(std::wstring& id, std::wstring& url, + int window_index = 0); // Finally, bookmark deletion: - bool RemoveBookmark(std::wstring& id); + bool RemoveBookmark(std::wstring& id, int window_index = 0); // Get a handle to browser window at the given index, or NULL on failure. scoped_refptr<BrowserProxy> GetBrowserWindow(int window_index); @@ -208,7 +212,7 @@ class PyUITestBase : public UITestBase { private: // Gets the current state of the bookmark bar. Returns false if it failed. - bool GetBookmarkBarState(bool* visible, bool* detached); + bool GetBookmarkBarState(bool* visible, bool* detached, int window_index = 0); // Enables PostTask to main thread. // Should be shared across multiple instances of PyUITestBase so that this diff --git a/chrome/test/pyautolib/pyautolib.i b/chrome/test/pyautolib/pyautolib.i index 40222a7..7d959a6 100644 --- a/chrome/test/pyautolib/pyautolib.i +++ b/chrome/test/pyautolib/pyautolib.i @@ -334,31 +334,46 @@ class PyUITestBase { %feature("docstring", "Wait for the bookmark bar animation to complete. " "|wait_for_open| specifies which kind of change we wait for.") WaitForBookmarkBarVisibilityChange; - bool WaitForBookmarkBarVisibilityChange(bool wait_for_open); + bool WaitForBookmarkBarVisibilityChange(bool wait_for_open, + int window_index=0); - %feature("docstring", "Get the bookmarks as a JSON string. Internal method.") + %feature("docstring", "Get the bookmarks as a JSON string. Internal method.") _GetBookmarksAsJSON; - std::string _GetBookmarksAsJSON(); - - %feature("docstring", "Add a bookmark folder with the given index in the parent." - " |title| is the title/name of the folder.") AddBookmarkGroup; - bool AddBookmarkGroup(std::wstring parent_id, int index, std::wstring title); - - %feature("docstring", "Add a bookmark with the given title and URL.") AddBookmarkURL; - bool AddBookmarkURL(std::wstring parent_id, int index, - std::wstring title, const std::wstring url); + std::string _GetBookmarksAsJSON(int window_index=0); + + %feature("docstring", "Add a bookmark folder with the given index in the " + " parent. |title| is the title/name of the folder.") + AddBookmarkGroup; + bool AddBookmarkGroup(std::wstring parent_id, + int index, std::wstring title, + int window_index=0); + + %feature("docstring", "Add a bookmark with the given title and URL.") + AddBookmarkURL; + bool AddBookmarkURL(std::wstring parent_id, + int index, + std::wstring title, + const std::wstring url, + int window_index=0); %feature("docstring", "Move a bookmark to a new parent.") ReparentBookmark; - bool ReparentBookmark(std::wstring id, std::wstring new_parent_id, int index); + bool ReparentBookmark(std::wstring id, + std::wstring new_parent_id, + int index, + int window_index=0); %feature("docstring", "Set the title of a bookmark.") SetBookmarkTitle; - bool SetBookmarkTitle(std::wstring id, std::wstring title); + bool SetBookmarkTitle(std::wstring id, + std::wstring title, + int window_index=0); %feature("docstring", "Set the URL of a bookmark.") SetBookmarkURL; - bool SetBookmarkURL(std::wstring id, const std::wstring url); + bool SetBookmarkURL(std::wstring id, + const std::wstring url, + int window_index=0); %feature("docstring", "Remove (delete) a bookmark.") RemoveBookmark; - bool RemoveBookmark(std::wstring id); + bool RemoveBookmark(std::wstring id, int window_index=0); %feature("docstring", "Open the Find box in the given or first browser " "window.") OpenFindInPage; |