summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/automation/automation_provider.cc94
-rw-r--r--chrome/browser/automation/automation_provider.h12
-rw-r--r--chrome/test/functional/PYAUTO_TESTS1
-rw-r--r--chrome/test/functional/prefs.py39
-rw-r--r--chrome/test/pyautolib/prefs_info.py101
-rw-r--r--chrome/test/pyautolib/pyauto.py46
-rw-r--r--chrome/test/pyautolib/pyautolib.i14
7 files changed, 268 insertions, 39 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc
index 7aec832..a878fca 100644
--- a/chrome/browser/automation/automation_provider.cc
+++ b/chrome/browser/automation/automation_provider.cc
@@ -1597,8 +1597,8 @@ void AutomationProvider::RemoveBookmark(int handle,
*success = false;
}
-// Sample json input: { 'command': 'GetHistoryInfo',
-// 'search_text': 'some text' }
+// Sample json input: { "command": "GetHistoryInfo",
+// "search_text": "some text" }
// Refer chrome/test/pyautolib/history_info.py for sample json output.
void AutomationProvider::GetHistoryInfo(
DictionaryValue* args,
@@ -1622,7 +1622,7 @@ void AutomationProvider::GetHistoryInfo(
&AutomationProviderHistoryObserver::HistoryQueryComplete));
}
-// Sample json input: { 'command': 'GetDownloadsInfo' }
+// Sample json input: { "command": "GetDownloadsInfo" }
// Refer chrome/test/pyautolib/download_info.py for sample json output.
void AutomationProvider::GetDownloadsInfo(
DictionaryValue* args,
@@ -1634,7 +1634,7 @@ void AutomationProvider::GetDownloadsInfo(
scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
if (!profile_->HasCreatedDownloadManager()) {
- json_return = "{'error': 'no download manager'}";
+ json_return = "{\"error\": \"no download manager\"}";
reply_return = false;
} else {
// Use DownloadManager's GetDownloads() method and not GetCurrentDownloads()
@@ -1699,7 +1699,7 @@ void AutomationProvider::WaitForDownloadsToComplete(
// Look for a quick return.
if (!profile_->HasCreatedDownloadManager()) {
- json_return = "{'error': 'no download manager'}";
+ json_return = "{\"error\": \"no download manager\"}";
reply_return = false;
} else {
profile_->GetDownloadManager()->GetCurrentDownloads(&observer,
@@ -1727,6 +1727,59 @@ void AutomationProvider::WaitForDownloadsToComplete(
}
}
+// Sample json input: { "command": "GetPrefsInfo" }
+// Refer chrome/test/pyautolib/prefs_info.py for sample json output.
+void AutomationProvider::GetPrefsInfo(DictionaryValue* args,
+ IPC::Message* reply_message) {
+ std::string json_return;
+ bool reply_return = true;
+
+ const PrefService::PreferenceSet& prefs =
+ profile_->GetPrefs()->preference_set();
+ DictionaryValue* items = new DictionaryValue;
+ for (PrefService::PreferenceSet::const_iterator it = prefs.begin();
+ it != prefs.end(); ++it) {
+ items->Set((*it)->name(), (*it)->GetValue()->DeepCopy());
+ }
+ scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
+ return_value->Set(L"prefs", items); // return_value owns items.
+
+ base::JSONWriter::Write(return_value.get(), false, &json_return);
+ AutomationMsg_SendJSONRequest::WriteReplyParams(
+ reply_message, json_return, reply_return);
+ Send(reply_message);
+}
+
+// Sample json input: { "command": "SetPrefs", "path": path, "value": value }
+void AutomationProvider::SetPrefs(DictionaryValue* args,
+ IPC::Message* reply_message) {
+ bool reply_return = true;
+ std::string json_return = "{}";
+ std::wstring path;
+ Value* val;
+ if (args->GetString(L"path", &path) && args->Get(L"value", &val)) {
+ PrefService* pref_service = profile_->GetPrefs();
+ const PrefService::Preference* pref =
+ pref_service->FindPreference(path.c_str());
+ if (!pref) { // Not a registered pref.
+ json_return = "{\"error\": \"pref not registered.\"}";
+ reply_return = false;
+ } else if (pref->IsManaged()) { // Do not attempt to change a managed pref.
+ json_return = "{\"error\": \"pref is managed. cannot be changed.\"}";
+ reply_return = false;
+ } else { // Set the pref.
+ pref_service->Set(path.c_str(), *val);
+ }
+ } else {
+ json_return = "{\"error\": \"no pref path or value given.\"}";
+ reply_return = false;
+ }
+
+ AutomationMsg_SendJSONRequest::WriteReplyParams(
+ reply_message, json_return, reply_return);
+ Send(reply_message);
+}
+
void AutomationProvider::SendJSONRequest(
int handle,
std::string json_request,
@@ -1765,27 +1818,30 @@ void AutomationProvider::SendJSONRequest(
}
}
+ // Map json commands to their handlers.
+ std::map<std::string, JsonHandler> handler_map;
+ handler_map["GetDownloadsInfo"] = &AutomationProvider::GetDownloadsInfo;
+ handler_map["GetHistoryInfo"] = &AutomationProvider::GetHistoryInfo;
+ handler_map["GetPrefsInfo"] = &AutomationProvider::GetPrefsInfo;
+ handler_map["SetPrefs"] = &AutomationProvider::SetPrefs;
+ handler_map["WaitForAllDownloadsToComplete"] =
+ &AutomationProvider::WaitForDownloadsToComplete;
+
if (error_string.empty()) {
- // TODO(jrg): table of calls; async gets passed reply_message,
- // sync methods gets passed an output json dict which we package
- // up and send. Right now we only have one.
- // TODO(nirnimesh): Replace if else cases with map.
- if (command == "GetDownloadsInfo") {
- this->GetDownloadsInfo(dict_value, reply_message);
- return;
- } else if (command == "GetHistoryInfo") {
- this->GetHistoryInfo(dict_value, reply_message);
- return;
- } else if (command == "WaitForAllDownloadsToComplete") {
- this->WaitForDownloadsToComplete(dict_value, reply_message);
+ if (handler_map.find(std::string(command)) != handler_map.end()) {
+ (this->*handler_map[command])(dict_value, reply_message);
return;
} else {
- error_string = "unknown command";
+ error_string = "Unknown command. Options: ";
+ for (std::map<std::string, JsonHandler>::const_iterator it =
+ handler_map.begin(); it != handler_map.end(); ++it) {
+ error_string += it->first + ", ";
+ }
}
}
// If we hit an error, return info.
- // Return a dict of {'error', 'descriptive_string_for_error'}.
+ // Return a dict of {"error", "descriptive_string_for_error"}.
// Else return an empty dict.
std::string json_string;
bool success = true;
diff --git a/chrome/browser/automation/automation_provider.h b/chrome/browser/automation/automation_provider.h
index d21456d..518eb8b 100644
--- a/chrome/browser/automation/automation_provider.h
+++ b/chrome/browser/automation/automation_provider.h
@@ -349,11 +349,23 @@ class AutomationProvider : public base::RefCounted<AutomationProvider>,
// Uses the JSON interface for input/output.
void GetHistoryInfo(DictionaryValue* args, IPC::Message* reply_message);
+ // Get info about preferences.
+ // Uses the JSON interface for input/output.
+ void GetPrefsInfo(DictionaryValue* args, IPC::Message* reply_message);
+
+ // Set prefs.
+ // Uses the JSON interface for input/output.
+ void SetPrefs(DictionaryValue* args, IPC::Message* reply_message);
+
// Generic pattern for pyautolib
void SendJSONRequest(int handle,
std::string json_request,
IPC::Message* reply_message);
+ // Method ptr for json handlers.
+ typedef void (AutomationProvider::*JsonHandler)(DictionaryValue*,
+ IPC::Message*);
+
// Responds to InspectElement request
void HandleInspectElementRequest(int handle,
int x,
diff --git a/chrome/test/functional/PYAUTO_TESTS b/chrome/test/functional/PYAUTO_TESTS
index f037d48..a955243 100644
--- a/chrome/test/functional/PYAUTO_TESTS
+++ b/chrome/test/functional/PYAUTO_TESTS
@@ -23,6 +23,7 @@
'history',
'test_basic.SimpleTest.testCanOpenGoogle',
'downloads',
+ 'prefs',
'special_tabs',
],
diff --git a/chrome/test/functional/prefs.py b/chrome/test/functional/prefs.py
index c02332b..31f8937 100644
--- a/chrome/test/functional/prefs.py
+++ b/chrome/test/functional/prefs.py
@@ -4,6 +4,7 @@
# found in the LICENSE file.
import logging
+import os
import pyauto_functional # Must be imported before pyauto
import pyauto
@@ -13,24 +14,50 @@ class PrefsTest(pyauto.PyUITest):
"""TestCase for Preferences."""
def testSessionRestore(self):
+ """Test session restore preference."""
url1 = 'http://www.google.com/'
url2 = 'http://news.google.com/'
self.NavigateToURL(url1)
self.AppendTab(pyauto.GURL(url2))
num_tabs = self.GetTabCount()
# Set pref to restore session on startup
- browser = self.GetBrowserWindow(0)
- browser.SetIntPreference(pyauto.kRestoreOnStartup, 1)
+ self.SetPrefs(pyauto.kRestoreOnStartup, 1)
logging.debug('Setting %s to 1' % pyauto.kRestoreOnStartup)
- self.CloseBrowserAndServer() # Close browser
- self.set_clear_profile(False) # Do not clear profile on next startup
- self.LaunchBrowserAndServer() # Reopen browser
+ self.RestartBrowser(clear_profile=False)
+ # Verify
+ self.assertEqual(self.GetPrefsInfo().Prefs(pyauto.kRestoreOnStartup), 1)
self.assertEqual(num_tabs, self.GetTabCount())
self.ActivateTab(0)
self.assertEqual(url1, self.GetActiveTabURL().spec())
self.ActivateTab(1)
self.assertEqual(url2, self.GetActiveTabURL().spec())
- self.set_clear_profile(True) # Restore the flag to clear profile next
+
+ def Debug(self):
+ """Test method for experimentation.
+
+ This method will not run automatically.
+ """
+ import pprint
+ pp = pprint.PrettyPrinter(indent=2)
+ while True:
+ raw_input('Interact with the browser and hit <enter> to dump prefs... ')
+ pp.pprint(self.GetPrefsInfo().Prefs())
+
+ def testSessionRestoreURLs(self):
+ """Verify restore URLs preference."""
+ url1 = self.GetFileURLForPath(os.path.join(self.DataDir(), 'title1.html'))
+ url2 = self.GetFileURLForPath(os.path.join(self.DataDir(), 'title2.html'))
+ # Set pref to restore given URLs on startup
+ self.SetPrefs(pyauto.kRestoreOnStartup, 4) # 4 is for restoring URLs
+ self.SetPrefs(pyauto.kURLsToRestoreOnStartup, [url1, url2])
+ self.RestartBrowser(clear_profile=False)
+ # Verify
+ self.assertEqual(self.GetPrefsInfo().Prefs(pyauto.kRestoreOnStartup), 4)
+ self.assertEqual(2, self.GetTabCount())
+ self.ActivateTab(0)
+ self.assertEqual(url1, self.GetActiveTabURL().spec())
+ self.ActivateTab(1)
+ self.assertEqual(url2, self.GetActiveTabURL().spec())
if __name__ == '__main__':
diff --git a/chrome/test/pyautolib/prefs_info.py b/chrome/test/pyautolib/prefs_info.py
new file mode 100644
index 0000000..8b7204d
--- /dev/null
+++ b/chrome/test/pyautolib/prefs_info.py
@@ -0,0 +1,101 @@
+#!/usr/bin/python
+
+# 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.
+
+"""Python representation for Chromium Preferences.
+
+Obtain one of these from PyUITestSuite::GetPrefsInfo() call.
+
+Example:
+class MyTest(pyauto.PyUITest):
+ def testBasic(self):
+ info = self.GetPrefsInfo() # fetch prefs snapshot
+ print info.Prefs() # all prefs
+ print info.Prefs('session.restore_on_startup') # a single pref
+
+See more tests in chrome/test/functional/prefs.py.
+"""
+
+import simplejson as json
+
+from pyauto_errors import JSONInterfaceError
+
+
+class PrefsInfo(object):
+ """Represent info for Chromium preferences.
+
+ The info is represented as a hierarchy of prefs values.
+ The values could be plain (integer, bool, float) or complex (like
+ dictionary, list).
+ """
+ def __init__(self, json_string):
+ """Initialize a PrefsInfo from a json string.
+
+ Args:
+ json_string: a json string, as returned by a json ipc call for the
+ command 'GetPrefsInfo'
+ A typical string representing prefs snapshot looks like:
+ { u'prefs':
+ { u'alternate_error_pages': {u'enabled': True},
+ u'autofill': { u'auxiliary_profiles_enabled': False,
+ u'default_creditcard': u'',
+ u'default_profile': u'',
+ u'enabled': True,
+ u'infobar_shown': False,
+ u'negative_upload_rate': 0.01,
+ u'positive_upload_rate': 0.01},
+ u'bookmark_bar': {u'show_on_all_tabs': False},
+ ...
+ ...
+ }
+ }
+
+ Raises:
+ pyauto_errors.JSONInterfaceError if the automation call returns an error.
+ """
+ # JSON string prepared in PrefsInfo() in automation_provider.cc
+ self.prefsdict = json.loads(json_string)
+ if self.prefsdict.has_key('error'):
+ raise JSONInterfaceError(self.prefsdict['error'])
+
+ def Prefs(self, path=None):
+ """Get preferences.
+
+ The preference dictionary (when using path=None) looks like:
+
+ { u'alternate_error_pages': {u'enabled': True},
+ u'autofill': { u'auxiliary_profiles_enabled': False,
+ u'default_creditcard': u'',
+ u'default_profile': u'',
+ u'enabled': True,
+ u'infobar_shown': False,
+ u'negative_upload_rate': 0.01,
+ u'positive_upload_rate': 0.01},
+ u'bookmark_bar': {u'show_on_all_tabs': False},
+ ...
+ ...
+ }
+
+ In this case, to fetch the preference value for autofill enabled, use
+ 'autofill.enabled' as the path.
+
+ Args:
+ path: If specified, return the preference item for the given path.
+ path is a dot-separated string like "session.restore_on_startup".
+ One of the equivalent names in chrome/common/pref_names.h could
+ also be used.
+
+ Returns:
+ preference value. It could be a dictionary (like the example above), a
+ list or a plain value.
+ None, if prefernece for path not found (if path is given).
+ """
+ all = self.prefsdict.get('prefs', {})
+ if not path: # No path given. Return all prefs.
+ return all
+ for part in path.split('.'): # Narrow down to the requested prefs path.
+ all = all.get(part)
+ if all is None: return None
+ return all
diff --git a/chrome/test/pyautolib/pyauto.py b/chrome/test/pyautolib/pyauto.py
index 4575a73..b00f071 100644
--- a/chrome/test/pyautolib/pyauto.py
+++ b/chrome/test/pyautolib/pyauto.py
@@ -74,6 +74,8 @@ except ImportError:
import bookmark_model
import download_info
import history_info
+import prefs_info
+from pyauto_errors import JSONInterfaceError
import simplejson as json # found in third_party
@@ -230,6 +232,50 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase):
return download_info.DownloadInfo(
self._SendJSONRequest(0, json.dumps({'command': 'GetDownloadsInfo'})))
+ def GetPrefsInfo(self):
+ """Return info about preferences.
+
+ This represents a snapshot of the preferences. If you expect preferences
+ to have changed, you need to call this method again to get a fresh
+ snapshot.
+
+ Returns:
+ an instance of prefs_info.PrefsInfo
+ """
+ return prefs_info.PrefsInfo(
+ self._SendJSONRequest(0, json.dumps({'command': 'GetPrefsInfo'})))
+
+ def SetPrefs(self, path, value):
+ """Set preference for the given path.
+
+ Preferences are stored by Chromium as a hierarchical dictionary.
+ dot-separated paths can be used to refer to a particular preference.
+ example: "session.restore_on_startup"
+
+ Some preferences are managed, that is, they cannot be changed by the
+ user. It's upto the user to know which ones can be changed. Typically,
+ the options available via Chromium preferences can be changed.
+
+ Args:
+ path: the path the preference key that needs to be changed
+ example: "session.restore_on_startup"
+ One of the equivalent names in chrome/common/pref_names.h could
+ also be used.
+ value: the value to be set. It could be plain values like int, bool,
+ string or complex ones like list.
+ The user has to ensure that the right value is specified for the
+ right key. It's useful to dump the preferences first to determine
+ what type is expected for a particular preference path.
+ """
+ cmd_dict = {
+ 'command': 'SetPrefs',
+ 'path': path,
+ 'value': value,
+ }
+ ret_dict = json.loads(self._SendJSONRequest(0, json.dumps(cmd_dict)))
+ if ret_dict.has_key('error'):
+ raise JSONInterfaceError(ret_dict['error'])
+
def WaitForAllDownloadsToComplete(self):
"""Wait for all downloads to complete."""
# Implementation detail: uses the generic "JSON command" model
diff --git a/chrome/test/pyautolib/pyautolib.i b/chrome/test/pyautolib/pyautolib.i
index 7156df6..1c36526 100644
--- a/chrome/test/pyautolib/pyautolib.i
+++ b/chrome/test/pyautolib/pyautolib.i
@@ -93,20 +93,6 @@ class BrowserProxy {
%feature("docstring", "Get proxy to the tab at the given zero-based index")
GetTab;
scoped_refptr<TabProxy> GetTab(int tab_index) const;
-
- // Prefs
- %feature("docstring", "Sets the int value of the specified preference. "
- "Refer chrome/common/pref_names.h for the list of prefs.")
- SetIntPreference;
- bool SetIntPreference(const std::wstring& name, int value);
- %feature("docstring", "Sets the string value of the specified preference. "
- "Refer chrome/common/pref_names.h for the list of prefs.")
- SetStringPreference;
- bool SetStringPreference(const std::wstring& name, const std::wstring& value);
- %feature("docstring", "Sets the boolean value of the specified preference. "
- "Refer chrome/common/pref_names.h for the list of prefs.")
- SetBooleanPreference;
- bool SetBooleanPreference(const std::wstring& name, bool value);
};
// TabProxy