diff options
author | rsimha@chromium.org <rsimha@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-03 23:27:31 +0000 |
---|---|---|
committer | rsimha@chromium.org <rsimha@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-03 23:27:31 +0000 |
commit | 909a81eaa4568f4b13562dc3f34ac7268b590f09 (patch) | |
tree | 958829ea557102634d623123a77f0ae20a7dd6da /chrome/browser/automation | |
parent | c09fb1c79c0a3e76dbb6091e4b718fd9bb197395 (diff) | |
download | chromium_src-909a81eaa4568f4b13562dc3f34ac7268b590f09.zip chromium_src-909a81eaa4568f4b13562dc3f34ac7268b590f09.tar.gz chromium_src-909a81eaa4568f4b13562dc3f34ac7268b590f09.tar.bz2 |
PyAuto hooks for Sync in TestingAutomationProvider
This patch exposes hooks for sync in TestingAutomationProvider that the chrome pyauto test suite can use. It contains the following changes:
- Partial revert of an earlier change to ProfileSyncServiceHarness. Some of its methods were made pure virtual, but this ended up being unnecessary. Also ripped out unnecessary code from LiveSyncTest.
- Minor refactor of ProfileSyncServiceHarness to allow for scenarios where the browser is restarted.
- A bunch of new methods in TestingAutomationProvider: SignInToSync, GetSyncInfo, AwaitSyncCycleCompletion, EnableSyncForDatatypes and DisableSyncForDatatypes.
- A new method in model_type.h/cc called ModelTypeFromString. Required for automation.
- New APIs in pyauto.py for sync.
- New test suite sync.py with sample tests.
BUG=53651, 60970, 56460, 61639
TEST=run pyauto sync tests
Review URL: http://codereview.chromium.org/4096004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@64988 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/automation')
-rw-r--r-- | chrome/browser/automation/testing_automation_provider.cc | 223 | ||||
-rw-r--r-- | chrome/browser/automation/testing_automation_provider.h | 35 |
2 files changed, 258 insertions, 0 deletions
diff --git a/chrome/browser/automation/testing_automation_provider.cc b/chrome/browser/automation/testing_automation_provider.cc index c3c8f14..6fc58d3 100644 --- a/chrome/browser/automation/testing_automation_provider.cc +++ b/chrome/browser/automation/testing_automation_provider.cc @@ -10,6 +10,7 @@ #include "base/json/json_writer.h" #include "base/json/string_escape.h" #include "base/path_service.h" +#include "base/stringprintf.h" #include "base/time.h" #include "base/utf_string_conversions.h" #include "chrome/app/chrome_dll_resource.h" @@ -2113,6 +2114,15 @@ void TestingAutomationProvider::SendJSONRequest(int handle, handler_map["WaitForNotificationCount"] = &TestingAutomationProvider::WaitForNotificationCount; + handler_map["SignInToSync"] = &TestingAutomationProvider::SignInToSync; + handler_map["GetSyncInfo"] = &TestingAutomationProvider::GetSyncInfo; + handler_map["AwaitSyncCycleCompletion"] = + &TestingAutomationProvider::AwaitSyncCycleCompletion; + handler_map["EnableSyncForDatatypes"] = + &TestingAutomationProvider::EnableSyncForDatatypes; + handler_map["DisableSyncForDatatypes"] = + &TestingAutomationProvider::DisableSyncForDatatypes; + if (handler_map.find(std::string(command)) != handler_map.end()) { (this->*handler_map[command])(browser, dict_value, reply_message); } else { @@ -3830,6 +3840,219 @@ void TestingAutomationProvider::FillAutoFillProfile( reply.SendSuccess(NULL); } +// Sample json output: { "success": true } +void TestingAutomationProvider::SignInToSync(Browser* browser, + DictionaryValue* args, + IPC::Message* reply_message) { + AutomationJSONReply reply(this, reply_message); + std::string username; + std::string password; + if (!args->GetString("username", &username) || + !args->GetString("password", &password)) { + reply.SendError("Invalid or missing args"); + return; + } + if (sync_waiter_.get() == NULL) { + sync_waiter_.reset(new ProfileSyncServiceHarness( + browser->profile(), username, password, 0)); + } else { + sync_waiter_->SetCredentials(username, password); + } + if (sync_waiter_->SetupSync()) { + DictionaryValue* return_value = new DictionaryValue; + return_value->SetBoolean("success", true); + reply.SendSuccess(return_value); + } else { + reply.SendError("Signing in to sync was unsuccessful"); + } +} + +// Sample json output: +// {u'summary': u'SYNC DISABLED'} +// +// { u'authenticated': True, +// u'last synced': u'Just now', +// u'summary': u'READY', +// u'sync url': u'clients4.google.com', +// u'synced datatypes': [ u'Bookmarks', +// u'Preferences', +// u'Passwords', +// u'Autofill', +// u'Themes', +// u'Extensions', +// u'Apps']} +void TestingAutomationProvider::GetSyncInfo(Browser* browser, + DictionaryValue* args, + IPC::Message* reply_message) { + AutomationJSONReply reply(this, reply_message); + DictionaryValue* sync_info = new DictionaryValue; + DictionaryValue* return_value = new DictionaryValue; + if (sync_waiter_.get() == NULL) { + sync_waiter_.reset( + ProfileSyncServiceHarness::CreateAndAttach(browser->profile())); + } + if (!sync_waiter_->IsSyncAlreadySetup()) { + sync_info->SetString("summary", "SYNC DISABLED"); + } else { + ProfileSyncService* service = sync_waiter_->service(); + ProfileSyncService::Status status = sync_waiter_->GetStatus(); + sync_info->SetString("summary", + ProfileSyncService::BuildSyncStatusSummaryText(status.summary)); + sync_info->SetString("sync url", service->sync_service_url().host()); + sync_info->SetBoolean("authenticated", status.authenticated); + sync_info->SetString("last synced", service->GetLastSyncedTimeString()); + ListValue* synced_datatype_list = new ListValue; + syncable::ModelTypeSet synced_datatypes; + service->GetPreferredDataTypes(&synced_datatypes); + for (syncable::ModelTypeSet::iterator it = synced_datatypes.begin(); + it != synced_datatypes.end(); ++it) { + synced_datatype_list->Append( + new StringValue(syncable::ModelTypeToString(*it))); + } + sync_info->Set("synced datatypes", synced_datatype_list); + } + return_value->Set("sync_info", sync_info); + reply.SendSuccess(return_value); +} + +// Sample json output: { "success": true } +void TestingAutomationProvider::AwaitSyncCycleCompletion( + Browser* browser, + DictionaryValue* args, + IPC::Message* reply_message) { + AutomationJSONReply reply(this, reply_message); + if (sync_waiter_.get() == NULL) { + sync_waiter_.reset( + ProfileSyncServiceHarness::CreateAndAttach(browser->profile())); + } + if (!sync_waiter_->IsSyncAlreadySetup()) { + reply.SendError("Not signed in to sync"); + return; + } + sync_waiter_->AwaitSyncCycleCompletion("Waiting for sync cycle"); + ProfileSyncService::Status status = sync_waiter_->GetStatus(); + if (status.summary == ProfileSyncService::Status::READY) { + scoped_ptr<DictionaryValue> return_value(new DictionaryValue); + return_value->SetBoolean("success", true); + reply.SendSuccess(return_value.get()); + } else { + reply.SendError("Wait for sync cycle was unsuccessful"); + } +} + +// Refer to EnableSyncForDatatypes() in chrome/test/pyautolib/pyauto.py for +// sample json input. Sample json output: { "success": true } +void TestingAutomationProvider::EnableSyncForDatatypes( + Browser* browser, + DictionaryValue* args, + IPC::Message* reply_message) { + AutomationJSONReply reply(this, reply_message); + if (sync_waiter_.get() == NULL) { + sync_waiter_.reset( + ProfileSyncServiceHarness::CreateAndAttach(browser->profile())); + } + if (!sync_waiter_->IsSyncAlreadySetup()) { + reply.SendError("Not signed in to sync"); + return; + } + ListValue* datatypes = NULL; + if (!args->GetList("datatypes", &datatypes)) { + reply.SendError("Invalid or missing args"); + return; + } + std::string first_datatype; + datatypes->GetString(0, &first_datatype); + if (first_datatype == "All") { + sync_waiter_->EnableSyncForAllDatatypes(); + } else { + int num_datatypes = datatypes->GetSize(); + for (int i = 0; i < num_datatypes; ++i) { + std::string datatype_string; + datatypes->GetString(i, &datatype_string); + syncable::ModelType datatype = + syncable::ModelTypeFromString(datatype_string); + if (datatype == syncable::UNSPECIFIED) { + AutomationJSONReply(this, reply_message).SendError(StringPrintf( + "Invalid datatype string: %s.", datatype_string.c_str())); + return; + } + sync_waiter_->EnableSyncForDatatype(datatype); + sync_waiter_->AwaitSyncCycleCompletion(StringPrintf( + "Enabling datatype: %s", datatype_string.c_str())); + } + } + ProfileSyncService::Status status = sync_waiter_->GetStatus(); + if (status.summary == ProfileSyncService::Status::READY || + status.summary == ProfileSyncService::Status::SYNCING) { + DictionaryValue* return_value = new DictionaryValue; + return_value->SetBoolean("success", true); + reply.SendSuccess(return_value); + } else { + reply.SendError("Enabling sync for given datatypes was unsuccessful"); + } +} + +// Refer to DisableSyncForDatatypes() in chrome/test/pyautolib/pyauto.py for +// sample json input. Sample json output: { "success": true } +void TestingAutomationProvider::DisableSyncForDatatypes( + Browser* browser, + DictionaryValue* args, + IPC::Message* reply_message) { + AutomationJSONReply reply(this, reply_message); + if (sync_waiter_.get() == NULL) { + sync_waiter_.reset( + ProfileSyncServiceHarness::CreateAndAttach(browser->profile())); + } + if (!sync_waiter_->IsSyncAlreadySetup()) { + reply.SendError("Not signed in to sync"); + return; + } + ListValue* datatypes = NULL; + if (!args->GetList("datatypes", &datatypes)) { + reply.SendError("Invalid or missing args"); + return; + } + std::string first_datatype; + datatypes->GetString(0, &first_datatype); + if (first_datatype == "All") { + sync_waiter_->DisableSyncForAllDatatypes(); + ProfileSyncService::Status status = sync_waiter_->GetStatus(); + if (status.summary != ProfileSyncService::Status::READY && + status.summary != ProfileSyncService::Status::SYNCING) { + DictionaryValue* return_value = new DictionaryValue; + return_value->SetBoolean("success", true); + reply.SendSuccess(return_value); + } else { + reply.SendError("Disabling all sync datatypes was unsuccessful"); + } + } else { + int num_datatypes = datatypes->GetSize(); + for (int i = 0; i < num_datatypes; i++) { + std::string datatype_string; + datatypes->GetString(i, &datatype_string); + syncable::ModelType datatype = + syncable::ModelTypeFromString(datatype_string); + if (datatype == syncable::UNSPECIFIED) { + AutomationJSONReply(this, reply_message).SendError(StringPrintf( + "Invalid datatype string: %s.", datatype_string.c_str())); + return; + } + sync_waiter_->DisableSyncForDatatype(datatype); + sync_waiter_->AwaitSyncCycleCompletion(StringPrintf( + "Disabling datatype: %s", datatype_string.c_str())); + } + ProfileSyncService::Status status = sync_waiter_->GetStatus(); + if (status.summary == ProfileSyncService::Status::READY || + status.summary == ProfileSyncService::Status::SYNCING) { + DictionaryValue* return_value = new DictionaryValue; + return_value->SetBoolean("success", true); + reply.SendSuccess(return_value); + } else { + reply.SendError("Disabling sync for given datatypes was unsuccessful"); + } + } +} + /* static */ ListValue* TestingAutomationProvider::GetListFromAutoFillProfiles( const std::vector<AutoFillProfile*>& autofill_profiles) { diff --git a/chrome/browser/automation/testing_automation_provider.h b/chrome/browser/automation/testing_automation_provider.h index dc76603..8cd999d 100644 --- a/chrome/browser/automation/testing_automation_provider.h +++ b/chrome/browser/automation/testing_automation_provider.h @@ -7,9 +7,11 @@ #pragma once #include "base/basictypes.h" +#include "base/scoped_ptr.h" #include "chrome/browser/automation/automation_provider.h" #include "chrome/browser/browser_list.h" #include "chrome/browser/history/history.h" +#include "chrome/browser/sync/profile_sync_service_harness.h" #include "chrome/common/notification_registrar.h" class DictionaryValue; @@ -612,6 +614,36 @@ class TestingAutomationProvider : public AutomationProvider, DictionaryValue* args, IPC::Message* reply_message); + // Signs in to sync using the given username and password. + // Uses the JSON interface for input/output. + void SignInToSync(Browser* browser, + DictionaryValue* args, + IPC::Message* reply_message); + + // Returns info about sync. + // Uses the JSON interface for input/output. + void GetSyncInfo(Browser* browser, + DictionaryValue* args, + IPC::Message* reply_message); + + // Waits for the ongoing sync cycle to complete. + // Uses the JSON interface for input/output. + void AwaitSyncCycleCompletion(Browser* browser, + DictionaryValue* args, + IPC::Message* reply_message); + + // Enables sync for one or more sync datatypes. + // Uses the JSON interface for input/output. + void EnableSyncForDatatypes(Browser* browser, + DictionaryValue* args, + IPC::Message* reply_message); + + // Disables sync for one or more sync datatypes. + // Uses the JSON interface for input/output. + void DisableSyncForDatatypes(Browser* browser, + DictionaryValue* args, + IPC::Message* reply_message); + // Translate DictionaryValues of autofill profiles and credit cards to the // data structure used in the browser. // Args: @@ -702,6 +734,9 @@ class TestingAutomationProvider : public AutomationProvider, PopupMenuWaiter* popup_menu_waiter_; #endif // defined(TOOLKIT_VIEWS) + // Used to wait on various browser sync events. + scoped_ptr<ProfileSyncServiceHarness> sync_waiter_; + // Handle for an in-process redirect query. We expect only one redirect query // at a time (we should have only one caller, and it will block while waiting // for the results) so there is only one handle. When non-0, indicates a |