browser_test_utils.h revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef CONTENT_PUBLIC_TEST_BROWSER_TEST_UTILS_H_ 6#define CONTENT_PUBLIC_TEST_BROWSER_TEST_UTILS_H_ 7 8#include <queue> 9#include <string> 10#include <vector> 11 12#include "base/callback_forward.h" 13#include "base/compiler_specific.h" 14#include "base/files/scoped_temp_dir.h" 15#include "base/memory/ref_counted.h" 16#include "base/process/process.h" 17#include "base/strings/string16.h" 18#include "content/public/browser/notification_observer.h" 19#include "content/public/browser/notification_registrar.h" 20#include "content/public/browser/render_process_host_observer.h" 21#include "content/public/browser/web_contents_observer.h" 22#include "third_party/WebKit/public/web/WebInputEvent.h" 23#include "ui/events/keycodes/keyboard_codes.h" 24#include "url/gurl.h" 25 26#if defined(OS_WIN) 27#include "base/win/scoped_handle.h" 28#endif 29 30namespace base { 31class RunLoop; 32} 33 34namespace gfx { 35class Point; 36} 37 38// A collections of functions designed for use with content_browsertests and 39// browser_tests. 40// TO BE CLEAR: any function here must work against both binaries. If it only 41// works with browser_tests, it should be in chrome\test\base\ui_test_utils.h. 42// If it only works with content_browsertests, it should be in 43// content\test\content_browser_test_utils.h. 44 45namespace content { 46 47class BrowserContext; 48class MessageLoopRunner; 49class RenderViewHost; 50class WebContents; 51 52// Generate a URL for a file path including a query string. 53GURL GetFileUrlWithQuery(const base::FilePath& path, 54 const std::string& query_string); 55 56// Waits for a load stop for the specified |web_contents|'s controller, if the 57// tab is currently web_contents. Otherwise returns immediately. 58void WaitForLoadStop(WebContents* web_contents); 59 60// Causes the specified web_contents to crash. Blocks until it is crashed. 61void CrashTab(WebContents* web_contents); 62 63// Simulates clicking at the center of the given tab asynchronously; modifiers 64// may contain bits from WebInputEvent::Modifiers. 65void SimulateMouseClick(WebContents* web_contents, 66 int modifiers, 67 blink::WebMouseEvent::Button button); 68 69// Simulates clicking at the point |point| of the given tab asynchronously; 70// modifiers may contain bits from WebInputEvent::Modifiers. 71void SimulateMouseClickAt(WebContents* web_contents, 72 int modifiers, 73 blink::WebMouseEvent::Button button, 74 const gfx::Point& point); 75 76// Simulates asynchronously a mouse enter/move/leave event. 77void SimulateMouseEvent(WebContents* web_contents, 78 blink::WebInputEvent::Type type, 79 const gfx::Point& point); 80 81// Sends a key press asynchronously. 82// The native code of the key event will be set to InvalidNativeKeycode(). 83// |key_code| alone is good enough for scenarios that only need the char 84// value represented by a key event and not the physical key on the keyboard 85// or the keyboard layout. 86// For scenarios such as chromoting that need the native code, 87// SimulateKeyPressWithCode should be used. 88void SimulateKeyPress(WebContents* web_contents, 89 ui::KeyboardCode key_code, 90 bool control, 91 bool shift, 92 bool alt, 93 bool command); 94 95// Sends a key press asynchronously. 96// |code| specifies the UIEvents (aka: DOM4Events) value of the key: 97// https://dvcs.w3.org/hg/d4e/raw-file/tip/source_respec.htm 98// The native code of the key event will be set based on |code|. 99// See ui/base/keycodes/vi usb_keycode_map.h for mappings between |code| 100// and the native code. 101// Examples of the various codes: 102// key_code: VKEY_A 103// code: "KeyA" 104// native key code: 0x001e (for Windows). 105// native key code: 0x0026 (for Linux). 106void SimulateKeyPressWithCode(WebContents* web_contents, 107 ui::KeyboardCode key_code, 108 const char* code, 109 bool control, 110 bool shift, 111 bool alt, 112 bool command); 113 114namespace internal { 115// Allow ExecuteScriptInFrame* methods to target either a WebContents or a 116// RenderViewHost. Targetting a WebContents means executing the script in the 117// RenderViewHost returned by WebContents::GetRenderViewHost(), which is the 118// "current" RenderViewHost. Pass a specific RenderViewHost to target, for 119// example, a "swapped-out" RenderViewHost. 120// OBSOLETE; DO NOT USE! Use ExecuteScript* methods that target a 121// RenderFrameHost instead. 122class ToRenderViewHost { 123 public: 124 ToRenderViewHost(WebContents* web_contents); 125 ToRenderViewHost(RenderViewHost* render_view_host); 126 127 RenderViewHost* render_view_host() const { return render_view_host_; } 128 129 private: 130 RenderViewHost* render_view_host_; 131}; 132 133// Allow ExecuteScript* methods to target either a WebContents or a 134// RenderFrameHost. Targetting a WebContents means executing the script in the 135// RenderFrameHost returned by WebContents::GetMainFrame(), which is the 136// main frame. Pass a specific RenderFrameHost to target it. 137class ToRenderFrameHost { 138 public: 139 ToRenderFrameHost(WebContents* web_contents); 140 ToRenderFrameHost(RenderViewHost* render_view_host); 141 ToRenderFrameHost(RenderFrameHost* render_frame_host); 142 143 RenderFrameHost* render_frame_host() const { return render_frame_host_; } 144 145 private: 146 RenderFrameHost* render_frame_host_; 147}; 148} // namespace internal 149 150// Executes the passed |script| in the frame pointed to by |frame_xpath| (use 151// empty string for main frame). The |script| should not invoke 152// domAutomationController.send(); otherwise, your test will hang or be flaky. 153// If you want to extract a result, use one of the below functions. 154// Returns true on success. 155// OBSOLETE; DO NOT USE! Use ExecuteScript and specify a RenderFrameHost. 156bool ExecuteScriptInFrame(const internal::ToRenderViewHost& adapter, 157 const std::string& frame_xpath, 158 const std::string& script) WARN_UNUSED_RESULT; 159 160// The following methods executes the passed |script| in the frame pointed to by 161// |frame_xpath| (use empty string for main frame) and sets |result| to the 162// value passed to "window.domAutomationController.send" by the executed script. 163// They return true on success, false if the script execution failed or did not 164// evaluate to the expected type. 165// OBSOLETE; DO NOT USE! Use ExecuteScriptAndExtract[Int|Bool|String] and 166// specify a RenderFrameHost. 167bool ExecuteScriptInFrameAndExtractInt( 168 const internal::ToRenderViewHost& adapter, 169 const std::string& frame_xpath, 170 const std::string& script, 171 int* result) WARN_UNUSED_RESULT; 172bool ExecuteScriptInFrameAndExtractBool( 173 const internal::ToRenderViewHost& adapter, 174 const std::string& frame_xpath, 175 const std::string& script, 176 bool* result) WARN_UNUSED_RESULT; 177bool ExecuteScriptInFrameAndExtractString( 178 const internal::ToRenderViewHost& adapter, 179 const std::string& frame_xpath, 180 const std::string& script, 181 std::string* result) WARN_UNUSED_RESULT; 182 183// Executes the passed |script| in the specified frame. The |script| should not 184// invoke domAutomationController.send(); otherwise, your test will hang or be 185// flaky. If you want to extract a result, use one of the below functions. 186// Returns true on success. 187bool ExecuteScript(const internal::ToRenderFrameHost& adapter, 188 const std::string& script) WARN_UNUSED_RESULT; 189 190// The following methods executes the passed |script| in the specified frame and 191// sets |result| to the value passed to "window.domAutomationController.send" by 192// the executed script. They return true on success, false if the script 193// execution failed or did not evaluate to the expected type. 194bool ExecuteScriptAndExtractInt(const internal::ToRenderFrameHost& adapter, 195 const std::string& script, 196 int* result) WARN_UNUSED_RESULT; 197bool ExecuteScriptAndExtractBool(const internal::ToRenderFrameHost& adapter, 198 const std::string& script, 199 bool* result) WARN_UNUSED_RESULT; 200bool ExecuteScriptAndExtractString(const internal::ToRenderFrameHost& adapter, 201 const std::string& script, 202 std::string* result) WARN_UNUSED_RESULT; 203 204// Executes the WebUI resource test runner injecting each resource ID in 205// |js_resource_ids| prior to executing the tests. 206// 207// Returns true if tests ran successfully, false otherwise. 208bool ExecuteWebUIResourceTest(WebContents* web_contents, 209 const std::vector<int>& js_resource_ids); 210 211// Returns the cookies for the given url. 212std::string GetCookies(BrowserContext* browser_context, const GURL& url); 213 214// Sets a cookie for the given url. Returns true on success. 215bool SetCookie(BrowserContext* browser_context, 216 const GURL& url, 217 const std::string& value); 218 219// Watches title changes on a WebContents, blocking until an expected title is 220// set. 221class TitleWatcher : public WebContentsObserver { 222 public: 223 // |web_contents| must be non-NULL and needs to stay alive for the 224 // entire lifetime of |this|. |expected_title| is the title that |this| 225 // will wait for. 226 TitleWatcher(WebContents* web_contents, 227 const base::string16& expected_title); 228 virtual ~TitleWatcher(); 229 230 // Adds another title to watch for. 231 void AlsoWaitForTitle(const base::string16& expected_title); 232 233 // Waits until the title matches either expected_title or one of the titles 234 // added with AlsoWaitForTitle. Returns the value of the most recently 235 // observed matching title. 236 const base::string16& WaitAndGetTitle() WARN_UNUSED_RESULT; 237 238 private: 239 // Overridden WebContentsObserver methods. 240 virtual void DidStopLoading(RenderViewHost* render_view_host) OVERRIDE; 241 virtual void TitleWasSet(NavigationEntry* entry, bool explicit_set) OVERRIDE; 242 243 void TestTitle(); 244 245 std::vector<base::string16> expected_titles_; 246 scoped_refptr<MessageLoopRunner> message_loop_runner_; 247 248 // The most recently observed expected title, if any. 249 base::string16 observed_title_; 250 251 DISALLOW_COPY_AND_ASSIGN(TitleWatcher); 252}; 253 254// Watches a WebContents and blocks until it is destroyed. 255class WebContentsDestroyedWatcher : public WebContentsObserver { 256 public: 257 explicit WebContentsDestroyedWatcher(WebContents* web_contents); 258 virtual ~WebContentsDestroyedWatcher(); 259 260 // Waits until the WebContents is destroyed. 261 void Wait(); 262 263 private: 264 // Overridden WebContentsObserver methods. 265 virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE; 266 267 scoped_refptr<MessageLoopRunner> message_loop_runner_; 268 269 DISALLOW_COPY_AND_ASSIGN(WebContentsDestroyedWatcher); 270}; 271 272// Watches a RenderProcessHost and waits for specified destruction events. 273class RenderProcessHostWatcher : public RenderProcessHostObserver { 274 public: 275 enum WatchType { 276 WATCH_FOR_PROCESS_EXIT, 277 WATCH_FOR_HOST_DESTRUCTION 278 }; 279 280 RenderProcessHostWatcher(RenderProcessHost* render_process_host, 281 WatchType type); 282 // Waits for the render process that contains the specified web contents. 283 RenderProcessHostWatcher(WebContents* web_contents, WatchType type); 284 virtual ~RenderProcessHostWatcher(); 285 286 // Waits until the renderer process exits. 287 void Wait(); 288 289 private: 290 // Overridden RenderProcessHost::LifecycleObserver methods. 291 virtual void RenderProcessExited(RenderProcessHost* host, 292 base::ProcessHandle handle, 293 base::TerminationStatus status, 294 int exit_code) OVERRIDE; 295 virtual void RenderProcessHostDestroyed(RenderProcessHost* host) OVERRIDE; 296 297 RenderProcessHost* render_process_host_; 298 WatchType type_; 299 300 scoped_refptr<MessageLoopRunner> message_loop_runner_; 301 302 DISALLOW_COPY_AND_ASSIGN(RenderProcessHostWatcher); 303}; 304 305// Watches for responses from the DOMAutomationController and keeps them in a 306// queue. Useful for waiting for a message to be received. 307class DOMMessageQueue : public NotificationObserver { 308 public: 309 // Constructs a DOMMessageQueue and begins listening for messages from the 310 // DOMAutomationController. Do not construct this until the browser has 311 // started. 312 DOMMessageQueue(); 313 virtual ~DOMMessageQueue(); 314 315 // Removes all messages in the message queue. 316 void ClearQueue(); 317 318 // Wait for the next message to arrive. |message| will be set to the next 319 // message, if not null. Returns true on success. 320 bool WaitForMessage(std::string* message) WARN_UNUSED_RESULT; 321 322 // Overridden NotificationObserver methods. 323 virtual void Observe(int type, 324 const NotificationSource& source, 325 const NotificationDetails& details) OVERRIDE; 326 327 private: 328 NotificationRegistrar registrar_; 329 std::queue<std::string> message_queue_; 330 bool waiting_for_message_; 331 scoped_refptr<MessageLoopRunner> message_loop_runner_; 332 333 DISALLOW_COPY_AND_ASSIGN(DOMMessageQueue); 334}; 335 336} // namespace content 337 338#endif // CONTENT_PUBLIC_TEST_BROWSER_TEST_UTILS_H_ 339