| Index: chrome/test/ui_test_utils.cc
|
| ===================================================================
|
| --- chrome/test/ui_test_utils.cc (revision 94694)
|
| +++ chrome/test/ui_test_utils.cc (working copy)
|
| @@ -1,1052 +0,0 @@
|
| -// Copyright (c) 2011 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.
|
| -
|
| -#include "chrome/test/ui_test_utils.h"
|
| -
|
| -#include <vector>
|
| -
|
| -#include "base/callback.h"
|
| -#include "base/command_line.h"
|
| -#include "base/file_path.h"
|
| -#include "base/json/json_reader.h"
|
| -#include "base/memory/scoped_ptr.h"
|
| -#include "base/message_loop.h"
|
| -#include "base/path_service.h"
|
| -#include "base/process_util.h"
|
| -#include "base/utf_string_conversions.h"
|
| -#include "base/values.h"
|
| -#include "chrome/browser/automation/ui_controls.h"
|
| -#include "chrome/browser/bookmarks/bookmark_model.h"
|
| -#include "chrome/browser/browser_process.h"
|
| -#include "chrome/browser/dom_operation_notification_details.h"
|
| -#include "chrome/browser/download/download_item.h"
|
| -#include "chrome/browser/download/download_manager.h"
|
| -#include "chrome/browser/profiles/profile.h"
|
| -#include "chrome/browser/tab_contents/thumbnail_generator.h"
|
| -#include "chrome/browser/ui/browser.h"
|
| -#include "chrome/browser/ui/browser_list.h"
|
| -#include "chrome/browser/ui/browser_navigator.h"
|
| -#include "chrome/browser/ui/browser_window.h"
|
| -#include "chrome/browser/ui/find_bar/find_notification_details.h"
|
| -#include "chrome/browser/ui/find_bar/find_tab_helper.h"
|
| -#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
|
| -#include "chrome/common/chrome_notification_types.h"
|
| -#include "chrome/common/chrome_paths.h"
|
| -#include "chrome/common/extensions/extension_action.h"
|
| -#include "chrome/test/automation/javascript_execution_controller.h"
|
| -#include "chrome/test/bookmark_load_observer.h"
|
| -#include "content/browser/renderer_host/render_process_host.h"
|
| -#include "content/browser/renderer_host/render_view_host.h"
|
| -#include "content/browser/tab_contents/navigation_controller.h"
|
| -#include "content/browser/tab_contents/navigation_entry.h"
|
| -#include "content/browser/tab_contents/tab_contents.h"
|
| -#include "googleurl/src/gurl.h"
|
| -#include "net/base/net_util.h"
|
| -#include "testing/gtest/include/gtest/gtest.h"
|
| -#include "third_party/skia/include/core/SkBitmap.h"
|
| -#include "third_party/skia/include/core/SkColor.h"
|
| -#include "ui/gfx/size.h"
|
| -
|
| -#if defined(TOOLKIT_VIEWS)
|
| -#include "views/focus/accelerator_handler.h"
|
| -#endif
|
| -
|
| -namespace ui_test_utils {
|
| -
|
| -namespace {
|
| -
|
| -// Used to block until a navigation completes.
|
| -class NavigationNotificationObserver : public NotificationObserver {
|
| - public:
|
| - NavigationNotificationObserver(const NotificationSource& source,
|
| - int number_of_navigations)
|
| - : navigation_started_(false),
|
| - navigations_completed_(0),
|
| - number_of_navigations_(number_of_navigations),
|
| - running_(false),
|
| - done_(false) {
|
| - registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, source);
|
| - registrar_.Add(this, content::NOTIFICATION_LOAD_START, source);
|
| - registrar_.Add(this, content::NOTIFICATION_LOAD_STOP, source);
|
| - }
|
| -
|
| - void Run() {
|
| - if (!done_) {
|
| - running_ = true;
|
| - RunMessageLoop();
|
| - }
|
| - }
|
| -
|
| - virtual void Observe(int type,
|
| - const NotificationSource& source,
|
| - const NotificationDetails& details) {
|
| - if (type == content::NOTIFICATION_NAV_ENTRY_COMMITTED ||
|
| - type == content::NOTIFICATION_LOAD_START) {
|
| - navigation_started_ = true;
|
| - } else if (type == content::NOTIFICATION_LOAD_STOP) {
|
| - if (navigation_started_ &&
|
| - ++navigations_completed_ == number_of_navigations_) {
|
| - navigation_started_ = false;
|
| - done_ = true;
|
| - if (running_)
|
| - MessageLoopForUI::current()->Quit();
|
| - }
|
| - }
|
| - }
|
| -
|
| - private:
|
| - NotificationRegistrar registrar_;
|
| -
|
| - // If true the navigation has started.
|
| - bool navigation_started_;
|
| -
|
| - // The number of navigations that have been completed.
|
| - int navigations_completed_;
|
| -
|
| - // The number of navigations to wait for.
|
| - int number_of_navigations_;
|
| -
|
| - // Calls to Observe() can happen early, before the user calls Run(), or
|
| - // after. When we've seen all the navigations we're looking for, we set
|
| - // done_ to true; then when Run() is called we'll never need to run the
|
| - // event loop. Also, we don't need to quit the event loop when we're
|
| - // done if we never had to start an event loop.
|
| - bool running_;
|
| - bool done_;
|
| - DISALLOW_COPY_AND_ASSIGN(NavigationNotificationObserver);
|
| -};
|
| -
|
| -class DOMOperationObserver : public NotificationObserver {
|
| - public:
|
| - explicit DOMOperationObserver(RenderViewHost* render_view_host)
|
| - : did_respond_(false) {
|
| - registrar_.Add(this, chrome::NOTIFICATION_DOM_OPERATION_RESPONSE,
|
| - Source<RenderViewHost>(render_view_host));
|
| - ui_test_utils::RunMessageLoop();
|
| - }
|
| -
|
| - virtual void Observe(int type,
|
| - const NotificationSource& source,
|
| - const NotificationDetails& details) {
|
| - DCHECK(type == chrome::NOTIFICATION_DOM_OPERATION_RESPONSE);
|
| - Details<DomOperationNotificationDetails> dom_op_details(details);
|
| - response_ = dom_op_details->json();
|
| - did_respond_ = true;
|
| - MessageLoopForUI::current()->Quit();
|
| - }
|
| -
|
| - bool GetResponse(std::string* response) WARN_UNUSED_RESULT {
|
| - *response = response_;
|
| - return did_respond_;
|
| - }
|
| -
|
| - private:
|
| - NotificationRegistrar registrar_;
|
| - std::string response_;
|
| - bool did_respond_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(DOMOperationObserver);
|
| -};
|
| -
|
| -class FindInPageNotificationObserver : public NotificationObserver {
|
| - public:
|
| - explicit FindInPageNotificationObserver(TabContentsWrapper* parent_tab)
|
| - : parent_tab_(parent_tab),
|
| - active_match_ordinal_(-1),
|
| - number_of_matches_(0) {
|
| - current_find_request_id_ =
|
| - parent_tab->find_tab_helper()->current_find_request_id();
|
| - registrar_.Add(this, chrome::NOTIFICATION_FIND_RESULT_AVAILABLE,
|
| - Source<TabContents>(parent_tab_->tab_contents()));
|
| - ui_test_utils::RunMessageLoop();
|
| - }
|
| -
|
| - int active_match_ordinal() const { return active_match_ordinal_; }
|
| -
|
| - int number_of_matches() const { return number_of_matches_; }
|
| -
|
| - virtual void Observe(int type, const NotificationSource& source,
|
| - const NotificationDetails& details) {
|
| - if (type == chrome::NOTIFICATION_FIND_RESULT_AVAILABLE) {
|
| - Details<FindNotificationDetails> find_details(details);
|
| - if (find_details->request_id() == current_find_request_id_) {
|
| - // We get multiple responses and one of those will contain the ordinal.
|
| - // This message comes to us before the final update is sent.
|
| - if (find_details->active_match_ordinal() > -1)
|
| - active_match_ordinal_ = find_details->active_match_ordinal();
|
| - if (find_details->final_update()) {
|
| - number_of_matches_ = find_details->number_of_matches();
|
| - MessageLoopForUI::current()->Quit();
|
| - } else {
|
| - DVLOG(1) << "Ignoring, since we only care about the final message";
|
| - }
|
| - }
|
| - } else {
|
| - NOTREACHED();
|
| - }
|
| - }
|
| -
|
| - private:
|
| - NotificationRegistrar registrar_;
|
| - TabContentsWrapper* parent_tab_;
|
| - // We will at some point (before final update) be notified of the ordinal and
|
| - // we need to preserve it so we can send it later.
|
| - int active_match_ordinal_;
|
| - int number_of_matches_;
|
| - // The id of the current find request, obtained from TabContents. Allows us
|
| - // to monitor when the search completes.
|
| - int current_find_request_id_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(FindInPageNotificationObserver);
|
| -};
|
| -
|
| -class InProcessJavaScriptExecutionController
|
| - : public base::RefCounted<InProcessJavaScriptExecutionController>,
|
| - public JavaScriptExecutionController {
|
| - public:
|
| - explicit InProcessJavaScriptExecutionController(
|
| - RenderViewHost* render_view_host)
|
| - : render_view_host_(render_view_host) {}
|
| -
|
| - protected:
|
| - // Executes |script| and sets the JSON response |json|.
|
| - virtual bool ExecuteJavaScriptAndGetJSON(const std::string& script,
|
| - std::string* json) {
|
| - render_view_host_->ExecuteJavascriptInWebFrame(string16(),
|
| - UTF8ToUTF16(script));
|
| - DOMOperationObserver dom_op_observer(render_view_host_);
|
| - return dom_op_observer.GetResponse(json);
|
| - }
|
| -
|
| - virtual void FirstObjectAdded() {
|
| - AddRef();
|
| - }
|
| -
|
| - virtual void LastObjectRemoved() {
|
| - Release();
|
| - }
|
| -
|
| - private:
|
| - // Weak pointer to the associated RenderViewHost.
|
| - RenderViewHost* render_view_host_;
|
| -};
|
| -
|
| -// Specifying a prototype so that we can add the WARN_UNUSED_RESULT attribute.
|
| -bool ExecuteJavaScriptHelper(RenderViewHost* render_view_host,
|
| - const std::wstring& frame_xpath,
|
| - const std::wstring& original_script,
|
| - scoped_ptr<Value>* result) WARN_UNUSED_RESULT;
|
| -
|
| -// Executes the passed |original_script| in the frame pointed to by
|
| -// |frame_xpath|. If |result| is not NULL, stores the value that the evaluation
|
| -// of the script in |result|. Returns true on success.
|
| -bool ExecuteJavaScriptHelper(RenderViewHost* render_view_host,
|
| - const std::wstring& frame_xpath,
|
| - const std::wstring& original_script,
|
| - scoped_ptr<Value>* result) {
|
| - // TODO(jcampan): we should make the domAutomationController not require an
|
| - // automation id.
|
| - std::wstring script = L"window.domAutomationController.setAutomationId(0);" +
|
| - original_script;
|
| - render_view_host->ExecuteJavascriptInWebFrame(WideToUTF16Hack(frame_xpath),
|
| - WideToUTF16Hack(script));
|
| - DOMOperationObserver dom_op_observer(render_view_host);
|
| - std::string json;
|
| - if (!dom_op_observer.GetResponse(&json))
|
| - return false;
|
| -
|
| - // Nothing more to do for callers that ignore the returned JS value.
|
| - if (!result)
|
| - return true;
|
| -
|
| - // Wrap |json| in an array before deserializing because valid JSON has an
|
| - // array or an object as the root.
|
| - json.insert(0, "[");
|
| - json.append("]");
|
| -
|
| - scoped_ptr<Value> root_val(base::JSONReader::Read(json, true));
|
| - if (!root_val->IsType(Value::TYPE_LIST))
|
| - return false;
|
| -
|
| - ListValue* list = static_cast<ListValue*>(root_val.get());
|
| - Value* result_val;
|
| - if (!list || !list->GetSize() ||
|
| - !list->Remove(0, &result_val)) // Remove gives us ownership of the value.
|
| - return false;
|
| -
|
| - result->reset(result_val);
|
| - return true;
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -void RunMessageLoop() {
|
| - MessageLoopForUI* loop = MessageLoopForUI::current();
|
| - bool did_allow_task_nesting = loop->NestableTasksAllowed();
|
| - loop->SetNestableTasksAllowed(true);
|
| -#if defined(TOOLKIT_VIEWS)
|
| - views::AcceleratorHandler handler;
|
| - loop->Run(&handler);
|
| -#elif defined(OS_POSIX) && !defined(OS_MACOSX)
|
| - loop->Run(NULL);
|
| -#else
|
| - loop->Run();
|
| -#endif
|
| - loop->SetNestableTasksAllowed(did_allow_task_nesting);
|
| -}
|
| -
|
| -void RunAllPendingInMessageLoop() {
|
| - MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
|
| - ui_test_utils::RunMessageLoop();
|
| -}
|
| -
|
| -bool GetCurrentTabTitle(const Browser* browser, string16* title) {
|
| - TabContents* tab_contents = browser->GetSelectedTabContents();
|
| - if (!tab_contents)
|
| - return false;
|
| - NavigationEntry* last_entry = tab_contents->controller().GetActiveEntry();
|
| - if (!last_entry)
|
| - return false;
|
| - title->assign(last_entry->GetTitleForDisplay(""));
|
| - return true;
|
| -}
|
| -
|
| -bool WaitForNavigationInCurrentTab(Browser* browser) {
|
| - TabContents* tab_contents = browser->GetSelectedTabContents();
|
| - if (!tab_contents)
|
| - return false;
|
| - WaitForNavigation(&tab_contents->controller());
|
| - return true;
|
| -}
|
| -
|
| -bool WaitForNavigationsInCurrentTab(Browser* browser,
|
| - int number_of_navigations) {
|
| - TabContents* tab_contents = browser->GetSelectedTabContents();
|
| - if (!tab_contents)
|
| - return false;
|
| - WaitForNavigations(&tab_contents->controller(), number_of_navigations);
|
| - return true;
|
| -}
|
| -
|
| -void WaitForNavigation(NavigationController* controller) {
|
| - WaitForNavigations(controller, 1);
|
| -}
|
| -
|
| -void WaitForNavigations(NavigationController* controller,
|
| - int number_of_navigations) {
|
| - NavigationNotificationObserver observer(
|
| - Source<NavigationController>(controller), number_of_navigations);
|
| - observer.Run();
|
| -}
|
| -
|
| -void WaitForNewTab(Browser* browser) {
|
| - TestNotificationObserver observer;
|
| - RegisterAndWait(&observer, content::NOTIFICATION_TAB_ADDED,
|
| - Source<TabContentsDelegate>(browser));
|
| -}
|
| -
|
| -void WaitForBrowserActionUpdated(ExtensionAction* browser_action) {
|
| - TestNotificationObserver observer;
|
| - RegisterAndWait(&observer,
|
| - chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_UPDATED,
|
| - Source<ExtensionAction>(browser_action));
|
| -}
|
| -
|
| -void WaitForLoadStop(TabContents* tab) {
|
| - // In many cases, the load may have finished before we get here. Only wait if
|
| - // the tab still has a pending navigation.
|
| - if (!tab->IsLoading() && !tab->render_manager()->pending_render_view_host())
|
| - return;
|
| - TestNotificationObserver observer;
|
| - RegisterAndWait(&observer, content::NOTIFICATION_LOAD_STOP,
|
| - Source<NavigationController>(&tab->controller()));
|
| -}
|
| -
|
| -Browser* WaitForNewBrowser() {
|
| - TestNotificationObserver observer;
|
| - RegisterAndWait(&observer, chrome::NOTIFICATION_BROWSER_WINDOW_READY,
|
| - NotificationService::AllSources());
|
| - return Source<Browser>(observer.source()).ptr();
|
| -}
|
| -
|
| -Browser* WaitForBrowserNotInSet(std::set<Browser*> excluded_browsers) {
|
| - TestNotificationObserver observer;
|
| - Browser* new_browser = GetBrowserNotInSet(excluded_browsers);
|
| - if (new_browser == NULL) {
|
| - new_browser = WaitForNewBrowser();
|
| - // The new browser should never be in |excluded_browsers|.
|
| - DCHECK(!ContainsKey(excluded_browsers, new_browser));
|
| - }
|
| - return new_browser;
|
| -}
|
| -
|
| -void OpenURLOffTheRecord(Profile* profile, const GURL& url) {
|
| - Browser::OpenURLOffTheRecord(profile, url);
|
| - Browser* browser = BrowserList::FindTabbedBrowser(
|
| - profile->GetOffTheRecordProfile(), false);
|
| - WaitForNavigations(&browser->GetSelectedTabContents()->controller(), 1);
|
| -}
|
| -
|
| -void NavigateToURL(browser::NavigateParams* params) {
|
| - NavigationNotificationObserver observer(NotificationService::AllSources(), 1);
|
| - browser::Navigate(params);
|
| - observer.Run();
|
| -}
|
| -
|
| -void NavigateToURL(Browser* browser, const GURL& url) {
|
| - NavigateToURLWithDisposition(browser, url, CURRENT_TAB,
|
| - BROWSER_TEST_WAIT_FOR_NAVIGATION);
|
| -}
|
| -
|
| -// Navigates the specified tab (via |disposition|) of |browser| to |url|,
|
| -// blocking until the |number_of_navigations| specified complete.
|
| -// |disposition| indicates what tab the download occurs in, and
|
| -// |browser_test_flags| controls what to wait for before continuing.
|
| -static void NavigateToURLWithDispositionBlockUntilNavigationsComplete(
|
| - Browser* browser,
|
| - const GURL& url,
|
| - int number_of_navigations,
|
| - WindowOpenDisposition disposition,
|
| - int browser_test_flags) {
|
| - NavigationNotificationObserver same_tab_observer(
|
| - Source<NavigationController>(
|
| - &browser->GetSelectedTabContents()->controller()),
|
| - number_of_navigations);
|
| -
|
| - std::set<Browser*> initial_browsers;
|
| - for (std::vector<Browser*>::const_iterator iter = BrowserList::begin();
|
| - iter != BrowserList::end();
|
| - ++iter) {
|
| - initial_browsers.insert(*iter);
|
| - }
|
| - browser->OpenURL(url, GURL(), disposition, PageTransition::TYPED);
|
| - if (browser_test_flags & BROWSER_TEST_WAIT_FOR_BROWSER)
|
| - browser = WaitForBrowserNotInSet(initial_browsers);
|
| - if (browser_test_flags & BROWSER_TEST_WAIT_FOR_TAB)
|
| - WaitForNotification(content::NOTIFICATION_TAB_ADDED);
|
| - if (!(browser_test_flags & BROWSER_TEST_WAIT_FOR_NAVIGATION)) {
|
| - // Some other flag caused the wait prior to this.
|
| - return;
|
| - }
|
| - TabContents* tab_contents = NULL;
|
| - if (disposition == NEW_BACKGROUND_TAB) {
|
| - // We've opened up a new tab, but not selected it.
|
| - tab_contents = browser->GetTabContentsAt(browser->active_index() + 1);
|
| - EXPECT_TRUE(tab_contents != NULL)
|
| - << " Unable to wait for navigation to \"" << url.spec()
|
| - << "\" because the new tab is not available yet";
|
| - return;
|
| - } else if ((disposition == CURRENT_TAB) ||
|
| - (disposition == NEW_FOREGROUND_TAB) ||
|
| - (disposition == SINGLETON_TAB)) {
|
| - // The currently selected tab is the right one.
|
| - tab_contents = browser->GetSelectedTabContents();
|
| - }
|
| - if (disposition == CURRENT_TAB) {
|
| - same_tab_observer.Run();
|
| - return;
|
| - } else if (tab_contents) {
|
| - NavigationController* controller = &tab_contents->controller();
|
| - WaitForNavigations(controller, number_of_navigations);
|
| - return;
|
| - }
|
| - EXPECT_TRUE(NULL != tab_contents) << " Unable to wait for navigation to \""
|
| - << url.spec() << "\""
|
| - << " because we can't get the tab contents";
|
| -}
|
| -
|
| -void NavigateToURLWithDisposition(Browser* browser,
|
| - const GURL& url,
|
| - WindowOpenDisposition disposition,
|
| - int browser_test_flags) {
|
| - NavigateToURLWithDispositionBlockUntilNavigationsComplete(
|
| - browser,
|
| - url,
|
| - 1,
|
| - disposition,
|
| - browser_test_flags);
|
| -}
|
| -
|
| -void NavigateToURLBlockUntilNavigationsComplete(Browser* browser,
|
| - const GURL& url,
|
| - int number_of_navigations) {
|
| - NavigateToURLWithDispositionBlockUntilNavigationsComplete(
|
| - browser,
|
| - url,
|
| - number_of_navigations,
|
| - CURRENT_TAB,
|
| - BROWSER_TEST_WAIT_FOR_NAVIGATION);
|
| -}
|
| -
|
| -DOMElementProxyRef GetActiveDOMDocument(Browser* browser) {
|
| - JavaScriptExecutionController* executor =
|
| - new InProcessJavaScriptExecutionController(
|
| - browser->GetSelectedTabContents()->render_view_host());
|
| - int element_handle;
|
| - executor->ExecuteJavaScriptAndGetReturn("document;", &element_handle);
|
| - return executor->GetObjectProxy<DOMElementProxy>(element_handle);
|
| -}
|
| -
|
| -bool ExecuteJavaScript(RenderViewHost* render_view_host,
|
| - const std::wstring& frame_xpath,
|
| - const std::wstring& original_script) {
|
| - std::wstring script =
|
| - original_script + L"window.domAutomationController.send(0);";
|
| - return ExecuteJavaScriptHelper(render_view_host, frame_xpath, script, NULL);
|
| -}
|
| -
|
| -bool ExecuteJavaScriptAndExtractInt(RenderViewHost* render_view_host,
|
| - const std::wstring& frame_xpath,
|
| - const std::wstring& script,
|
| - int* result) {
|
| - DCHECK(result);
|
| - scoped_ptr<Value> value;
|
| - if (!ExecuteJavaScriptHelper(render_view_host, frame_xpath, script, &value) ||
|
| - !value.get())
|
| - return false;
|
| -
|
| - return value->GetAsInteger(result);
|
| -}
|
| -
|
| -bool ExecuteJavaScriptAndExtractBool(RenderViewHost* render_view_host,
|
| - const std::wstring& frame_xpath,
|
| - const std::wstring& script,
|
| - bool* result) {
|
| - DCHECK(result);
|
| - scoped_ptr<Value> value;
|
| - if (!ExecuteJavaScriptHelper(render_view_host, frame_xpath, script, &value) ||
|
| - !value.get())
|
| - return false;
|
| -
|
| - return value->GetAsBoolean(result);
|
| -}
|
| -
|
| -bool ExecuteJavaScriptAndExtractString(RenderViewHost* render_view_host,
|
| - const std::wstring& frame_xpath,
|
| - const std::wstring& script,
|
| - std::string* result) {
|
| - DCHECK(result);
|
| - scoped_ptr<Value> value;
|
| - if (!ExecuteJavaScriptHelper(render_view_host, frame_xpath, script, &value) ||
|
| - !value.get())
|
| - return false;
|
| -
|
| - return value->GetAsString(result);
|
| -}
|
| -
|
| -FilePath GetTestFilePath(const FilePath& dir, const FilePath& file) {
|
| - FilePath path;
|
| - PathService::Get(chrome::DIR_TEST_DATA, &path);
|
| - return path.Append(dir).Append(file);
|
| -}
|
| -
|
| -GURL GetTestUrl(const FilePath& dir, const FilePath& file) {
|
| - return net::FilePathToFileURL(GetTestFilePath(dir, file));
|
| -}
|
| -
|
| -GURL GetFileUrlWithQuery(const FilePath& path,
|
| - const std::string& query_string) {
|
| - GURL url = net::FilePathToFileURL(path);
|
| - if (!query_string.empty()) {
|
| - GURL::Replacements replacements;
|
| - replacements.SetQueryStr(query_string);
|
| - return url.ReplaceComponents(replacements);
|
| - }
|
| - return url;
|
| -}
|
| -
|
| -AppModalDialog* WaitForAppModalDialog() {
|
| - TestNotificationObserver observer;
|
| - RegisterAndWait(&observer, chrome::NOTIFICATION_APP_MODAL_DIALOG_SHOWN,
|
| - NotificationService::AllSources());
|
| - return Source<AppModalDialog>(observer.source()).ptr();
|
| -}
|
| -
|
| -void CrashTab(TabContents* tab) {
|
| - RenderProcessHost* rph = tab->render_view_host()->process();
|
| - base::KillProcess(rph->GetHandle(), 0, false);
|
| - TestNotificationObserver observer;
|
| - RegisterAndWait(&observer, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
|
| - Source<RenderProcessHost>(rph));
|
| -}
|
| -
|
| -void WaitForFocusChange(TabContents* tab_contents) {
|
| - TestNotificationObserver observer;
|
| - RegisterAndWait(&observer, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE,
|
| - Source<TabContents>(tab_contents));
|
| -}
|
| -
|
| -void WaitForFocusInBrowser(Browser* browser) {
|
| - TestNotificationObserver observer;
|
| - RegisterAndWait(&observer, chrome::NOTIFICATION_FOCUS_RETURNED_TO_BROWSER,
|
| - Source<Browser>(browser));
|
| -}
|
| -
|
| -int FindInPage(TabContentsWrapper* tab_contents, const string16& search_string,
|
| - bool forward, bool match_case, int* ordinal) {
|
| - tab_contents->
|
| - find_tab_helper()->StartFinding(search_string, forward, match_case);
|
| - FindInPageNotificationObserver observer(tab_contents);
|
| - if (ordinal)
|
| - *ordinal = observer.active_match_ordinal();
|
| - return observer.number_of_matches();
|
| -}
|
| -
|
| -void WaitForNotification(int type) {
|
| - TestNotificationObserver observer;
|
| - RegisterAndWait(&observer, type, NotificationService::AllSources());
|
| -}
|
| -
|
| -void WaitForNotificationFrom(int type,
|
| - const NotificationSource& source) {
|
| - TestNotificationObserver observer;
|
| - RegisterAndWait(&observer, type, source);
|
| -}
|
| -
|
| -void RegisterAndWait(NotificationObserver* observer,
|
| - int type,
|
| - const NotificationSource& source) {
|
| - NotificationRegistrar registrar;
|
| - registrar.Add(observer, type, source);
|
| - RunMessageLoop();
|
| -}
|
| -
|
| -void WaitForBookmarkModelToLoad(BookmarkModel* model) {
|
| - if (model->IsLoaded())
|
| - return;
|
| - BookmarkLoadObserver observer;
|
| - model->AddObserver(&observer);
|
| - RunMessageLoop();
|
| - model->RemoveObserver(&observer);
|
| - ASSERT_TRUE(model->IsLoaded());
|
| -}
|
| -
|
| -void WaitForHistoryToLoad(Browser* browser) {
|
| - HistoryService* history_service =
|
| - browser->profile()->GetHistoryService(Profile::EXPLICIT_ACCESS);
|
| - if (!history_service->BackendLoaded())
|
| - WaitForNotification(chrome::NOTIFICATION_HISTORY_LOADED);
|
| -}
|
| -
|
| -bool GetNativeWindow(const Browser* browser, gfx::NativeWindow* native_window) {
|
| - BrowserWindow* window = browser->window();
|
| - if (!window)
|
| - return false;
|
| -
|
| - *native_window = window->GetNativeHandle();
|
| - return *native_window;
|
| -}
|
| -
|
| -bool BringBrowserWindowToFront(const Browser* browser) {
|
| - gfx::NativeWindow window = NULL;
|
| - if (!GetNativeWindow(browser, &window))
|
| - return false;
|
| -
|
| - ui_test_utils::ShowAndFocusNativeWindow(window);
|
| - return true;
|
| -}
|
| -
|
| -Browser* GetBrowserNotInSet(std::set<Browser*> excluded_browsers) {
|
| - for (BrowserList::const_iterator iter = BrowserList::begin();
|
| - iter != BrowserList::end();
|
| - ++iter) {
|
| - if (excluded_browsers.find(*iter) == excluded_browsers.end())
|
| - return *iter;
|
| - }
|
| -
|
| - return NULL;
|
| -}
|
| -
|
| -bool SendKeyPressSync(const Browser* browser,
|
| - ui::KeyboardCode key,
|
| - bool control,
|
| - bool shift,
|
| - bool alt,
|
| - bool command) {
|
| - gfx::NativeWindow window = NULL;
|
| - if (!GetNativeWindow(browser, &window))
|
| - return false;
|
| -
|
| - if (!ui_controls::SendKeyPressNotifyWhenDone(
|
| - window, key, control, shift, alt, command,
|
| - new MessageLoop::QuitTask())) {
|
| - LOG(ERROR) << "ui_controls::SendKeyPressNotifyWhenDone failed";
|
| - return false;
|
| - }
|
| - // Run the message loop. It'll stop running when either the key was received
|
| - // or the test timed out (in which case testing::Test::HasFatalFailure should
|
| - // be set).
|
| - RunMessageLoop();
|
| - return !testing::Test::HasFatalFailure();
|
| -}
|
| -
|
| -bool SendKeyPressAndWait(const Browser* browser,
|
| - ui::KeyboardCode key,
|
| - bool control,
|
| - bool shift,
|
| - bool alt,
|
| - bool command,
|
| - int type,
|
| - const NotificationSource& source) {
|
| - WindowedNotificationObserver observer(type, source);
|
| -
|
| - if (!SendKeyPressSync(browser, key, control, shift, alt, command))
|
| - return false;
|
| -
|
| - observer.Wait();
|
| - return !testing::Test::HasFatalFailure();
|
| -}
|
| -
|
| -
|
| -TimedMessageLoopRunner::TimedMessageLoopRunner()
|
| - : loop_(new MessageLoopForUI()),
|
| - owned_(true),
|
| - quit_loop_invoked_(false) {
|
| -}
|
| -
|
| -TimedMessageLoopRunner::~TimedMessageLoopRunner() {
|
| - if (owned_)
|
| - delete loop_;
|
| -}
|
| -
|
| -void TimedMessageLoopRunner::RunFor(int ms) {
|
| - QuitAfter(ms);
|
| - quit_loop_invoked_ = false;
|
| - loop_->Run();
|
| -}
|
| -
|
| -void TimedMessageLoopRunner::Quit() {
|
| - quit_loop_invoked_ = true;
|
| - loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask);
|
| -}
|
| -
|
| -void TimedMessageLoopRunner::QuitAfter(int ms) {
|
| - quit_loop_invoked_ = true;
|
| - loop_->PostDelayedTask(FROM_HERE, new MessageLoop::QuitTask, ms);
|
| -}
|
| -
|
| -namespace {
|
| -
|
| -void AppendToPythonPath(const FilePath& dir) {
|
| -#if defined(OS_WIN)
|
| - const wchar_t kPythonPath[] = L"PYTHONPATH";
|
| - // TODO(ukai): handle longer PYTHONPATH variables.
|
| - wchar_t oldpath[4096];
|
| - if (::GetEnvironmentVariable(kPythonPath, oldpath, arraysize(oldpath)) == 0) {
|
| - ::SetEnvironmentVariableW(kPythonPath, dir.value().c_str());
|
| - } else if (!wcsstr(oldpath, dir.value().c_str())) {
|
| - std::wstring newpath(oldpath);
|
| - newpath.append(L";");
|
| - newpath.append(dir.value());
|
| - SetEnvironmentVariableW(kPythonPath, newpath.c_str());
|
| - }
|
| -#elif defined(OS_POSIX)
|
| - const char kPythonPath[] = "PYTHONPATH";
|
| - const char* oldpath = getenv(kPythonPath);
|
| - if (!oldpath) {
|
| - setenv(kPythonPath, dir.value().c_str(), 1);
|
| - } else if (!strstr(oldpath, dir.value().c_str())) {
|
| - std::string newpath(oldpath);
|
| - newpath.append(":");
|
| - newpath.append(dir.value());
|
| - setenv(kPythonPath, newpath.c_str(), 1);
|
| - }
|
| -#endif
|
| -}
|
| -
|
| -} // anonymous namespace
|
| -
|
| -TestWebSocketServer::TestWebSocketServer() : started_(false) {
|
| -}
|
| -
|
| -bool TestWebSocketServer::Start(const FilePath& root_directory) {
|
| - if (started_)
|
| - return true;
|
| - // Append CommandLine arguments after the server script, switches won't work.
|
| - scoped_ptr<CommandLine> cmd_line(CreateWebSocketServerCommandLine());
|
| - cmd_line->AppendArg("--server=start");
|
| - cmd_line->AppendArg("--chromium");
|
| - cmd_line->AppendArg("--register_cygwin");
|
| - cmd_line->AppendArgNative(FILE_PATH_LITERAL("--root=") +
|
| - root_directory.value());
|
| - if (!temp_dir_.CreateUniqueTempDir()) {
|
| - LOG(ERROR) << "Unable to create a temporary directory.";
|
| - return false;
|
| - }
|
| - websocket_pid_file_ = temp_dir_.path().AppendASCII("websocket.pid");
|
| - cmd_line->AppendArgNative(FILE_PATH_LITERAL("--pidfile=") +
|
| - websocket_pid_file_.value());
|
| - SetPythonPath();
|
| - base::LaunchOptions options;
|
| - options.wait = true;
|
| - if (!base::LaunchProcess(*cmd_line.get(), options, NULL)) {
|
| - LOG(ERROR) << "Unable to launch websocket server.";
|
| - return false;
|
| - }
|
| - started_ = true;
|
| - return true;
|
| -}
|
| -
|
| -CommandLine* TestWebSocketServer::CreatePythonCommandLine() {
|
| - // Note: Python's first argument must be the script; do not append CommandLine
|
| - // switches, as they would precede the script path and break this CommandLine.
|
| - return new CommandLine(FilePath(FILE_PATH_LITERAL("python")));
|
| -}
|
| -
|
| -void TestWebSocketServer::SetPythonPath() {
|
| - FilePath scripts_path;
|
| - PathService::Get(base::DIR_SOURCE_ROOT, &scripts_path);
|
| -
|
| - scripts_path = scripts_path
|
| - .Append(FILE_PATH_LITERAL("third_party"))
|
| - .Append(FILE_PATH_LITERAL("WebKit"))
|
| - .Append(FILE_PATH_LITERAL("Tools"))
|
| - .Append(FILE_PATH_LITERAL("Scripts"));
|
| - AppendToPythonPath(scripts_path);
|
| -}
|
| -
|
| -CommandLine* TestWebSocketServer::CreateWebSocketServerCommandLine() {
|
| - FilePath src_path;
|
| - // Get to 'src' dir.
|
| - PathService::Get(base::DIR_SOURCE_ROOT, &src_path);
|
| -
|
| - FilePath script_path(src_path);
|
| - script_path = script_path.AppendASCII("third_party");
|
| - script_path = script_path.AppendASCII("WebKit");
|
| - script_path = script_path.AppendASCII("Tools");
|
| - script_path = script_path.AppendASCII("Scripts");
|
| - script_path = script_path.AppendASCII("new-run-webkit-websocketserver");
|
| -
|
| - CommandLine* cmd_line = CreatePythonCommandLine();
|
| - cmd_line->AppendArgPath(script_path);
|
| - return cmd_line;
|
| -}
|
| -
|
| -TestWebSocketServer::~TestWebSocketServer() {
|
| - if (!started_)
|
| - return;
|
| - // Append CommandLine arguments after the server script, switches won't work.
|
| - scoped_ptr<CommandLine> cmd_line(CreateWebSocketServerCommandLine());
|
| - cmd_line->AppendArg("--server=stop");
|
| - cmd_line->AppendArg("--chromium");
|
| - cmd_line->AppendArgNative(FILE_PATH_LITERAL("--pidfile=") +
|
| - websocket_pid_file_.value());
|
| - base::LaunchOptions options;
|
| - options.wait = true;
|
| - base::LaunchProcess(*cmd_line.get(), options, NULL);
|
| -}
|
| -
|
| -TestNotificationObserver::TestNotificationObserver()
|
| - : source_(NotificationService::AllSources()) {
|
| -}
|
| -
|
| -TestNotificationObserver::~TestNotificationObserver() {}
|
| -
|
| -void TestNotificationObserver::Observe(int type,
|
| - const NotificationSource& source,
|
| - const NotificationDetails& details) {
|
| - source_ = source;
|
| - details_ = details;
|
| - MessageLoopForUI::current()->Quit();
|
| -}
|
| -
|
| -WindowedNotificationObserver::WindowedNotificationObserver(
|
| - int notification_type,
|
| - const NotificationSource& source)
|
| - : seen_(false),
|
| - running_(false),
|
| - waiting_for_(source) {
|
| - registrar_.Add(this, notification_type, waiting_for_);
|
| -}
|
| -
|
| -WindowedNotificationObserver::~WindowedNotificationObserver() {}
|
| -
|
| -void WindowedNotificationObserver::Wait() {
|
| - if (seen_ || (waiting_for_ == NotificationService::AllSources() &&
|
| - !sources_seen_.empty())) {
|
| - return;
|
| - }
|
| -
|
| - running_ = true;
|
| - ui_test_utils::RunMessageLoop();
|
| -}
|
| -
|
| -void WindowedNotificationObserver::WaitFor(const NotificationSource& source) {
|
| - if (waiting_for_ != NotificationService::AllSources()) {
|
| - LOG(FATAL) << "WaitFor called when already waiting on a specific source."
|
| - << "Use Wait in this case.";
|
| - }
|
| -
|
| - waiting_for_ = source;
|
| - if (sources_seen_.count(waiting_for_.map_key()) > 0)
|
| - return;
|
| -
|
| - running_ = true;
|
| - ui_test_utils::RunMessageLoop();
|
| -}
|
| -
|
| -void WindowedNotificationObserver::Observe(int type,
|
| - const NotificationSource& source,
|
| - const NotificationDetails& details) {
|
| - if (waiting_for_ == source ||
|
| - (running_ && waiting_for_ == NotificationService::AllSources())) {
|
| - seen_ = true;
|
| - if (running_)
|
| - MessageLoopForUI::current()->Quit();
|
| - } else {
|
| - sources_seen_.insert(source.map_key());
|
| - }
|
| -}
|
| -
|
| -TitleWatcher::TitleWatcher(TabContents* tab_contents,
|
| - const string16& expected_title)
|
| - : expected_tab_(tab_contents),
|
| - expected_title_(expected_title),
|
| - title_observed_(false),
|
| - quit_loop_on_observation_(false) {
|
| - EXPECT_TRUE(tab_contents != NULL);
|
| - notification_registrar_.Add(this,
|
| - content::NOTIFICATION_TAB_CONTENTS_TITLE_UPDATED,
|
| - Source<TabContents>(tab_contents));
|
| -}
|
| -
|
| -TitleWatcher::~TitleWatcher() {
|
| -}
|
| -
|
| -bool TitleWatcher::Wait() {
|
| - if (title_observed_)
|
| - return true;
|
| - quit_loop_on_observation_ = true;
|
| - ui_test_utils::RunMessageLoop();
|
| - return title_observed_;
|
| -}
|
| -
|
| -void TitleWatcher::Observe(int type,
|
| - const NotificationSource& source,
|
| - const NotificationDetails& details) {
|
| - if (type != content::NOTIFICATION_TAB_CONTENTS_TITLE_UPDATED)
|
| - return;
|
| -
|
| - TabContents* source_contents = Source<TabContents>(source).ptr();
|
| - ASSERT_EQ(expected_tab_, source_contents);
|
| - if (source_contents->GetTitle() != expected_title_)
|
| - return;
|
| -
|
| - title_observed_ = true;
|
| - if (quit_loop_on_observation_)
|
| - MessageLoopForUI::current()->Quit();
|
| -}
|
| -
|
| -DOMMessageQueue::DOMMessageQueue() {
|
| - registrar_.Add(this, chrome::NOTIFICATION_DOM_OPERATION_RESPONSE,
|
| - NotificationService::AllSources());
|
| -}
|
| -
|
| -DOMMessageQueue::~DOMMessageQueue() {}
|
| -
|
| -void DOMMessageQueue::Observe(int type,
|
| - const NotificationSource& source,
|
| - const NotificationDetails& details) {
|
| - Details<DomOperationNotificationDetails> dom_op_details(details);
|
| - Source<RenderViewHost> sender(source);
|
| - message_queue_.push(dom_op_details->json());
|
| - if (waiting_for_message_) {
|
| - waiting_for_message_ = false;
|
| - MessageLoopForUI::current()->Quit();
|
| - }
|
| -}
|
| -
|
| -bool DOMMessageQueue::WaitForMessage(std::string* message) {
|
| - if (message_queue_.empty()) {
|
| - waiting_for_message_ = true;
|
| - // This will be quit when a new message comes in.
|
| - RunMessageLoop();
|
| - }
|
| - // The queue should not be empty, unless we were quit because of a timeout.
|
| - if (message_queue_.empty())
|
| - return false;
|
| - if (message)
|
| - *message = message_queue_.front();
|
| - return true;
|
| -}
|
| -
|
| -// Coordinates taking snapshots of a |RenderWidget|.
|
| -class SnapshotTaker {
|
| - public:
|
| - SnapshotTaker() : bitmap_(NULL) {}
|
| -
|
| - bool TakeRenderWidgetSnapshot(RenderWidgetHost* rwh,
|
| - const gfx::Size& page_size,
|
| - const gfx::Size& desired_size,
|
| - SkBitmap* bitmap) WARN_UNUSED_RESULT {
|
| - bitmap_ = bitmap;
|
| - ThumbnailGenerator* generator = g_browser_process->GetThumbnailGenerator();
|
| - generator->MonitorRenderer(rwh, true);
|
| - snapshot_taken_ = false;
|
| - generator->AskForSnapshot(
|
| - rwh,
|
| - false, // don't use backing_store
|
| - NewCallback(this, &SnapshotTaker::OnSnapshotTaken),
|
| - page_size,
|
| - desired_size);
|
| - ui_test_utils::RunMessageLoop();
|
| - return snapshot_taken_;
|
| - }
|
| -
|
| - bool TakeEntirePageSnapshot(RenderViewHost* rvh,
|
| - SkBitmap* bitmap) WARN_UNUSED_RESULT {
|
| - const wchar_t* script =
|
| - L"window.domAutomationController.send("
|
| - L" JSON.stringify([document.width, document.height]))";
|
| - std::string json;
|
| - if (!ui_test_utils::ExecuteJavaScriptAndExtractString(
|
| - rvh, L"", script, &json))
|
| - return false;
|
| -
|
| - // Parse the JSON.
|
| - std::vector<int> dimensions;
|
| - scoped_ptr<Value> value(base::JSONReader::Read(json, true));
|
| - if (!value->IsType(Value::TYPE_LIST))
|
| - return false;
|
| - ListValue* list = static_cast<ListValue*>(value.get());
|
| - int width, height;
|
| - if (!list->GetInteger(0, &width) || !list->GetInteger(1, &height))
|
| - return false;
|
| -
|
| - // Take the snapshot.
|
| - gfx::Size page_size(width, height);
|
| - return TakeRenderWidgetSnapshot(rvh, page_size, page_size, bitmap);
|
| - }
|
| -
|
| - private:
|
| - // Called when the ThumbnailGenerator has taken the snapshot.
|
| - void OnSnapshotTaken(const SkBitmap& bitmap) {
|
| - *bitmap_ = bitmap;
|
| - snapshot_taken_ = true;
|
| - MessageLoop::current()->Quit();
|
| - }
|
| -
|
| - SkBitmap* bitmap_;
|
| - // Whether the snapshot was actually taken and received by this SnapshotTaker.
|
| - // This will be false if the test times out.
|
| - bool snapshot_taken_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(SnapshotTaker);
|
| -};
|
| -
|
| -bool TakeRenderWidgetSnapshot(RenderWidgetHost* rwh,
|
| - const gfx::Size& page_size,
|
| - SkBitmap* bitmap) {
|
| - DCHECK(bitmap);
|
| - SnapshotTaker taker;
|
| - return taker.TakeRenderWidgetSnapshot(rwh, page_size, page_size, bitmap);
|
| -}
|
| -
|
| -bool TakeEntirePageSnapshot(RenderViewHost* rvh, SkBitmap* bitmap) {
|
| - DCHECK(bitmap);
|
| - SnapshotTaker taker;
|
| - return taker.TakeEntirePageSnapshot(rvh, bitmap);
|
| -}
|
| -
|
| -} // namespace ui_test_utils
|
|
|