Home | History | Annotate | Download | only in test
      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 
     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                         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.
     71 void 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.
     77 void SimulateMouseEvent(WebContents* web_contents,
     78                         blink::WebInputEvent::Type type,
     79                         const gfx::Point& point);
     80 
     81 // Taps the screen at |point|.
     82 void SimulateTapAt(WebContents* web_contents, const gfx::Point& point);
     83 
     84 // Sends a key press asynchronously.
     85 // The native code of the key event will be set to InvalidNativeKeycode().
     86 // |key_code| alone is good enough for scenarios that only need the char
     87 // value represented by a key event and not the physical key on the keyboard
     88 // or the keyboard layout.
     89 // For scenarios such as chromoting that need the native code,
     90 // SimulateKeyPressWithCode should be used.
     91 void SimulateKeyPress(WebContents* web_contents,
     92                       ui::KeyboardCode key_code,
     93                       bool control,
     94                       bool shift,
     95                       bool alt,
     96                       bool command);
     97 
     98 // Sends a key press asynchronously.
     99 // |code| specifies the UIEvents (aka: DOM4Events) value of the key:
    100 // https://dvcs.w3.org/hg/d4e/raw-file/tip/source_respec.htm
    101 // The native code of the key event will be set based on |code|.
    102 // See ui/base/keycodes/vi usb_keycode_map.h for mappings between |code|
    103 // and the native code.
    104 // Examples of the various codes:
    105 //   key_code: VKEY_A
    106 //   code: "KeyA"
    107 //   native key code: 0x001e (for Windows).
    108 //   native key code: 0x0026 (for Linux).
    109 void SimulateKeyPressWithCode(WebContents* web_contents,
    110                               ui::KeyboardCode key_code,
    111                               const char* code,
    112                               bool control,
    113                               bool shift,
    114                               bool alt,
    115                               bool command);
    116 
    117 namespace internal {
    118 // Allow ExecuteScript* methods to target either a WebContents or a
    119 // RenderFrameHost.  Targetting a WebContents means executing the script in the
    120 // RenderFrameHost returned by WebContents::GetMainFrame(), which is the
    121 // main frame.  Pass a specific RenderFrameHost to target it.
    122 class ToRenderFrameHost {
    123  public:
    124   ToRenderFrameHost(WebContents* web_contents);
    125   ToRenderFrameHost(RenderViewHost* render_view_host);
    126   ToRenderFrameHost(RenderFrameHost* render_frame_host);
    127 
    128   RenderFrameHost* render_frame_host() const { return render_frame_host_; }
    129 
    130  private:
    131   RenderFrameHost* render_frame_host_;
    132 };
    133 }  // namespace internal
    134 
    135 // Executes the passed |script| in the specified frame. The |script| should not
    136 // invoke domAutomationController.send(); otherwise, your test will hang or be
    137 // flaky. If you want to extract a result, use one of the below functions.
    138 // Returns true on success.
    139 bool ExecuteScript(const internal::ToRenderFrameHost& adapter,
    140                    const std::string& script) WARN_UNUSED_RESULT;
    141 
    142 // The following methods executes the passed |script| in the specified frame and
    143 // sets |result| to the value passed to "window.domAutomationController.send" by
    144 // the executed script. They return true on success, false if the script
    145 // execution failed or did not evaluate to the expected type.
    146 bool ExecuteScriptAndExtractInt(const internal::ToRenderFrameHost& adapter,
    147                                 const std::string& script,
    148                                 int* result) WARN_UNUSED_RESULT;
    149 bool ExecuteScriptAndExtractBool(const internal::ToRenderFrameHost& adapter,
    150                                  const std::string& script,
    151                                  bool* result) WARN_UNUSED_RESULT;
    152 bool ExecuteScriptAndExtractString(const internal::ToRenderFrameHost& adapter,
    153                                    const std::string& script,
    154                                    std::string* result) WARN_UNUSED_RESULT;
    155 
    156 // Walks the frame tree of the specified WebContents and returns the sole frame
    157 // that matches the specified predicate function. This function will DCHECK if
    158 // no frames match the specified predicate, or if more than one frame matches.
    159 RenderFrameHost* FrameMatchingPredicate(
    160     WebContents* web_contents,
    161     const base::Callback<bool(RenderFrameHost*)>& predicate);
    162 
    163 // Predicates for use with FrameMatchingPredicate.
    164 bool FrameMatchesName(const std::string& name, RenderFrameHost* frame);
    165 bool FrameIsChildOfMainFrame(RenderFrameHost* frame);
    166 bool FrameHasSourceUrl(const GURL& url, RenderFrameHost* frame);
    167 
    168 // Executes the WebUI resource test runner injecting each resource ID in
    169 // |js_resource_ids| prior to executing the tests.
    170 //
    171 // Returns true if tests ran successfully, false otherwise.
    172 bool ExecuteWebUIResourceTest(WebContents* web_contents,
    173                               const std::vector<int>& js_resource_ids);
    174 
    175 // Returns the cookies for the given url.
    176 std::string GetCookies(BrowserContext* browser_context, const GURL& url);
    177 
    178 // Sets a cookie for the given url. Returns true on success.
    179 bool SetCookie(BrowserContext* browser_context,
    180                const GURL& url,
    181                const std::string& value);
    182 
    183 // Watches title changes on a WebContents, blocking until an expected title is
    184 // set.
    185 class TitleWatcher : public WebContentsObserver {
    186  public:
    187   // |web_contents| must be non-NULL and needs to stay alive for the
    188   // entire lifetime of |this|. |expected_title| is the title that |this|
    189   // will wait for.
    190   TitleWatcher(WebContents* web_contents,
    191                const base::string16& expected_title);
    192   virtual ~TitleWatcher();
    193 
    194   // Adds another title to watch for.
    195   void AlsoWaitForTitle(const base::string16& expected_title);
    196 
    197   // Waits until the title matches either expected_title or one of the titles
    198   // added with AlsoWaitForTitle. Returns the value of the most recently
    199   // observed matching title.
    200   const base::string16& WaitAndGetTitle() WARN_UNUSED_RESULT;
    201 
    202  private:
    203   // Overridden WebContentsObserver methods.
    204   virtual void DidStopLoading(RenderViewHost* render_view_host) OVERRIDE;
    205   virtual void TitleWasSet(NavigationEntry* entry, bool explicit_set) OVERRIDE;
    206 
    207   void TestTitle();
    208 
    209   std::vector<base::string16> expected_titles_;
    210   scoped_refptr<MessageLoopRunner> message_loop_runner_;
    211 
    212   // The most recently observed expected title, if any.
    213   base::string16 observed_title_;
    214 
    215   DISALLOW_COPY_AND_ASSIGN(TitleWatcher);
    216 };
    217 
    218 // Watches a WebContents and blocks until it is destroyed.
    219 class WebContentsDestroyedWatcher : public WebContentsObserver {
    220  public:
    221   explicit WebContentsDestroyedWatcher(WebContents* web_contents);
    222   virtual ~WebContentsDestroyedWatcher();
    223 
    224   // Waits until the WebContents is destroyed.
    225   void Wait();
    226 
    227  private:
    228   // Overridden WebContentsObserver methods.
    229   virtual void WebContentsDestroyed() OVERRIDE;
    230 
    231   scoped_refptr<MessageLoopRunner> message_loop_runner_;
    232 
    233   DISALLOW_COPY_AND_ASSIGN(WebContentsDestroyedWatcher);
    234 };
    235 
    236 // Watches a RenderProcessHost and waits for specified destruction events.
    237 class RenderProcessHostWatcher : public RenderProcessHostObserver {
    238  public:
    239   enum WatchType {
    240     WATCH_FOR_PROCESS_EXIT,
    241     WATCH_FOR_HOST_DESTRUCTION
    242   };
    243 
    244   RenderProcessHostWatcher(RenderProcessHost* render_process_host,
    245                            WatchType type);
    246   // Waits for the render process that contains the specified web contents.
    247   RenderProcessHostWatcher(WebContents* web_contents, WatchType type);
    248   virtual ~RenderProcessHostWatcher();
    249 
    250   // Waits until the renderer process exits.
    251   void Wait();
    252 
    253  private:
    254   // Overridden RenderProcessHost::LifecycleObserver methods.
    255   virtual void RenderProcessExited(RenderProcessHost* host,
    256                                    base::ProcessHandle handle,
    257                                    base::TerminationStatus status,
    258                                    int exit_code) OVERRIDE;
    259   virtual void RenderProcessHostDestroyed(RenderProcessHost* host) OVERRIDE;
    260 
    261   RenderProcessHost* render_process_host_;
    262   WatchType type_;
    263 
    264   scoped_refptr<MessageLoopRunner> message_loop_runner_;
    265 
    266   DISALLOW_COPY_AND_ASSIGN(RenderProcessHostWatcher);
    267 };
    268 
    269 // Watches for responses from the DOMAutomationController and keeps them in a
    270 // queue. Useful for waiting for a message to be received.
    271 class DOMMessageQueue : public NotificationObserver {
    272  public:
    273   // Constructs a DOMMessageQueue and begins listening for messages from the
    274   // DOMAutomationController. Do not construct this until the browser has
    275   // started.
    276   DOMMessageQueue();
    277   virtual ~DOMMessageQueue();
    278 
    279   // Removes all messages in the message queue.
    280   void ClearQueue();
    281 
    282   // Wait for the next message to arrive. |message| will be set to the next
    283   // message. Returns true on success.
    284   bool WaitForMessage(std::string* message) WARN_UNUSED_RESULT;
    285 
    286   // Overridden NotificationObserver methods.
    287   virtual void Observe(int type,
    288                        const NotificationSource& source,
    289                        const NotificationDetails& details) OVERRIDE;
    290 
    291  private:
    292   NotificationRegistrar registrar_;
    293   std::queue<std::string> message_queue_;
    294   scoped_refptr<MessageLoopRunner> message_loop_runner_;
    295 
    296   DISALLOW_COPY_AND_ASSIGN(DOMMessageQueue);
    297 };
    298 
    299 }  // namespace content
    300 
    301 #endif  // CONTENT_PUBLIC_TEST_BROWSER_TEST_UTILS_H_
    302