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/web_contents_observer.h" 21 #include "third_party/WebKit/public/web/WebInputEvent.h" 22 #include "ui/events/keycodes/keyboard_codes.h" 23 #include "url/gurl.h" 24 25 #if defined(OS_WIN) 26 #include "base/win/scoped_handle.h" 27 #endif 28 29 class CommandLine; 30 31 namespace base { 32 class RunLoop; 33 } 34 35 namespace gfx { 36 class Point; 37 } 38 39 // A collections of functions designed for use with content_browsertests and 40 // browser_tests. 41 // TO BE CLEAR: any function here must work against both binaries. If it only 42 // works with browser_tests, it should be in chrome\test\base\ui_test_utils.h. 43 // If it only works with content_browsertests, it should be in 44 // content\test\content_browser_test_utils.h. 45 46 namespace content { 47 48 class BrowserContext; 49 class MessageLoopRunner; 50 class RenderViewHost; 51 class WebContents; 52 53 // Generate a URL for a file path including a query string. 54 GURL GetFileUrlWithQuery(const base::FilePath& path, 55 const std::string& query_string); 56 57 // Waits for a load stop for the specified |web_contents|'s controller, if the 58 // tab is currently web_contents. Otherwise returns immediately. 59 void WaitForLoadStop(WebContents* web_contents); 60 61 // Causes the specified web_contents to crash. Blocks until it is crashed. 62 void CrashTab(WebContents* web_contents); 63 64 // Simulates clicking at the center of the given tab asynchronously; modifiers 65 // may contain bits from WebInputEvent::Modifiers. 66 void SimulateMouseClick(WebContents* web_contents, 67 int modifiers, 68 blink::WebMouseEvent::Button button); 69 70 // Simulates clicking at the point |point| of the given tab asynchronously; 71 // modifiers may contain bits from WebInputEvent::Modifiers. 72 void SimulateMouseClickAt(WebContents* web_contents, 73 int modifiers, 74 blink::WebMouseEvent::Button button, 75 const gfx::Point& point); 76 77 // Simulates asynchronously a mouse enter/move/leave event. 78 void SimulateMouseEvent(WebContents* web_contents, 79 blink::WebInputEvent::Type type, 80 const gfx::Point& point); 81 82 // Sends a key press asynchronously. 83 // The native code of the key event will be set to InvalidNativeKeycode(). 84 // |key_code| alone is good enough for scenarios that only need the char 85 // value represented by a key event and not the physical key on the keyboard 86 // or the keyboard layout. 87 // For scenarios such as chromoting that need the native code, 88 // SimulateKeyPressWithCode should be used. 89 void SimulateKeyPress(WebContents* web_contents, 90 ui::KeyboardCode key_code, 91 bool control, 92 bool shift, 93 bool alt, 94 bool command); 95 96 // Sends a key press asynchronously. 97 // |code| specifies the UIEvents (aka: DOM4Events) value of the key: 98 // https://dvcs.w3.org/hg/d4e/raw-file/tip/source_respec.htm 99 // The native code of the key event will be set based on |code|. 100 // See ui/base/keycodes/vi usb_keycode_map.h for mappings between |code| 101 // and the native code. 102 // Examples of the various codes: 103 // key_code: VKEY_A 104 // code: "KeyA" 105 // native key code: 0x001e (for Windows). 106 // native key code: 0x0026 (for Linux). 107 void SimulateKeyPressWithCode(WebContents* web_contents, 108 ui::KeyboardCode key_code, 109 const char* code, 110 bool control, 111 bool shift, 112 bool alt, 113 bool command); 114 115 // Allow ExecuteScript* methods to target either a WebContents or a 116 // RenderViewHost. Targetting a WebContents means executing 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 namespace internal { 121 class ToRenderViewHost { 122 public: 123 ToRenderViewHost(WebContents* web_contents); 124 ToRenderViewHost(RenderViewHost* render_view_host); 125 126 RenderViewHost* render_view_host() const { return render_view_host_; } 127 128 private: 129 RenderViewHost* render_view_host_; 130 }; 131 } // namespace internal 132 133 // Executes the passed |script| in the frame pointed to by |frame_xpath| (use 134 // empty string for main frame). The |script| should not invoke 135 // domAutomationController.send(); otherwise, your test will hang or be flaky. 136 // If you want to extract a result, use one of the below functions. 137 // Returns true on success. 138 bool ExecuteScriptInFrame(const internal::ToRenderViewHost& adapter, 139 const std::string& frame_xpath, 140 const std::string& script) WARN_UNUSED_RESULT; 141 142 // The following methods executes the passed |script| in the frame pointed to by 143 // |frame_xpath| (use empty string for main frame) and sets |result| to the 144 // value passed to "window.domAutomationController.send" by the executed script. 145 // They return true on success, false if the script execution failed or did not 146 // evaluate to the expected type. 147 bool ExecuteScriptInFrameAndExtractInt( 148 const internal::ToRenderViewHost& adapter, 149 const std::string& frame_xpath, 150 const std::string& script, 151 int* result) WARN_UNUSED_RESULT; 152 bool ExecuteScriptInFrameAndExtractBool( 153 const internal::ToRenderViewHost& adapter, 154 const std::string& frame_xpath, 155 const std::string& script, 156 bool* result) WARN_UNUSED_RESULT; 157 bool ExecuteScriptInFrameAndExtractString( 158 const internal::ToRenderViewHost& adapter, 159 const std::string& frame_xpath, 160 const std::string& script, 161 std::string* result) WARN_UNUSED_RESULT; 162 163 // Top-frame script execution helpers (a.k.a., the common case): 164 bool ExecuteScript(const internal::ToRenderViewHost& adapter, 165 const std::string& script) WARN_UNUSED_RESULT; 166 bool ExecuteScriptAndExtractInt(const internal::ToRenderViewHost& adapter, 167 const std::string& script, 168 int* result) WARN_UNUSED_RESULT; 169 bool ExecuteScriptAndExtractBool(const internal::ToRenderViewHost& adapter, 170 const std::string& script, 171 bool* result) WARN_UNUSED_RESULT; 172 bool ExecuteScriptAndExtractString(const internal::ToRenderViewHost& adapter, 173 const std::string& script, 174 std::string* result) WARN_UNUSED_RESULT; 175 176 // Executes the WebUI resource test runner injecting each resource ID in 177 // |js_resource_ids| prior to executing the tests. 178 // 179 // Returns true if tests ran successfully, false otherwise. 180 bool ExecuteWebUIResourceTest(const internal::ToRenderViewHost& adapter, 181 const std::vector<int>& js_resource_ids); 182 183 // Returns the cookies for the given url. 184 std::string GetCookies(BrowserContext* browser_context, const GURL& url); 185 186 // Sets a cookie for the given url. Returns true on success. 187 bool SetCookie(BrowserContext* browser_context, 188 const GURL& url, 189 const std::string& value); 190 191 // Watches title changes on a WebContents, blocking until an expected title is 192 // set. 193 class TitleWatcher : public WebContentsObserver { 194 public: 195 // |web_contents| must be non-NULL and needs to stay alive for the 196 // entire lifetime of |this|. |expected_title| is the title that |this| 197 // will wait for. 198 TitleWatcher(WebContents* web_contents, 199 const base::string16& expected_title); 200 virtual ~TitleWatcher(); 201 202 // Adds another title to watch for. 203 void AlsoWaitForTitle(const base::string16& expected_title); 204 205 // Waits until the title matches either expected_title or one of the titles 206 // added with AlsoWaitForTitle. Returns the value of the most recently 207 // observed matching title. 208 const base::string16& WaitAndGetTitle() WARN_UNUSED_RESULT; 209 210 private: 211 // Overridden WebContentsObserver methods. 212 virtual void DidStopLoading(RenderViewHost* render_view_host) OVERRIDE; 213 virtual void TitleWasSet(NavigationEntry* entry, bool explicit_set) OVERRIDE; 214 215 void TestTitle(); 216 217 std::vector<base::string16> expected_titles_; 218 scoped_refptr<MessageLoopRunner> message_loop_runner_; 219 220 // The most recently observed expected title, if any. 221 base::string16 observed_title_; 222 223 DISALLOW_COPY_AND_ASSIGN(TitleWatcher); 224 }; 225 226 // Watches a WebContents and blocks until it is destroyed. 227 class WebContentsDestroyedWatcher : public WebContentsObserver { 228 public: 229 explicit WebContentsDestroyedWatcher(WebContents* web_contents); 230 virtual ~WebContentsDestroyedWatcher(); 231 232 // Waits until the WebContents is destroyed. 233 void Wait(); 234 235 private: 236 // Overridden WebContentsObserver methods. 237 virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE; 238 239 scoped_refptr<MessageLoopRunner> message_loop_runner_; 240 241 DISALLOW_COPY_AND_ASSIGN(WebContentsDestroyedWatcher); 242 }; 243 244 // Watches for responses from the DOMAutomationController and keeps them in a 245 // queue. Useful for waiting for a message to be received. 246 class DOMMessageQueue : public NotificationObserver { 247 public: 248 // Constructs a DOMMessageQueue and begins listening for messages from the 249 // DOMAutomationController. Do not construct this until the browser has 250 // started. 251 DOMMessageQueue(); 252 virtual ~DOMMessageQueue(); 253 254 // Removes all messages in the message queue. 255 void ClearQueue(); 256 257 // Wait for the next message to arrive. |message| will be set to the next 258 // message, if not null. Returns true on success. 259 bool WaitForMessage(std::string* message) WARN_UNUSED_RESULT; 260 261 // Overridden NotificationObserver methods. 262 virtual void Observe(int type, 263 const NotificationSource& source, 264 const NotificationDetails& details) OVERRIDE; 265 266 private: 267 NotificationRegistrar registrar_; 268 std::queue<std::string> message_queue_; 269 bool waiting_for_message_; 270 scoped_refptr<MessageLoopRunner> message_loop_runner_; 271 272 DISALLOW_COPY_AND_ASSIGN(DOMMessageQueue); 273 }; 274 275 } // namespace content 276 277 #endif // CONTENT_PUBLIC_TEST_BROWSER_TEST_UTILS_H_ 278