summaryrefslogtreecommitdiffstats
path: root/chrome/browser/automation
diff options
context:
space:
mode:
authorrsimha@chromium.org <rsimha@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-03 23:27:31 +0000
committerrsimha@chromium.org <rsimha@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-03 23:27:31 +0000
commit909a81eaa4568f4b13562dc3f34ac7268b590f09 (patch)
tree958829ea557102634d623123a77f0ae20a7dd6da /chrome/browser/automation
parentc09fb1c79c0a3e76dbb6091e4b718fd9bb197395 (diff)
downloadchromium_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.cc223
-rw-r--r--chrome/browser/automation/testing_automation_provider.h35
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