Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / content / public / test / browser_test_utils.h
blobf05f4037b4c0980626b8c48ff7d30397a63adcfd
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.
5 #ifndef CONTENT_PUBLIC_TEST_BROWSER_TEST_UTILS_H_
6 #define CONTENT_PUBLIC_TEST_BROWSER_TEST_UTILS_H_
8 #include <queue>
9 #include <string>
10 #include <vector>
12 #include "base/callback.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/browser_message_filter.h"
19 #include "content/public/browser/notification_observer.h"
20 #include "content/public/browser/notification_registrar.h"
21 #include "content/public/browser/render_process_host_observer.h"
22 #include "content/public/browser/web_contents_observer.h"
23 #include "content/public/common/page_type.h"
24 #include "third_party/WebKit/public/web/WebInputEvent.h"
25 #include "ui/events/keycodes/keyboard_codes.h"
26 #include "url/gurl.h"
28 #if defined(OS_WIN)
29 #include "base/win/scoped_handle.h"
30 #endif
32 namespace gfx {
33 class Point;
36 namespace net {
37 namespace test_server {
38 class EmbeddedTestServer;
42 // A collections of functions designed for use with content_browsertests and
43 // browser_tests.
44 // TO BE CLEAR: any function here must work against both binaries. If it only
45 // works with browser_tests, it should be in chrome\test\base\ui_test_utils.h.
46 // If it only works with content_browsertests, it should be in
47 // content\test\content_browser_test_utils.h.
49 namespace content {
51 class BrowserContext;
52 class MessageLoopRunner;
53 class RenderViewHost;
54 class WebContents;
56 // Navigate a frame with ID |iframe_id| to |url|, blocking until the navigation
57 // finishes. Uses a renderer-initiated navigation from script code in the
58 // main frame.
59 bool NavigateIframeToURL(WebContents* web_contents,
60 std::string iframe_id,
61 const GURL& url);
63 // Generate a URL for a file path including a query string.
64 GURL GetFileUrlWithQuery(const base::FilePath& path,
65 const std::string& query_string);
67 // Checks whether the page type of the last committed navigation entry matches
68 // |page_type|.
69 bool IsLastCommittedEntryOfPageType(WebContents* web_contents,
70 content::PageType page_type);
72 // Waits for a load stop for the specified |web_contents|'s controller, if the
73 // tab is currently web_contents. Otherwise returns immediately. Tests should
74 // use WaitForLoadStop instead and check that last navigation succeeds, and
75 // this function should only be used if the navigation leads to web_contents
76 // being destroyed.
77 void WaitForLoadStopWithoutSuccessCheck(WebContents* web_contents);
79 // Waits for a load stop for the specified |web_contents|'s controller, if the
80 // tab is currently web_contents. Otherwise returns immediately. Returns true
81 // if the last navigation succeeded (resulted in a committed navigation entry
82 // of type PAGE_TYPE_NORMAL).
83 // TODO(alexmos): tests that use this function to wait for successful
84 // navigations should be refactored to do EXPECT_TRUE(WaitForLoadStop()).
85 bool WaitForLoadStop(WebContents* web_contents);
87 #if defined(USE_AURA) || defined(OS_ANDROID)
88 // If WebContent's view is currently being resized, this will wait for the ack
89 // from the renderer that the resize is complete and for the
90 // WindowEventDispatcher to release the pointer moves. If there's no resize in
91 // progress, the method will return right away.
92 void WaitForResizeComplete(WebContents* web_contents);
93 #endif // defined(USE_AURA) || defined(OS_ANDROID)
95 // Causes the specified web_contents to crash. Blocks until it is crashed.
96 void CrashTab(WebContents* web_contents);
98 // Simulates clicking at the center of the given tab asynchronously; modifiers
99 // may contain bits from WebInputEvent::Modifiers.
100 void SimulateMouseClick(WebContents* web_contents,
101 int modifiers,
102 blink::WebMouseEvent::Button button);
104 // Simulates clicking at the point |point| of the given tab asynchronously;
105 // modifiers may contain bits from WebInputEvent::Modifiers.
106 void SimulateMouseClickAt(WebContents* web_contents,
107 int modifiers,
108 blink::WebMouseEvent::Button button,
109 const gfx::Point& point);
111 // Simulates asynchronously a mouse enter/move/leave event.
112 void SimulateMouseEvent(WebContents* web_contents,
113 blink::WebInputEvent::Type type,
114 const gfx::Point& point);
116 // Taps the screen at |point|.
117 void SimulateTapAt(WebContents* web_contents, const gfx::Point& point);
119 // Generates a TouchStart at |point|.
120 void SimulateTouchPressAt(WebContents* web_contents, const gfx::Point& point);
122 // Taps the screen with modifires at |point|.
123 void SimulateTapWithModifiersAt(WebContents* web_contents,
124 unsigned Modifiers,
125 const gfx::Point& point);
127 // Sends a key press asynchronously.
128 // The native code of the key event will be set to InvalidNativeKeycode().
129 // |key_code| alone is good enough for scenarios that only need the char
130 // value represented by a key event and not the physical key on the keyboard
131 // or the keyboard layout.
132 // For scenarios such as chromoting that need the native code,
133 // SimulateKeyPressWithCode should be used.
134 void SimulateKeyPress(WebContents* web_contents,
135 ui::KeyboardCode key_code,
136 bool control,
137 bool shift,
138 bool alt,
139 bool command);
141 // Sends a key press asynchronously.
142 // |code| specifies the UIEvents (aka: DOM4Events) value of the key:
143 // https://dvcs.w3.org/hg/d4e/raw-file/tip/source_respec.htm
144 // The native code of the key event will be set based on |code|.
145 // See ui/base/keycodes/vi usb_keycode_map.h for mappings between |code|
146 // and the native code.
147 // Examples of the various codes:
148 // key_code: VKEY_A
149 // code: "KeyA"
150 // native key code: 0x001e (for Windows).
151 // native key code: 0x0026 (for Linux).
152 void SimulateKeyPressWithCode(WebContents* web_contents,
153 ui::KeyboardCode key_code,
154 const char* code,
155 bool control,
156 bool shift,
157 bool alt,
158 bool command);
160 // Allow ExecuteScript* methods to target either a WebContents or a
161 // RenderFrameHost. Targetting a WebContents means executing the script in the
162 // RenderFrameHost returned by WebContents::GetMainFrame(), which is the
163 // main frame. Pass a specific RenderFrameHost to target it.
164 class ToRenderFrameHost {
165 public:
166 ToRenderFrameHost(WebContents* web_contents);
167 ToRenderFrameHost(RenderViewHost* render_view_host);
168 ToRenderFrameHost(RenderFrameHost* render_frame_host);
170 RenderFrameHost* render_frame_host() const { return render_frame_host_; }
172 private:
173 RenderFrameHost* render_frame_host_;
176 // Executes the passed |script| in the specified frame. The |script| should not
177 // invoke domAutomationController.send(); otherwise, your test will hang or be
178 // flaky. If you want to extract a result, use one of the below functions.
179 // Returns true on success.
180 bool ExecuteScript(const ToRenderFrameHost& adapter,
181 const std::string& script) WARN_UNUSED_RESULT;
183 // The following methods executes the passed |script| in the specified frame and
184 // sets |result| to the value passed to "window.domAutomationController.send" by
185 // the executed script. They return true on success, false if the script
186 // execution failed or did not evaluate to the expected type.
187 bool ExecuteScriptAndExtractInt(const ToRenderFrameHost& adapter,
188 const std::string& script,
189 int* result) WARN_UNUSED_RESULT;
190 bool ExecuteScriptAndExtractBool(const ToRenderFrameHost& adapter,
191 const std::string& script,
192 bool* result) WARN_UNUSED_RESULT;
193 bool ExecuteScriptAndExtractString(const ToRenderFrameHost& adapter,
194 const std::string& script,
195 std::string* result) WARN_UNUSED_RESULT;
197 // Walks the frame tree of the specified WebContents and returns the sole frame
198 // that matches the specified predicate function. This function will DCHECK if
199 // no frames match the specified predicate, or if more than one frame matches.
200 RenderFrameHost* FrameMatchingPredicate(
201 WebContents* web_contents,
202 const base::Callback<bool(RenderFrameHost*)>& predicate);
204 // Predicates for use with FrameMatchingPredicate.
205 bool FrameMatchesName(const std::string& name, RenderFrameHost* frame);
206 bool FrameIsChildOfMainFrame(RenderFrameHost* frame);
207 bool FrameHasSourceUrl(const GURL& url, RenderFrameHost* frame);
209 // Executes the WebUI resource test runner injecting each resource ID in
210 // |js_resource_ids| prior to executing the tests.
212 // Returns true if tests ran successfully, false otherwise.
213 bool ExecuteWebUIResourceTest(WebContents* web_contents,
214 const std::vector<int>& js_resource_ids);
216 // Returns the cookies for the given url.
217 std::string GetCookies(BrowserContext* browser_context, const GURL& url);
219 // Sets a cookie for the given url. Returns true on success.
220 bool SetCookie(BrowserContext* browser_context,
221 const GURL& url,
222 const std::string& value);
224 // Fetch the histograms data from other processes. This should be called after
225 // the test code has been executed but before performing assertions.
226 void FetchHistogramsFromChildProcesses();
228 // Registers a request handler which redirects to a different host, based
229 // on the request path. The format of the path should be
230 // "/cross-site/hostname/rest/of/path" to redirect the request to
231 // "<scheme>://hostname:<port>/rest/of/path", where <scheme> and <port>
232 // are the values for the instance of EmbeddedTestServer.
233 void SetupCrossSiteRedirector(
234 net::test_server::EmbeddedTestServer* embedded_test_server);
236 // Waits for an interstitial page to attach to given web contents.
237 void WaitForInterstitialAttach(content::WebContents* web_contents);
239 // Waits for an interstitial page to detach from given web contents.
240 void WaitForInterstitialDetach(content::WebContents* web_contents);
242 // Runs task and waits for an interstitial page to detach from given web
243 // contents. Prefer this over WaitForInterstitialDetach if web_contents may be
244 // destroyed by the time WaitForInterstitialDetach is called (e.g. when waiting
245 // for an interstitial detach after closing a tab).
246 void RunTaskAndWaitForInterstitialDetach(content::WebContents* web_contents,
247 const base::Closure& task);
249 // Waits until all resources have loaded in the given RenderFrameHost.
250 // When the load completes, this function sends a "pageLoadComplete" message
251 // via domAutomationController. The caller should make sure this extra
252 // message is handled properly.
253 bool WaitForRenderFrameReady(RenderFrameHost* rfh) WARN_UNUSED_RESULT;
255 // Watches title changes on a WebContents, blocking until an expected title is
256 // set.
257 class TitleWatcher : public WebContentsObserver {
258 public:
259 // |web_contents| must be non-NULL and needs to stay alive for the
260 // entire lifetime of |this|. |expected_title| is the title that |this|
261 // will wait for.
262 TitleWatcher(WebContents* web_contents,
263 const base::string16& expected_title);
264 ~TitleWatcher() override;
266 // Adds another title to watch for.
267 void AlsoWaitForTitle(const base::string16& expected_title);
269 // Waits until the title matches either expected_title or one of the titles
270 // added with AlsoWaitForTitle. Returns the value of the most recently
271 // observed matching title.
272 const base::string16& WaitAndGetTitle() WARN_UNUSED_RESULT;
274 private:
275 // Overridden WebContentsObserver methods.
276 void DidStopLoading() override;
277 void TitleWasSet(NavigationEntry* entry, bool explicit_set) override;
279 void TestTitle();
281 std::vector<base::string16> expected_titles_;
282 scoped_refptr<MessageLoopRunner> message_loop_runner_;
284 // The most recently observed expected title, if any.
285 base::string16 observed_title_;
287 DISALLOW_COPY_AND_ASSIGN(TitleWatcher);
290 // Watches a RenderProcessHost and waits for specified destruction events.
291 class RenderProcessHostWatcher : public RenderProcessHostObserver {
292 public:
293 enum WatchType {
294 WATCH_FOR_PROCESS_EXIT,
295 WATCH_FOR_HOST_DESTRUCTION
298 RenderProcessHostWatcher(RenderProcessHost* render_process_host,
299 WatchType type);
300 // Waits for the render process that contains the specified web contents.
301 RenderProcessHostWatcher(WebContents* web_contents, WatchType type);
302 ~RenderProcessHostWatcher() override;
304 // Waits until the renderer process exits.
305 void Wait();
307 // Returns true if a renderer process exited cleanly (without hitting
308 // RenderProcessExited with an abnormal TerminationStatus). This should be
309 // called after Wait().
310 bool did_exit_normally() { return did_exit_normally_; }
312 private:
313 // Overridden RenderProcessHost::LifecycleObserver methods.
314 void RenderProcessExited(RenderProcessHost* host,
315 base::TerminationStatus status,
316 int exit_code) override;
317 void RenderProcessHostDestroyed(RenderProcessHost* host) override;
319 RenderProcessHost* render_process_host_;
320 WatchType type_;
321 bool did_exit_normally_;
323 scoped_refptr<MessageLoopRunner> message_loop_runner_;
325 DISALLOW_COPY_AND_ASSIGN(RenderProcessHostWatcher);
328 // Watches for responses from the DOMAutomationController and keeps them in a
329 // queue. Useful for waiting for a message to be received.
330 class DOMMessageQueue : public NotificationObserver {
331 public:
332 // Constructs a DOMMessageQueue and begins listening for messages from the
333 // DOMAutomationController. Do not construct this until the browser has
334 // started.
335 DOMMessageQueue();
336 ~DOMMessageQueue() override;
338 // Removes all messages in the message queue.
339 void ClearQueue();
341 // Wait for the next message to arrive. |message| will be set to the next
342 // message. Returns true on success.
343 bool WaitForMessage(std::string* message) WARN_UNUSED_RESULT;
345 // Overridden NotificationObserver methods.
346 void Observe(int type,
347 const NotificationSource& source,
348 const NotificationDetails& details) override;
350 private:
351 NotificationRegistrar registrar_;
352 std::queue<std::string> message_queue_;
353 scoped_refptr<MessageLoopRunner> message_loop_runner_;
355 DISALLOW_COPY_AND_ASSIGN(DOMMessageQueue);
358 // Used to wait for a new WebContents to be created. Instantiate this object
359 // before the operation that will create the window.
360 class WebContentsAddedObserver {
361 public:
362 WebContentsAddedObserver();
363 ~WebContentsAddedObserver();
365 // Will run a message loop to wait for the new window if it hasn't been
366 // created since the constructor
367 WebContents* GetWebContents();
369 // Will tell whether RenderViewCreated Callback has invoked
370 bool RenderViewCreatedCalled();
372 private:
373 class RenderViewCreatedObserver;
375 void WebContentsCreated(WebContents* web_contents);
377 // Callback to WebContentCreated(). Cached so that we can unregister it.
378 base::Callback<void(WebContents*)> web_contents_created_callback_;
380 WebContents* web_contents_;
381 scoped_ptr<RenderViewCreatedObserver> child_observer_;
382 scoped_refptr<MessageLoopRunner> runner_;
384 DISALLOW_COPY_AND_ASSIGN(WebContentsAddedObserver);
387 // Request a new frame be drawn, returns false if request fails.
388 bool RequestFrame(WebContents* web_contents);
390 // Watches compositor frame changes, blocking until a frame has been
391 // composited. This class is intended to be run on the main thread; to
392 // synchronize the main thread against the impl thread.
393 class FrameWatcher : public BrowserMessageFilter {
394 public:
395 FrameWatcher();
397 // Listen for new frames from the |web_contents| renderer process.
398 void AttachTo(WebContents* web_contents);
400 // Wait for |frames_to_wait| swap mesages from the compositor.
401 void WaitFrames(int frames_to_wait);
403 private:
404 ~FrameWatcher() override;
406 // Overridden BrowserMessageFilter methods.
407 bool OnMessageReceived(const IPC::Message& message) override;
409 void ReceivedFrameSwap();
411 int frames_to_wait_;
412 base::Closure quit_;
414 DISALLOW_COPY_AND_ASSIGN(FrameWatcher);
417 } // namespace content
419 #endif // CONTENT_PUBLIC_TEST_BROWSER_TEST_UTILS_H_