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 "third_party/WebKit/public/web/WebInputEvent.h" 21 #include "ui/base/keycodes/keyboard_codes.h" 22 #include "url/gurl.h" 23 24 #if defined(OS_WIN) 25 #include "base/win/scoped_handle.h" 26 #endif 27 28 class CommandLine; 29 30 namespace base { 31 class RunLoop; 32 } 33 34 namespace gfx { 35 class 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 45 namespace content { 46 47 class BrowserContext; 48 class MessageLoopRunner; 49 class RenderViewHost; 50 class WebContents; 51 52 // Generate a URL for a file path including a query string. 53 GURL 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. 58 void WaitForLoadStop(WebContents* web_contents); 59 60 // Causes the specified web_contents to crash. Blocks until it is crashed. 61 void CrashTab(WebContents* web_contents); 62 63 // Simulates clicking at the center of the given tab asynchronously; modifiers 64 // may contain bits from WebInputEvent::Modifiers. 65 void SimulateMouseClick(WebContents* web_contents, 66 int modifiers, 67 WebKit::WebMouseEvent::Button button); 68 69 // Simulates clicking at the point |point| of the given tab asynchronously; 70 // modifiers may contain bits from WebInputEvent::Modifiers. 71 void SimulateMouseClickAt(WebContents* web_contents, 72 int modifiers, 73 WebKit::WebMouseEvent::Button button, 74 const gfx::Point& point); 75 76 // Simulates asynchronously a mouse enter/move/leave event. 77 void SimulateMouseEvent(WebContents* web_contents, 78 WebKit::WebInputEvent::Type type, 79 const gfx::Point& point); 80 81 // Sends a key press asynchronously. 82 void SimulateKeyPress(WebContents* web_contents, 83 ui::KeyboardCode key, 84 bool control, 85 bool shift, 86 bool alt, 87 bool command); 88 89 // Allow ExecuteScript* methods to target either a WebContents or a 90 // RenderViewHost. Targetting a WebContents means executing script in the 91 // RenderViewHost returned by WebContents::GetRenderViewHost(), which is the 92 // "current" RenderViewHost. Pass a specific RenderViewHost to target, for 93 // example, a "swapped-out" RenderViewHost. 94 namespace internal { 95 class ToRenderViewHost { 96 public: 97 ToRenderViewHost(WebContents* web_contents); 98 ToRenderViewHost(RenderViewHost* render_view_host); 99 100 RenderViewHost* render_view_host() const { return render_view_host_; } 101 102 private: 103 RenderViewHost* render_view_host_; 104 }; 105 } // namespace internal 106 107 // Executes the passed |script| in the frame pointed to by |frame_xpath| (use 108 // empty string for main frame). The |script| should not invoke 109 // domAutomationController.send(); otherwise, your test will hang or be flaky. 110 // If you want to extract a result, use one of the below functions. 111 // Returns true on success. 112 bool ExecuteScriptInFrame(const internal::ToRenderViewHost& adapter, 113 const std::string& frame_xpath, 114 const std::string& script) WARN_UNUSED_RESULT; 115 116 // The following methods executes the passed |script| in the frame pointed to by 117 // |frame_xpath| (use empty string for main frame) and sets |result| to the 118 // value passed to "window.domAutomationController.send" by the executed script. 119 // They return true on success, false if the script execution failed or did not 120 // evaluate to the expected type. 121 bool ExecuteScriptInFrameAndExtractInt( 122 const internal::ToRenderViewHost& adapter, 123 const std::string& frame_xpath, 124 const std::string& script, 125 int* result) WARN_UNUSED_RESULT; 126 bool ExecuteScriptInFrameAndExtractBool( 127 const internal::ToRenderViewHost& adapter, 128 const std::string& frame_xpath, 129 const std::string& script, 130 bool* result) WARN_UNUSED_RESULT; 131 bool ExecuteScriptInFrameAndExtractString( 132 const internal::ToRenderViewHost& adapter, 133 const std::string& frame_xpath, 134 const std::string& script, 135 std::string* result) WARN_UNUSED_RESULT; 136 137 // Top-frame script execution helpers (a.k.a., the common case): 138 bool ExecuteScript(const internal::ToRenderViewHost& adapter, 139 const std::string& script) WARN_UNUSED_RESULT; 140 bool ExecuteScriptAndExtractInt(const internal::ToRenderViewHost& adapter, 141 const std::string& script, 142 int* result) WARN_UNUSED_RESULT; 143 bool ExecuteScriptAndExtractBool(const internal::ToRenderViewHost& adapter, 144 const std::string& script, 145 bool* result) WARN_UNUSED_RESULT; 146 bool ExecuteScriptAndExtractString(const internal::ToRenderViewHost& adapter, 147 const std::string& script, 148 std::string* result) WARN_UNUSED_RESULT; 149 150 // Returns the cookies for the given url. 151 std::string GetCookies(BrowserContext* browser_context, const GURL& url); 152 153 // Sets a cookie for the given url. Returns true on success. 154 bool SetCookie(BrowserContext* browser_context, 155 const GURL& url, 156 const std::string& value); 157 158 // Watches title changes on a tab, blocking until an expected title is set. 159 class TitleWatcher : public NotificationObserver { 160 public: 161 // |web_contents| must be non-NULL and needs to stay alive for the 162 // entire lifetime of |this|. |expected_title| is the title that |this| 163 // will wait for. 164 TitleWatcher(WebContents* web_contents, 165 const string16& expected_title); 166 virtual ~TitleWatcher(); 167 168 // Adds another title to watch for. 169 void AlsoWaitForTitle(const string16& expected_title); 170 171 // Waits until the title matches either expected_title or one of the titles 172 // added with AlsoWaitForTitle. Returns the value of the most recently 173 // observed matching title. 174 const string16& WaitAndGetTitle() WARN_UNUSED_RESULT; 175 176 private: 177 // NotificationObserver 178 virtual void Observe(int type, 179 const NotificationSource& source, 180 const NotificationDetails& details) OVERRIDE; 181 182 WebContents* web_contents_; 183 std::vector<string16> expected_titles_; 184 NotificationRegistrar notification_registrar_; 185 scoped_refptr<MessageLoopRunner> message_loop_runner_; 186 187 // The most recently observed expected title, if any. 188 string16 observed_title_; 189 190 bool expected_title_observed_; 191 bool quit_loop_on_observation_; 192 193 DISALLOW_COPY_AND_ASSIGN(TitleWatcher); 194 }; 195 196 // Watches for responses from the DOMAutomationController and keeps them in a 197 // queue. Useful for waiting for a message to be received. 198 class DOMMessageQueue : public NotificationObserver { 199 public: 200 // Constructs a DOMMessageQueue and begins listening for messages from the 201 // DOMAutomationController. Do not construct this until the browser has 202 // started. 203 DOMMessageQueue(); 204 virtual ~DOMMessageQueue(); 205 206 // Removes all messages in the message queue. 207 void ClearQueue(); 208 209 // Wait for the next message to arrive. |message| will be set to the next 210 // message, if not null. Returns true on success. 211 bool WaitForMessage(std::string* message) WARN_UNUSED_RESULT; 212 213 // Overridden NotificationObserver methods. 214 virtual void Observe(int type, 215 const NotificationSource& source, 216 const NotificationDetails& details) OVERRIDE; 217 218 private: 219 NotificationRegistrar registrar_; 220 std::queue<std::string> message_queue_; 221 bool waiting_for_message_; 222 scoped_refptr<MessageLoopRunner> message_loop_runner_; 223 224 DISALLOW_COPY_AND_ASSIGN(DOMMessageQueue); 225 }; 226 227 } // namespace content 228 229 #endif // CONTENT_PUBLIC_TEST_BROWSER_TEST_UTILS_H_ 230