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