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 |