diff options
author | nirnimesh@chromium.org <nirnimesh@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-06 08:17:05 +0000 |
---|---|---|
committer | nirnimesh@chromium.org <nirnimesh@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-06 08:17:05 +0000 |
commit | f7d48015503c80e2f29df6a59b39a179649a6a5f (patch) | |
tree | 42e2bebe5b47cb7448c6ee6e4deffa6e2fbcf1c7 /chrome | |
parent | 03e32def91b569982af74094c51651924d38e70c (diff) | |
download | chromium_src-f7d48015503c80e2f29df6a59b39a179649a6a5f.zip chromium_src-f7d48015503c80e2f29df6a59b39a179649a6a5f.tar.gz chromium_src-f7d48015503c80e2f29df6a59b39a179649a6a5f.tar.bz2 |
Add hooks to fetch about:plugins info for PyAuto.
Also, hooks for to enable/disable a plugin.
Add a test which excercises them.
Review URL: http://codereview.chromium.org/1935003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@46553 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/automation/automation_provider.cc | 105 | ||||
-rw-r--r-- | chrome/browser/automation/automation_provider.h | 12 | ||||
-rw-r--r-- | chrome/test/functional/PYAUTO_TESTS | 1 | ||||
-rw-r--r-- | chrome/test/functional/plugins.py | 44 | ||||
-rw-r--r-- | chrome/test/pyautolib/plugins_info.py | 115 | ||||
-rw-r--r-- | chrome/test/pyautolib/pyauto.py | 44 |
6 files changed, 320 insertions, 1 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc index b43ef22..24cff0f 100644 --- a/chrome/browser/automation/automation_provider.cc +++ b/chrome/browser/automation/automation_provider.cc @@ -85,6 +85,7 @@ #include "net/url_request/url_request_context.h" #include "chrome/browser/automation/ui_controls.h" #include "views/event.h" +#include "webkit/glue/plugins/plugin_list.h" #if defined(OS_WIN) #include "chrome/browser/external_tab_container.h" @@ -1773,6 +1774,102 @@ void AutomationProvider::SetPrefs(DictionaryValue* args, Send(reply_message); } +// Sample json input: { "command": "GetPluginsInfo" } +// Refer chrome/test/pyautolib/plugins_info.py for sample json output. +void AutomationProvider::GetPluginsInfo(DictionaryValue* args, + IPC::Message* reply_message) { + std::string json_return; + bool reply_return = true; + + std::vector<WebPluginInfo> plugins; + NPAPI::PluginList::Singleton()->GetPlugins(false, &plugins); + ListValue* items = new ListValue; + for (std::vector<WebPluginInfo>::const_iterator it = plugins.begin(); + it != plugins.end(); + ++it) { + DictionaryValue* item = new DictionaryValue; + item->SetString(L"name", it->name); + item->SetString(L"path", it->path.value()); + item->SetString(L"version", it->version); + item->SetString(L"desc", it->desc); + item->SetBoolean(L"enabled", it->enabled); + // Add info about mime types. + ListValue* mime_types = new ListValue(); + for (std::vector<WebPluginMimeType>::const_iterator type_it = + it->mime_types.begin(); + type_it != it->mime_types.end(); + ++type_it) { + DictionaryValue* mime_type = new DictionaryValue(); + mime_type->SetString(L"mimeType", type_it->mime_type); + mime_type->SetString(L"description", type_it->description); + + ListValue* file_extensions = new ListValue(); + for (std::vector<std::string>::const_iterator ext_it = + type_it->file_extensions.begin(); + ext_it != type_it->file_extensions.end(); + ++ext_it) { + file_extensions->Append(new StringValue(*ext_it)); + } + mime_type->Set(L"fileExtensions", file_extensions); + + mime_types->Append(mime_type); + } + item->Set(L"mimeTypes", mime_types); + items->Append(item); + } + scoped_ptr<DictionaryValue> return_value(new DictionaryValue); + return_value->Set(L"plugins", 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": "EnablePlugin", +// "path": "/Library/Internet Plug-Ins/Flash Player.plugin" } +void AutomationProvider::EnablePlugin(DictionaryValue* args, + IPC::Message* reply_message) { + std::string json_return = "{}"; + bool reply_return = true; + FilePath::StringType path; + if (!args->GetString(L"path", &path)) { + json_return = "{\"error\": \"path not specified.\"}"; + reply_return = false; + } else if (!NPAPI::PluginList::Singleton()->EnablePlugin(FilePath(path))) { + json_return = StringPrintf("{\"error\": \"Could not enable plugin" + " for path %s.\"}", path.c_str()); + reply_return = false; + } + + AutomationMsg_SendJSONRequest::WriteReplyParams( + reply_message, json_return, reply_return); + Send(reply_message); +} + +// Sample json input: +// { "command": "DisablePlugin", +// "path": "/Library/Internet Plug-Ins/Flash Player.plugin" } +void AutomationProvider::DisablePlugin(DictionaryValue* args, + IPC::Message* reply_message) { + std::string json_return = "{}"; + bool reply_return = true; + FilePath::StringType path; + if (!args->GetString(L"path", &path)) { + json_return = "{\"error\": \"path not specified.\"}"; + reply_return = false; + } else if (!NPAPI::PluginList::Singleton()->DisablePlugin(FilePath(path))) { + json_return = StringPrintf("{\"error\": \"Could not enable plugin" + " for path %s.\"}", path.c_str()); + reply_return = false; + } + + AutomationMsg_SendJSONRequest::WriteReplyParams( + reply_message, json_return, reply_return); + Send(reply_message); +} + void AutomationProvider::SendJSONRequest( int handle, std::string json_request, @@ -1813,10 +1910,16 @@ void AutomationProvider::SendJSONRequest( // Map json commands to their handlers. std::map<std::string, JsonHandler> handler_map; - handler_map["GetDownloadsInfo"] = &AutomationProvider::GetDownloadsInfo; + handler_map["DisablePlugin"] = &AutomationProvider::DisablePlugin; + handler_map["EnablePlugin"] = &AutomationProvider::EnablePlugin; + handler_map["GetPluginsInfo"] = &AutomationProvider::GetPluginsInfo; + handler_map["GetHistoryInfo"] = &AutomationProvider::GetHistoryInfo; + handler_map["GetPrefsInfo"] = &AutomationProvider::GetPrefsInfo; handler_map["SetPrefs"] = &AutomationProvider::SetPrefs; + + handler_map["GetDownloadsInfo"] = &AutomationProvider::GetDownloadsInfo; handler_map["WaitForAllDownloadsToComplete"] = &AutomationProvider::WaitForDownloadsToComplete; diff --git a/chrome/browser/automation/automation_provider.h b/chrome/browser/automation/automation_provider.h index 518eb8b..83b52e6 100644 --- a/chrome/browser/automation/automation_provider.h +++ b/chrome/browser/automation/automation_provider.h @@ -353,6 +353,18 @@ class AutomationProvider : public base::RefCounted<AutomationProvider>, // Uses the JSON interface for input/output. void GetPrefsInfo(DictionaryValue* args, IPC::Message* reply_message); + // Get info about plugins. + // Uses the JSON interface for input/output. + void GetPluginsInfo(DictionaryValue* args, IPC::Message* reply_message); + + // Enable a plugin. + // Uses the JSON interface for input/output. + void EnablePlugin(DictionaryValue* args, IPC::Message* reply_message); + + // Disable a plugin. + // Uses the JSON interface for input/output. + void DisablePlugin(DictionaryValue* args, IPC::Message* reply_message); + // Set prefs. // Uses the JSON interface for input/output. void SetPrefs(DictionaryValue* args, IPC::Message* reply_message); diff --git a/chrome/test/functional/PYAUTO_TESTS b/chrome/test/functional/PYAUTO_TESTS index c556fc0..146f039 100644 --- a/chrome/test/functional/PYAUTO_TESTS +++ b/chrome/test/functional/PYAUTO_TESTS @@ -22,6 +22,7 @@ 'downloads', 'history', 'navigation', + 'plugins', 'prefs', 'special_tabs', 'test_basic.SimpleTest.testCanOpenGoogle', diff --git a/chrome/test/functional/plugins.py b/chrome/test/functional/plugins.py new file mode 100644 index 0000000..4ac9267 --- /dev/null +++ b/chrome/test/functional/plugins.py @@ -0,0 +1,44 @@ +#!/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. + +import pyauto_functional # Must be imported before pyauto +import pyauto + + +class PluginsTest(pyauto.PyUITest): + """TestCase for Plugins.""" + + 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 list plugins... ') + pp.pprint(self.GetPluginsInfo().Plugins()) + + def testHasFlash(self): + """Verify that Flash plugin loads and is enabled.""" + flash = self.GetPluginsInfo().FirstPluginForName('Shockwave Flash') + self.assertTrue(flash) + self.assertTrue(flash['enabled']) + + def testEnableDisableFlash(self): + """Verify that flash plugin can be enabled/disabled.""" + flash = self.GetPluginsInfo().FirstPluginForName('Shockwave Flash') + self.assertTrue(flash['enabled']) + self.DisablePlugin(flash['path']) + flash = self.GetPluginsInfo().FirstPluginForName('Shockwave Flash') + self.assertFalse(flash['enabled']) + self.EnablePlugin(flash['path']) + flash = self.GetPluginsInfo().FirstPluginForName('Shockwave Flash') + self.assertTrue(flash['enabled']) + + +if __name__ == '__main__': + pyauto_functional.Main() + diff --git a/chrome/test/pyautolib/plugins_info.py b/chrome/test/pyautolib/plugins_info.py new file mode 100644 index 0000000..6cf8620 --- /dev/null +++ b/chrome/test/pyautolib/plugins_info.py @@ -0,0 +1,115 @@ +#!/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 Plugins info. + +This is the info available at about:plugins. +Obtain one of these from PyUITestSuite::GetPluginsInfo() call. + +Example: +class MyTest(pyauto.PyUITest): + def testBasic(self): + info = self.GetPluginsInfo() # fetch plugins snapshot + print info.Plugins() + +See more examples in chrome/test/functional/plugins.py. +""" + +import simplejson as json + +from pyauto_errors import JSONInterfaceError + + +class PluginsInfo(object): + """Represent info for Chromium plugins. + + The info is represented as a list of dictionaries, one for each plugin. + """ + def __init__(self, json_string): + """Initialize a PluginsInfo from a json string. + + Args: + json_string: a json string, as returned by a json ipc call for the + command 'GetPluginsInfo' + + Raises: + pyauto_errors.JSONInterfaceError if the automation call returns an error. + """ + # JSON string prepared in GetPluginsInfo() in automation_provider.cc + self.pluginsdict = json.loads(json_string) + if self.pluginsdict.has_key('error'): + raise JSONInterfaceError(self.pluginsdict['error']) + + def Plugins(self): + """Get plugins. + + Returns: + a list of plugins info + Sample: + [ { u'desc': u'Shockwave Flash 10.0 r45', + u'enabled': True, + u'mimeTypes': [ { u'description': u'Shockwave Flash', + u'fileExtensions': [u'swf'], + u'mimeType': u'application/x-shockwave-flash'}, + { u'description': u'FutureSplash Player', + u'fileExtensions': [u'spl'], + u'mimeType': u'application/futuresplash'}], + u'name': u'Shockwave Flash', + u'path': u'/Library/Internet Plug-Ins/Flash Player.plugin', + u'version': u'10.0.45.2'}, + { u'desc': u'Version 1.1.2.9282', + u'enabled': True, + u'mimeTypes': [ { u'description': u'Google voice and video chat', + u'fileExtensions': [u'googletalk'], + u'mimeType': u'application/googletalk'}], + u'name': u'Google Talk NPAPI Plugin', + u'path': u'/Library/Internet Plug-Ins/googletalkbrowserplugin.plugin', + u'version': u'1.1.2.9282'}, + ..., + ..., + ] + """ + return self.pluginsdict.get('plugins', []) + + def PluginForPath(self, path): + """Get plugin info for the given plugin path. + + Returns: + a dictionary of info for the plugin. + """ + got = filter(lambda x: x['path'] == path, self.Plugins()) + if not got: return None + return got[0] + + def PluginForName(self, name): + """Get plugin info for the given name. + + There might be several plugins with the same name. + + Args: + name: the name for which to look for. + + Returns: + a list of info dictionaries for each plugin found with the given name. + """ + return filter(lambda x: x['name'] == name, self.Plugins()) + + def FirstPluginForName(self, name): + """Get plugin info for the first plugin with the given name. + + This is useful in case there are multiple plugins for a name. + + Args: + name: the name for which to look for. + + Returns: + a plugin info dictionary + None, if not found + """ + all = self.PluginForName(name) + if not all: return None + return all[0] + diff --git a/chrome/test/pyautolib/pyauto.py b/chrome/test/pyautolib/pyauto.py index ddf6bc9..6438c5f 100644 --- a/chrome/test/pyautolib/pyauto.py +++ b/chrome/test/pyautolib/pyauto.py @@ -74,6 +74,7 @@ except ImportError: import bookmark_model import download_info import history_info +import plugins_info import prefs_info from pyauto_errors import JSONInterfaceError import simplejson as json # found in third_party @@ -329,6 +330,49 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase): return history_info.HistoryInfo( self._SendJSONRequest(0, json.dumps(cmd_dict))) + def GetPluginsInfo(self): + """Return info about plugins. + + This is the info available from about:plugins + + Returns: + an instance of plugins_info.PluginsInfo + """ + return plugins_info.PluginsInfo( + self._SendJSONRequest(0, json.dumps({'command': 'GetPluginsInfo'}))) + + def EnablePlugin(self, path): + """Enable the plugin at the given path. + + Use GetPluginsInfo() to fetch path info about a plugin. + + Raises: + pyauto_errors.JSONInterfaceError if the automation call returns an error. + """ + cmd_dict = { + 'command': 'EnablePlugin', + 'path': path, + } + ret_dict = json.loads(self._SendJSONRequest(0, json.dumps(cmd_dict))) + if ret_dict.has_key('error'): + raise JSONInterfaceError(ret_dict['error']) + + def DisablePlugin(self, path): + """Disable the plugin at the given path. + + Use GetPluginsInfo() to fetch path info about a plugin. + + Raises: + pyauto_errors.JSONInterfaceError if the automation call returns an error. + """ + cmd_dict = { + 'command': 'DisablePlugin', + 'path': path, + } + ret_dict = json.loads(self._SendJSONRequest(0, json.dumps(cmd_dict))) + if ret_dict.has_key('error'): + raise JSONInterfaceError(ret_dict['error']) + class PyUITestSuite(pyautolib.PyUITestSuiteBase, unittest.TestSuite): """Base TestSuite for PyAuto UI tests.""" |