summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornirnimesh@chromium.org <nirnimesh@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-25 21:09:14 +0000
committernirnimesh@chromium.org <nirnimesh@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-25 21:09:14 +0000
commitef413cad1e7daa23b6b52062066462d4e76f2374 (patch)
tree9228a268fdcf652aae0d2c2da449ba4081232903
parent8e27873fcab3f343096e43ffa72f4ee78597380c (diff)
downloadchromium_src-ef413cad1e7daa23b6b52062066462d4e76f2374.zip
chromium_src-ef413cad1e7daa23b6b52062066462d4e76f2374.tar.gz
chromium_src-ef413cad1e7daa23b6b52062066462d4e76f2374.tar.bz2
Fetch a bunch of info from the browser
This includes info about the browser/renderer/extension/other PIDs, window size. Add a method to set window size. Add tests to verify window size, and verify flash loading. BUG=43234 TEST=python chrome/test/functional/browser.py Review URL: http://codereview.chromium.org/2133013 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@48192 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/automation/automation_provider.cc121
-rw-r--r--chrome/browser/automation/automation_provider.h6
-rw-r--r--chrome/test/functional/PYAUTO_TESTS1
-rw-r--r--chrome/test/functional/browser.py35
-rw-r--r--chrome/test/pyautolib/pyauto.py82
5 files changed, 224 insertions, 21 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc
index 4dc12d3..eb165e1 100644
--- a/chrome/browser/automation/automation_provider.cc
+++ b/chrome/browser/automation/automation_provider.cc
@@ -34,6 +34,7 @@
#include "chrome/browser/blocked_popup_container.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/bookmarks/bookmark_storage.h"
+#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/browsing_data_remover.h"
@@ -46,6 +47,7 @@
#include "chrome/browser/download/save_package.h"
#include "chrome/browser/extensions/crx_installer.h"
#include "chrome/browser/extensions/extension_browser_event_router.h"
+#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_install_ui.h"
#include "chrome/browser/extensions/extension_message_service.h"
#include "chrome/browser/extensions/extension_tabs_module.h"
@@ -1592,6 +1594,30 @@ void AutomationProvider::RemoveBookmark(int handle,
*success = false;
}
+// Sample json input: { "command": "SetWindowDimensions",
+// "x": 20, # optional
+// "y": 20, # optional
+// "width": 800, # optional
+// "height": 600 } # optional
+void AutomationProvider::SetWindowDimensions(Browser* browser,
+ DictionaryValue* args,
+ IPC::Message* reply_message) {
+ gfx::Rect rect = browser->window()->GetRestoredBounds();
+ int x, y, width, height;
+ if (args->GetInteger(L"x", &x))
+ rect.set_x(x);
+ if (args->GetInteger(L"y", &y))
+ rect.set_y(y);
+ if (args->GetInteger(L"width", &width))
+ rect.set_width(width);
+ if (args->GetInteger(L"height", &height))
+ rect.set_height(height);
+ browser->window()->SetBounds(rect);
+ AutomationMsg_SendJSONRequest::WriteReplyParams(
+ reply_message, std::string("{}"), true);
+ Send(reply_message);
+}
+
// Sample json input: { "command": "GetBrowserInfo" }
// Refer to GetBrowserInfo() in chrome/test/pyautolib/pyauto.py for
// sample json output.
@@ -1615,17 +1641,98 @@ void AutomationProvider::GetBrowserInfo(Browser* browser,
properties->SetString(L"command_line_string",
CommandLine::ForCurrentProcess()->command_line_string());
#elif defined(OS_POSIX)
- std::string command_line_string;
- const std::vector<std::string>& argv =
- CommandLine::ForCurrentProcess()->argv();
- for (uint i = 0; i < argv.size(); ++i)
- command_line_string += argv[i] + " ";
- properties->SetString(L"command_line_string", command_line_string);
+ properties->SetString(L"command_line_string",
+ JoinString(CommandLine::ForCurrentProcess()->argv(), ' '));
#endif
scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
return_value->Set(L"properties", properties);
+ return_value->SetInteger(L"browser_pid", base::GetCurrentProcId());
+ // Add info about all windows in a list of dictionaries, one dictionary
+ // item per window.
+ ListValue* windows = new ListValue;
+ int windex = 0;
+ for (BrowserList::const_iterator it = BrowserList::begin();
+ it != BrowserList::end();
+ ++it, ++windex) {
+ DictionaryValue* browser_item = new DictionaryValue;
+ browser = *it;
+ browser_item->SetInteger(L"index", windex);
+ // Window properties
+ gfx::Rect rect = browser->window()->GetRestoredBounds();
+ browser_item->SetInteger(L"x", rect.x());
+ browser_item->SetInteger(L"y", rect.y());
+ browser_item->SetInteger(L"width", rect.width());
+ browser_item->SetInteger(L"height", rect.height());
+ browser_item->SetBoolean(L"fullscreen",
+ browser->window()->IsFullscreen());
+ browser_item->SetInteger(L"selected_tab", browser->selected_index());
+ browser_item->SetBoolean(L"incognito",
+ browser->profile()->IsOffTheRecord());
+ // For each window, add info about all tabs in a list of dictionaries,
+ // one dictionary item per tab.
+ ListValue* tabs = new ListValue;
+ for (int i = 0; i < browser->tab_count(); ++i) {
+ TabContents* tc = browser->GetTabContentsAt(i);
+ DictionaryValue* tab = new DictionaryValue;
+ tab->SetInteger(L"index", i);
+ tab->SetString(L"url", tc->GetURL().spec());
+ tab->SetInteger(L"renderer_pid",
+ base::GetProcId(tc->GetRenderProcessHost()->GetHandle()));
+ tab->SetInteger(L"num_infobars", tc->infobar_delegate_count());
+ tabs->Append(tab);
+ }
+ browser_item->Set(L"tabs", tabs);
+
+ windows->Append(browser_item);
+ }
+ return_value->Set(L"windows", windows);
+
+ return_value->SetString(L"child_process_path",
+ ChildProcessHost::GetChildPath(true).value());
+ // Child processes are the processes for plugins and other workers.
+ // Add all child processes in a list of dictionaries, one dictionary item
+ // per child process.
+ ListValue* child_processes = new ListValue;
+ for (ChildProcessHost::Iterator iter; !iter.Done(); ++iter) {
+ // Only add processes which are already started, since we need their handle.
+ if ((*iter)->handle() != base::kNullProcessHandle) {
+ ChildProcessInfo* info = *iter;
+ DictionaryValue* item = new DictionaryValue;
+ item->SetString(L"name", info->name());
+ item->SetString(L"type",
+ ChildProcessInfo::GetTypeNameInEnglish(info->type()));
+ item->SetInteger(L"pid", base::GetProcId(info->handle()));
+ child_processes->Append(item);
+ }
+ }
+ return_value->Set(L"child_processes", child_processes);
+
+ // Add all extension processes in a list of dictionaries, one dictionary
+ // item per extension process.
+ ListValue* extension_processes = new ListValue;
+ ProfileManager* profile_manager = g_browser_process->profile_manager();
+ for (ProfileManager::const_iterator it = profile_manager->begin();
+ it != profile_manager->end(); ++it) {
+ ExtensionProcessManager* process_manager =
+ (*it)->GetExtensionProcessManager();
+ ExtensionProcessManager::const_iterator jt;
+ for (jt = process_manager->begin(); jt != process_manager->end(); ++jt) {
+ ExtensionHost* ex_host = *jt;
+ // Don't add dead extension processes.
+ if (!ex_host->IsRenderViewLive())
+ continue;
+ DictionaryValue* item = new DictionaryValue;
+ item->SetString(L"name", ex_host->extension()->name());
+ item->SetInteger(
+ L"pid",
+ base::GetProcId(ex_host->render_process_host()->GetHandle()));
+ extension_processes->Append(item);
+ }
+ }
+ return_value->Set(L"extension_processes", extension_processes);
+
base::JSONWriter::Write(return_value.get(), false, &json_return);
AutomationMsg_SendJSONRequest::WriteReplyParams(
reply_message, json_return, reply_return);
@@ -2136,6 +2243,8 @@ void AutomationProvider::SendJSONRequest(int handle,
handler_map["GetPrefsInfo"] = &AutomationProvider::GetPrefsInfo;
handler_map["SetPrefs"] = &AutomationProvider::SetPrefs;
+ handler_map["SetWindowDimensions"] = &AutomationProvider::SetWindowDimensions;
+
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 fb23506..59be59f 100644
--- a/chrome/browser/automation/automation_provider.h
+++ b/chrome/browser/automation/automation_provider.h
@@ -334,6 +334,12 @@ class AutomationProvider : public base::RefCounted<AutomationProvider>,
int64 id,
bool* success);
+ // Set window dimensions.
+ // Uses the JSON interface for input/output.
+ void SetWindowDimensions(Browser* browser,
+ DictionaryValue* args,
+ IPC::Message* reply_message);
+
// Get info about the chromium/chrome in use.
// This includes things like version, executable name, executable path.
// Uses the JSON interface for input/output.
diff --git a/chrome/test/functional/PYAUTO_TESTS b/chrome/test/functional/PYAUTO_TESTS
index a0c80c0..656f2b99 100644
--- a/chrome/test/functional/PYAUTO_TESTS
+++ b/chrome/test/functional/PYAUTO_TESTS
@@ -44,6 +44,7 @@
'linux': [
'-omnibox', # http://crbug.com/44203
+ '-browser.BrowserTest.testWindowResize', # crbug.com/44963
],
# TODO(nirnimesh): Add a ChromeOS section
diff --git a/chrome/test/functional/browser.py b/chrome/test/functional/browser.py
index 7d2b08b..05aea1e 100644
--- a/chrome/test/functional/browser.py
+++ b/chrome/test/functional/browser.py
@@ -3,6 +3,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import os
import re
import pyauto_functional # Must be imported before pyauto
@@ -21,14 +22,38 @@ class BrowserTest(pyauto.PyUITest):
pp = pprint.PrettyPrinter(indent=2)
while True:
raw_input('Hit <enter> to dump info.. ')
- properties = self.GetBrowserInfo()
- self.assertTrue(properties)
- pp.pprint(properties)
+ info = self.GetBrowserInfo()
+ pp.pprint(info)
def testGotVersion(self):
"""Verify there's a valid version string."""
- version_string = self.GetBrowserInfo()['ChromeVersion']
- self.assertTrue(re.match("\d+\.\d+\.\d+.\.\d+", version_string))
+ version_string = self.GetBrowserInfo()['properties']['ChromeVersion']
+ self.assertTrue(re.match('\d+\.\d+\.\d+.\.\d+', version_string))
+
+ def testWindowResize(self):
+ """Verify window resizing and persistence after restart."""
+ def _VerifySize(x, y, width, height):
+ info = self.GetBrowserInfo()
+ self.assertEqual(x, info['windows'][0]['x'])
+ self.assertEqual(y, info['windows'][0]['y'])
+ self.assertEqual(width, info['windows'][0]['width'])
+ self.assertEqual(height, info['windows'][0]['height'])
+ self.SetWindowDimensions(x=20, y=40, width=600, height=300)
+ _VerifySize(20, 40, 600, 300)
+ self.RestartBrowser(clear_profile=False)
+ _VerifySize(20, 40, 600, 300)
+
+ def testCanLoadFlash(self):
+ """Verify that we can play Flash.
+
+ We merely check that the flash process kicks in.
+ """
+ flash_url = self.GetFileURLForPath(os.path.join(self.DataDir(),
+ 'plugin', 'flash.swf'))
+ self.NavigateToURL(flash_url)
+ child_processes = self.GetBrowserInfo()['child_processes']
+ self.assertTrue([x for x in child_processes
+ if x['type'] == 'Plug-in' and x['name'] == 'Shockwave Flash'])
if __name__ == '__main__':
diff --git a/chrome/test/pyautolib/pyauto.py b/chrome/test/pyautolib/pyauto.py
index 42102402..3ef206c 100644
--- a/chrome/test/pyautolib/pyauto.py
+++ b/chrome/test/pyautolib/pyauto.py
@@ -434,24 +434,86 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase):
self.assertTrue(self.WaitUntil(
lambda: len(self.GetDownloadsInfo().Downloads()) == num_downloads + 1))
+ def SetWindowDimensions(
+ self, x=None, y=None, width=None, height=None, windex=0):
+ """Set window dimensions.
+
+ All args are optional and current values will be preserved.
+ Arbitrarily large values will be handled gracefully by the browser.
+
+ Args:
+ x: window origin x
+ y: window origin y
+ width: window width
+ height: window height
+ windex: window index to work on. Defaults to 0 (first window)
+ """
+ cmd_dict = { # Prepare command for the json interface
+ 'command': 'SetWindowDimensions',
+ }
+ if x:
+ cmd_dict['x'] = x
+ if y:
+ cmd_dict['y'] = y
+ if width:
+ cmd_dict['width'] = width
+ if height:
+ cmd_dict['height'] = height
+ ret_dict = json.loads(self._SendJSONRequest(0, json.dumps(cmd_dict)))
+ if ret_dict.has_key('error'):
+ raise JSONInterfaceError(ret_dict['error'])
+ return ret_dict
+
def GetBrowserInfo(self):
"""Return info about the browser.
This includes things like the version number, the executable name,
- executable path, and so on.
+ executable path, pid info about the renderer/plugin/extension processes,
+ window dimensions. (See sample below)
Returns:
- a dictionary of properties about the browser
+ a dictionary
+
Sample:
- { u'BrowserProcessExecutableName': u'Chromium',
- u'BrowserProcessExecutablePath': u'Chromium.app/Contents/'
- 'MacOS/Chromium',
- u'ChromeVersion': u'6.0.401.0',
+ { u'browser_pid': 93737,
+ # Child processes are the processes for plugins and other workers.
+ u'child_process_path': u'.../Chromium.app/Contents/'
+ 'Versions/6.0.412.0/Chromium Helper.app/'
+ 'Contents/MacOS/Chromium Helper',
+ u'child_processes': [ { u'name': u'Shockwave Flash',
+ u'pid': 93766,
+ u'type': u'Plug-in'}],
+ # There's one extension process per extension.
+ u'extension_processes': [
+ { u'name': u'Webpage Screenshot', u'pid': 93938},
+ { u'name': u'Google Voice (by Google)', u'pid': 93852}],
+ u'properties': {
+ u'BrowserProcessExecutableName': u'Chromium',
+ u'BrowserProcessExecutablePath': u'Chromium.app/Contents/MacOS/'
+ 'Chromium',
+ u'ChromeVersion': u'6.0.412.0',
u'HelperProcessExecutableName': u'Chromium Helper',
u'HelperProcessExecutablePath': u'Chromium Helper.app/Contents/'
- 'MacOS/Chromium Helper',
- u'command_line_string': "command_line_string --with-flags"
- }
+ 'MacOS/Chromium Helper',
+ u'command_line_string': "COMMAND_LINE_STRING --WITH-FLAGS"},
+ # The order of the windows and tabs listed here will be the same as
+ # what shows up on screen.
+ u'windows': [ { u'index': 0,
+ u'height': 1134,
+ u'incognito': False,
+ u'is_fullscreen': False,
+ u'selected_tab': 0,
+ u'tabs': [ { u'index': 0,
+ u'num_infobars': 0,
+ u'renderer_pid': 93747,
+ u'url': u'http://www.google.com/'},
+ { u'index': 1,
+ u'num_infobars': 0,
+ u'renderer_pid': 93919,
+ u'url': u'https://chrome.google.com/'}],
+ u'width': 925,
+ u'x': 26,
+ u'y': 44}]}
Raises:
pyauto_errors.JSONInterfaceError if the automation call returns an error.
@@ -462,7 +524,7 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase):
ret_dict = json.loads(self._SendJSONRequest(0, json.dumps(cmd_dict)))
if ret_dict.has_key('error'):
raise JSONInterfaceError(ret_dict['error'])
- return ret_dict['properties']
+ return ret_dict
def GetHistoryInfo(self, search_text=''):
"""Return info about browsing history.