diff options
author | nirnimesh@chromium.org <nirnimesh@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-25 21:09:14 +0000 |
---|---|---|
committer | nirnimesh@chromium.org <nirnimesh@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-25 21:09:14 +0000 |
commit | ef413cad1e7daa23b6b52062066462d4e76f2374 (patch) | |
tree | 9228a268fdcf652aae0d2c2da449ba4081232903 | |
parent | 8e27873fcab3f343096e43ffa72f4ee78597380c (diff) | |
download | chromium_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.cc | 121 | ||||
-rw-r--r-- | chrome/browser/automation/automation_provider.h | 6 | ||||
-rw-r--r-- | chrome/test/functional/PYAUTO_TESTS | 1 | ||||
-rw-r--r-- | chrome/test/functional/browser.py | 35 | ||||
-rw-r--r-- | chrome/test/pyautolib/pyauto.py | 82 |
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. |