browser_test_utils.h revision 58e6fbe4ee35d65e14b626c557d37565bf8ad179
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
28class CommandLine;
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                        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.
71void 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.
77void SimulateMouseEvent(WebContents* web_contents,
78                        WebKit::WebInputEvent::Type type,
79                        const gfx::Point& point);
80
81// Sends a key press asynchronously.
82void 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.
94namespace internal {
95class 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.
112bool 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.
121bool ExecuteScriptInFrameAndExtractInt(
122    const internal::ToRenderViewHost& adapter,
123    const std::string& frame_xpath,
124    const std::string& script,
125    int* result) WARN_UNUSED_RESULT;
126bool ExecuteScriptInFrameAndExtractBool(
127    const internal::ToRenderViewHost& adapter,
128    const std::string& frame_xpath,
129    const std::string& script,
130    bool* result) WARN_UNUSED_RESULT;
131bool 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):
138bool ExecuteScript(const internal::ToRenderViewHost& adapter,
139                   const std::string& script) WARN_UNUSED_RESULT;
140bool ExecuteScriptAndExtractInt(const internal::ToRenderViewHost& adapter,
141                                const std::string& script,
142                                int* result) WARN_UNUSED_RESULT;
143bool ExecuteScriptAndExtractBool(const internal::ToRenderViewHost& adapter,
144                                 const std::string& script,
145                                 bool* result) WARN_UNUSED_RESULT;
146bool 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.
151std::string GetCookies(BrowserContext* browser_context, const GURL& url);
152
153// Sets a cookie for the given url. Returns true on success.
154bool 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.
159class 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.
198class 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