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_
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/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 "content/public/common/page_type.h"
23 #include "third_party/WebKit/public/web/WebInputEvent.h"
24 #include "ui/events/keycodes/keyboard_codes.h"
28 #include "base/win/scoped_handle.h"
40 namespace test_server
{
41 class EmbeddedTestServer
;
45 // A collections of functions designed for use with content_browsertests and
47 // TO BE CLEAR: any function here must work against both binaries. If it only
48 // works with browser_tests, it should be in chrome\test\base\ui_test_utils.h.
49 // If it only works with content_browsertests, it should be in
50 // content\test\content_browser_test_utils.h.
55 class MessageLoopRunner
;
59 // Navigate a frame with ID |iframe_id| to |url|, blocking until the navigation
60 // finishes. Uses a renderer-initiated navigation from script code in the
62 bool NavigateIframeToURL(WebContents
* web_contents
,
63 std::string iframe_id
,
66 // Generate a URL for a file path including a query string.
67 GURL
GetFileUrlWithQuery(const base::FilePath
& path
,
68 const std::string
& query_string
);
70 // Checks whether the page type of the last committed navigation entry matches
72 bool IsLastCommittedEntryOfPageType(WebContents
* web_contents
,
73 content::PageType page_type
);
75 // Waits for a load stop for the specified |web_contents|'s controller, if the
76 // tab is currently web_contents. Otherwise returns immediately. Tests should
77 // use WaitForLoadStop instead and check that last navigation succeeds, and
78 // this function should only be used if the navigation leads to web_contents
80 void WaitForLoadStopWithoutSuccessCheck(WebContents
* web_contents
);
82 // Waits for a load stop for the specified |web_contents|'s controller, if the
83 // tab is currently web_contents. Otherwise returns immediately. Returns true
84 // if the last navigation succeeded (resulted in a committed navigation entry
85 // of type PAGE_TYPE_NORMAL).
86 // TODO(alexmos): tests that use this function to wait for successful
87 // navigations should be refactored to do EXPECT_TRUE(WaitForLoadStop()).
88 bool WaitForLoadStop(WebContents
* web_contents
);
90 #if defined(USE_AURA) || defined(OS_ANDROID)
91 // If WebContent's view is currently being resized, this will wait for the ack
92 // from the renderer that the resize is complete and for the
93 // WindowEventDispatcher to release the pointer moves. If there's no resize in
94 // progress, the method will return right away.
95 void WaitForResizeComplete(WebContents
* web_contents
);
96 #endif // defined(USE_AURA) || defined(OS_ANDROID)
98 // Causes the specified web_contents to crash. Blocks until it is crashed.
99 void CrashTab(WebContents
* web_contents
);
101 // Simulates clicking at the center of the given tab asynchronously; modifiers
102 // may contain bits from WebInputEvent::Modifiers.
103 void SimulateMouseClick(WebContents
* web_contents
,
105 blink::WebMouseEvent::Button button
);
107 // Simulates clicking at the point |point| of the given tab asynchronously;
108 // modifiers may contain bits from WebInputEvent::Modifiers.
109 void SimulateMouseClickAt(WebContents
* web_contents
,
111 blink::WebMouseEvent::Button button
,
112 const gfx::Point
& point
);
114 // Simulates asynchronously a mouse enter/move/leave event.
115 void SimulateMouseEvent(WebContents
* web_contents
,
116 blink::WebInputEvent::Type type
,
117 const gfx::Point
& point
);
119 // Taps the screen at |point|.
120 void SimulateTapAt(WebContents
* web_contents
, const gfx::Point
& point
);
122 // Taps the screen with modifires at |point|.
123 void SimulateTapWithModifiersAt(WebContents
* web_contents
,
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
,
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:
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
,
161 // Allow ExecuteScript* methods to target either a WebContents or a
162 // RenderFrameHost. Targetting a WebContents means executing the script in the
163 // RenderFrameHost returned by WebContents::GetMainFrame(), which is the
164 // main frame. Pass a specific RenderFrameHost to target it.
165 class ToRenderFrameHost
{
167 ToRenderFrameHost(WebContents
* web_contents
);
168 ToRenderFrameHost(RenderViewHost
* render_view_host
);
169 ToRenderFrameHost(RenderFrameHost
* render_frame_host
);
171 RenderFrameHost
* render_frame_host() const { return render_frame_host_
; }
174 RenderFrameHost
* render_frame_host_
;
176 } // namespace internal
178 // Executes the passed |script| in the specified frame. The |script| should not
179 // invoke domAutomationController.send(); otherwise, your test will hang or be
180 // flaky. If you want to extract a result, use one of the below functions.
181 // Returns true on success.
182 bool ExecuteScript(const internal::ToRenderFrameHost
& adapter
,
183 const std::string
& script
) WARN_UNUSED_RESULT
;
185 // The following methods executes the passed |script| in the specified frame and
186 // sets |result| to the value passed to "window.domAutomationController.send" by
187 // the executed script. They return true on success, false if the script
188 // execution failed or did not evaluate to the expected type.
189 bool ExecuteScriptAndExtractInt(const internal::ToRenderFrameHost
& adapter
,
190 const std::string
& script
,
191 int* result
) WARN_UNUSED_RESULT
;
192 bool ExecuteScriptAndExtractBool(const internal::ToRenderFrameHost
& adapter
,
193 const std::string
& script
,
194 bool* result
) WARN_UNUSED_RESULT
;
195 bool ExecuteScriptAndExtractString(const internal::ToRenderFrameHost
& adapter
,
196 const std::string
& script
,
197 std::string
* result
) WARN_UNUSED_RESULT
;
199 // Walks the frame tree of the specified WebContents and returns the sole frame
200 // that matches the specified predicate function. This function will DCHECK if
201 // no frames match the specified predicate, or if more than one frame matches.
202 RenderFrameHost
* FrameMatchingPredicate(
203 WebContents
* web_contents
,
204 const base::Callback
<bool(RenderFrameHost
*)>& predicate
);
206 // Predicates for use with FrameMatchingPredicate.
207 bool FrameMatchesName(const std::string
& name
, RenderFrameHost
* frame
);
208 bool FrameIsChildOfMainFrame(RenderFrameHost
* frame
);
209 bool FrameHasSourceUrl(const GURL
& url
, RenderFrameHost
* frame
);
211 // Executes the WebUI resource test runner injecting each resource ID in
212 // |js_resource_ids| prior to executing the tests.
214 // Returns true if tests ran successfully, false otherwise.
215 bool ExecuteWebUIResourceTest(WebContents
* web_contents
,
216 const std::vector
<int>& js_resource_ids
);
218 // Returns the cookies for the given url.
219 std::string
GetCookies(BrowserContext
* browser_context
, const GURL
& url
);
221 // Sets a cookie for the given url. Returns true on success.
222 bool SetCookie(BrowserContext
* browser_context
,
224 const std::string
& value
);
226 // Fetch the histograms data from other processes. This should be called after
227 // the test code has been executed but before performing assertions.
228 void FetchHistogramsFromChildProcesses();
230 // Registers a request handler which redirects to a different host, based
231 // on the request path. The format of the path should be
232 // "/cross-site/hostname/rest/of/path" to redirect the request to
233 // "<scheme>://hostname:<port>/rest/of/path", where <scheme> and <port>
234 // are the values for the instance of EmbeddedTestServer.
235 void SetupCrossSiteRedirector(
236 net::test_server::EmbeddedTestServer
* embedded_test_server
);
238 // Waits for an interstitial page to attach to given web contents.
239 void WaitForInterstitialAttach(content::WebContents
* web_contents
);
241 // Waits for an interstitial page to detach from given web contents.
242 void WaitForInterstitialDetach(content::WebContents
* web_contents
);
244 // Runs task and waits for an interstitial page to detach from given web
245 // contents. Prefer this over WaitForInterstitialDetach if web_contents may be
246 // destroyed by the time WaitForInterstitialDetach is called (e.g. when waiting
247 // for an interstitial detach after closing a tab).
248 void RunTaskAndWaitForInterstitialDetach(content::WebContents
* web_contents
,
249 const base::Closure
& task
);
251 // Waits until all resources have loaded in the given RenderFrameHost.
252 // When the load completes, this function sends a "pageLoadComplete" message
253 // via domAutomationController. The caller should make sure this extra
254 // message is handled properly.
255 bool WaitForRenderFrameReady(RenderFrameHost
* rfh
) WARN_UNUSED_RESULT
;
257 // Watches title changes on a WebContents, blocking until an expected title is
259 class TitleWatcher
: public WebContentsObserver
{
261 // |web_contents| must be non-NULL and needs to stay alive for the
262 // entire lifetime of |this|. |expected_title| is the title that |this|
264 TitleWatcher(WebContents
* web_contents
,
265 const base::string16
& expected_title
);
266 ~TitleWatcher() override
;
268 // Adds another title to watch for.
269 void AlsoWaitForTitle(const base::string16
& expected_title
);
271 // Waits until the title matches either expected_title or one of the titles
272 // added with AlsoWaitForTitle. Returns the value of the most recently
273 // observed matching title.
274 const base::string16
& WaitAndGetTitle() WARN_UNUSED_RESULT
;
277 // Overridden WebContentsObserver methods.
278 void DidStopLoading() override
;
279 void TitleWasSet(NavigationEntry
* entry
, bool explicit_set
) override
;
283 std::vector
<base::string16
> expected_titles_
;
284 scoped_refptr
<MessageLoopRunner
> message_loop_runner_
;
286 // The most recently observed expected title, if any.
287 base::string16 observed_title_
;
289 DISALLOW_COPY_AND_ASSIGN(TitleWatcher
);
292 // Watches a WebContents and blocks until it is destroyed.
293 class WebContentsDestroyedWatcher
: public WebContentsObserver
{
295 explicit WebContentsDestroyedWatcher(WebContents
* web_contents
);
296 ~WebContentsDestroyedWatcher() override
;
298 // Waits until the WebContents is destroyed.
302 // Overridden WebContentsObserver methods.
303 void WebContentsDestroyed() override
;
305 scoped_refptr
<MessageLoopRunner
> message_loop_runner_
;
307 DISALLOW_COPY_AND_ASSIGN(WebContentsDestroyedWatcher
);
310 // Watches a RenderProcessHost and waits for specified destruction events.
311 class RenderProcessHostWatcher
: public RenderProcessHostObserver
{
314 WATCH_FOR_PROCESS_EXIT
,
315 WATCH_FOR_HOST_DESTRUCTION
318 RenderProcessHostWatcher(RenderProcessHost
* render_process_host
,
320 // Waits for the render process that contains the specified web contents.
321 RenderProcessHostWatcher(WebContents
* web_contents
, WatchType type
);
322 ~RenderProcessHostWatcher() override
;
324 // Waits until the renderer process exits.
328 // Overridden RenderProcessHost::LifecycleObserver methods.
329 void RenderProcessExited(RenderProcessHost
* host
,
330 base::TerminationStatus status
,
331 int exit_code
) override
;
332 void RenderProcessHostDestroyed(RenderProcessHost
* host
) override
;
334 RenderProcessHost
* render_process_host_
;
337 scoped_refptr
<MessageLoopRunner
> message_loop_runner_
;
339 DISALLOW_COPY_AND_ASSIGN(RenderProcessHostWatcher
);
342 // Watches for responses from the DOMAutomationController and keeps them in a
343 // queue. Useful for waiting for a message to be received.
344 class DOMMessageQueue
: public NotificationObserver
{
346 // Constructs a DOMMessageQueue and begins listening for messages from the
347 // DOMAutomationController. Do not construct this until the browser has
350 ~DOMMessageQueue() override
;
352 // Removes all messages in the message queue.
355 // Wait for the next message to arrive. |message| will be set to the next
356 // message. Returns true on success.
357 bool WaitForMessage(std::string
* message
) WARN_UNUSED_RESULT
;
359 // Overridden NotificationObserver methods.
360 void Observe(int type
,
361 const NotificationSource
& source
,
362 const NotificationDetails
& details
) override
;
365 NotificationRegistrar registrar_
;
366 std::queue
<std::string
> message_queue_
;
367 scoped_refptr
<MessageLoopRunner
> message_loop_runner_
;
369 DISALLOW_COPY_AND_ASSIGN(DOMMessageQueue
);
372 // Used to wait for a new WebContents to be created. Instantiate this object
373 // before the operation that will create the window.
374 class WebContentsAddedObserver
{
376 WebContentsAddedObserver();
377 ~WebContentsAddedObserver();
379 // Will run a message loop to wait for the new window if it hasn't been
380 // created since the constructor
381 WebContents
* GetWebContents();
383 // Will tell whether RenderViewCreated Callback has invoked
384 bool RenderViewCreatedCalled();
387 class RenderViewCreatedObserver
;
389 void WebContentsCreated(WebContents
* web_contents
);
391 // Callback to WebContentCreated(). Cached so that we can unregister it.
392 base::Callback
<void(WebContents
*)> web_contents_created_callback_
;
394 WebContents
* web_contents_
;
395 scoped_ptr
<RenderViewCreatedObserver
> child_observer_
;
396 scoped_refptr
<MessageLoopRunner
> runner_
;
398 DISALLOW_COPY_AND_ASSIGN(WebContentsAddedObserver
);
401 } // namespace content
403 #endif // CONTENT_PUBLIC_TEST_BROWSER_TEST_UTILS_H_