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