15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/browser_test_utils.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_reader.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
1158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include "base/process/kill.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/rand_util.h"
137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/string_number_conversions.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/waitable_event.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/test/test_timeouts.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h"
18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/browser/renderer_host/render_widget_host_impl.h"
19010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/browser/web_contents/web_contents_view.h"
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/common/input/synthetic_web_input_event_builders.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_context.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/dom_operation_notification_details.h"
2303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "content/public/browser/histogram_fetcher.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/browser/notification_types.h"
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/browser/render_frame_host.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_process_host.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents_observer.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_utils.h"
32c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "net/base/filename_util.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/cookies/cookie_store.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/test/python_utils.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/compositor/test/draw_waiter_for_test.h"
40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/events/gestures/gesture_configuration.h"
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/events/keycodes/dom4/keycode_converter.h"
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/resources/grit/webui_resources.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(USE_AURA)
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/aura/test/window_event_dispatcher_test_api.h"
46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/aura/window.h"
47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/aura/window_event_dispatcher.h"
48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/aura/window_tree_host.h"
49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif  // USE_AURA
50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DOMOperationObserver : public NotificationObserver,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             public WebContentsObserver {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit DOMOperationObserver(RenderViewHost* rvh)
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : WebContentsObserver(WebContents::FromRenderViewHost(rvh)),
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        did_respond_(false) {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    registrar_.Add(this, NOTIFICATION_DOM_OPERATION_RESPONSE,
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   Source<WebContents>(web_contents()));
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_loop_runner_ = new MessageLoopRunner;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Observe(int type,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const NotificationSource& source,
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const NotificationDetails& details) OVERRIDE {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(type == NOTIFICATION_DOM_OPERATION_RESPONSE);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Details<DomOperationNotificationDetails> dom_op_details(details);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response_ = dom_op_details->json;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    did_respond_ = true;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_loop_runner_->Quit();
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from WebContentsObserver:
767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_loop_runner_->Quit();
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool WaitAndGetResponse(std::string* response) WARN_UNUSED_RESULT {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_loop_runner_->Run();
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *response = response_;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return did_respond_;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotificationRegistrar registrar_;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool did_respond_;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MessageLoopRunner> message_loop_runner_;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DOMOperationObserver);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Specifying a prototype so that we can add the WARN_UNUSED_RESULT attribute.
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ExecuteScriptHelper(
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RenderFrameHost* render_frame_host,
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::string& original_script,
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    scoped_ptr<base::Value>* result) WARN_UNUSED_RESULT;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Executes the passed |original_script| in the frame specified by
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// |render_frame_host|.  If |result| is not NULL, stores the value that the
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// evaluation of the script in |result|.  Returns true on success.
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ExecuteScriptHelper(RenderFrameHost* render_frame_host,
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                         const std::string& original_script,
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                         scoped_ptr<base::Value>* result) {
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // TODO(jcampan): we should make the domAutomationController not require an
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  //                automation id.
109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::string script =
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      "window.domAutomationController.setAutomationId(0);" + original_script;
111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DOMOperationObserver dom_op_observer(render_frame_host->GetRenderViewHost());
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  render_frame_host->ExecuteJavaScriptForTests(base::UTF8ToUTF16(script));
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::string json;
114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!dom_op_observer.WaitAndGetResponse(&json)) {
115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DLOG(ERROR) << "Cannot communicate with DOMOperationObserver.";
116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Nothing more to do for callers that ignore the returned JS value.
120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!result)
121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return true;
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::JSONReader reader(base::JSON_ALLOW_TRAILING_COMMAS);
124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  result->reset(reader.ReadToValue(json));
125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!result->get()) {
126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DLOG(ERROR) << reader.GetErrorMessage();
127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return true;
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void BuildSimpleWebKeyEvent(blink::WebInputEvent::Type type,
13458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                            ui::KeyboardCode key_code,
13558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                            int native_key_code,
13668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                            int modifiers,
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            NativeWebKeyboardEvent* event) {
13858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  event->nativeKeyCode = native_key_code;
13958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  event->windowsKeyCode = key_code;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event->setKeyIdentifierFromWindowsKeyCode();
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event->type = type;
14268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  event->modifiers = modifiers;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event->isSystemKey = false;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event->timeStampSeconds = base::Time::Now().ToDoubleT();
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event->skip_in_browser = true;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (type == blink::WebInputEvent::Char ||
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      type == blink::WebInputEvent::RawKeyDown) {
14958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    event->text[0] = key_code;
15058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    event->unmodifiedText[0] = key_code;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void InjectRawKeyEvent(WebContents* web_contents,
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       blink::WebInputEvent::Type type,
15668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                       ui::KeyboardCode key_code,
15768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                       int native_key_code,
15868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                       int modifiers) {
15968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  NativeWebKeyboardEvent event;
16068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  BuildSimpleWebKeyEvent(type, key_code, native_key_code, modifiers, &event);
16168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  web_contents->GetRenderViewHost()->ForwardKeyboardEvent(event);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetCookiesCallback(std::string* cookies_out,
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        base::WaitableEvent* event,
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        const std::string& cookies) {
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *cookies_out = cookies;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event->Signal();
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetCookiesOnIOThread(const GURL& url,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          net::URLRequestContextGetter* context_getter,
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          base::WaitableEvent* event,
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          std::string* cookies) {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CookieStore* cookie_store =
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      context_getter->GetURLRequestContext()->cookie_store();
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cookie_store->GetCookiesWithOptionsAsync(
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, net::CookieOptions(),
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&GetCookiesCallback, cookies, event));
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetCookieCallback(bool* result,
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       base::WaitableEvent* event,
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       bool success) {
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *result = success;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event->Signal();
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetCookieOnIOThread(const GURL& url,
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const std::string& value,
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         net::URLRequestContextGetter* context_getter,
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         base::WaitableEvent* event,
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         bool* result) {
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CookieStore* cookie_store =
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      context_getter->GetURLRequestContext()->cookie_store();
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cookie_store->SetCookieWithOptionsAsync(
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, value, net::CookieOptions(),
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&SetCookieCallback, result, event));
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GURL GetFileUrlWithQuery(const base::FilePath& path,
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const std::string& query_string) {
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url = net::FilePathToFileURL(path);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!query_string.empty()) {
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL::Replacements replacements;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    replacements.SetQueryStr(query_string);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return url.ReplaceComponents(replacements);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return url;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WaitForLoadStop(WebContents* web_contents) {
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In many cases, the load may have finished before we get here.  Only wait if
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the tab still has a pending navigation.
218116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (web_contents->IsLoading()) {
219116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    WindowedNotificationObserver load_stop_observer(
220116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        NOTIFICATION_LOAD_STOP,
221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        Source<NavigationController>(&web_contents->GetController()));
222116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    load_stop_observer.Wait();
223116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CrashTab(WebContents* web_contents) {
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderProcessHost* rph = web_contents->GetRenderProcessHost();
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RenderProcessHostWatcher watcher(
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      rph, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::KillProcess(rph->GetHandle(), 0, false);
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  watcher.Wait();
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
234116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(USE_AURA)
235116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool IsResizeComplete(aura::test::WindowEventDispatcherTestApi* dispatcher_test,
236116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                      RenderWidgetHostImpl* widget_host) {
237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return !dispatcher_test->HoldingPointerMoves() &&
238116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      !widget_host->resize_ack_pending_for_testing();
239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
241116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid WaitForResizeComplete(WebContents* web_contents) {
242116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  aura::Window* content = web_contents->GetContentNativeView();
243116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!content)
244116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
245116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
246116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  aura::WindowTreeHost* window_host = content->GetHost();
247116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  aura::WindowEventDispatcher* dispatcher = window_host->dispatcher();
248116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  aura::test::WindowEventDispatcherTestApi dispatcher_test(dispatcher);
249116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RenderWidgetHostImpl* widget_host =
250116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      RenderWidgetHostImpl::From(web_contents->GetRenderViewHost());
251116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!IsResizeComplete(&dispatcher_test, widget_host)) {
252116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    WindowedNotificationObserver resize_observer(
253116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE,
254116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        base::Bind(IsResizeComplete, &dispatcher_test, widget_host));
255116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    resize_observer.Wait();
256116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
257116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
258116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif  // USE_AURA
259116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SimulateMouseClick(WebContents* web_contents,
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        int modifiers,
262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        blink::WebMouseEvent::Button button) {
263010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  int x = web_contents->GetContainerBounds().width() / 2;
264010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  int y = web_contents->GetContainerBounds().height() / 2;
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SimulateMouseClickAt(web_contents, modifiers, button, gfx::Point(x, y));
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SimulateMouseClickAt(WebContents* web_contents,
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          int modifiers,
270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          blink::WebMouseEvent::Button button,
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          const gfx::Point& point) {
272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  blink::WebMouseEvent mouse_event;
273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  mouse_event.type = blink::WebInputEvent::MouseDown;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_event.button = button;
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mouse_event.x = point.x();
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mouse_event.y = point.y();
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_event.modifiers = modifiers;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Mac needs globalX/globalY for events to plugins.
279010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  gfx::Rect offset = web_contents->GetContainerBounds();
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mouse_event.globalX = point.x() + offset.x();
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mouse_event.globalY = point.y() + offset.y();
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_event.clickCount = 1;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_contents->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  mouse_event.type = blink::WebInputEvent::MouseUp;
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_contents->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SimulateMouseEvent(WebContents* web_contents,
289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        blink::WebInputEvent::Type type,
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        const gfx::Point& point) {
291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  blink::WebMouseEvent mouse_event;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_event.type = type;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_event.x = point.x();
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_event.y = point.y();
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_contents->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
298cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void SimulateTapAt(WebContents* web_contents, const gfx::Point& point) {
2996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  blink::WebGestureEvent tap;
3006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  tap.type = blink::WebGestureEvent::GestureTap;
3016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  tap.x = point.x();
3026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  tap.y = point.y();
303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  RenderWidgetHostImpl* widget_host =
304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      RenderWidgetHostImpl::From(web_contents->GetRenderViewHost());
3056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  widget_host->ForwardGestureEvent(tap);
306cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SimulateKeyPress(WebContents* web_contents,
30958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                      ui::KeyboardCode key_code,
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      bool control,
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      bool shift,
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      bool alt,
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      bool command) {
31458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  SimulateKeyPressWithCode(
31558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      web_contents, key_code, NULL, control, shift, alt, command);
31658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
31758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
31858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void SimulateKeyPressWithCode(WebContents* web_contents,
31958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              ui::KeyboardCode key_code,
32058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              const char* code,
32158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              bool control,
32258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              bool shift,
32358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              bool alt,
32458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              bool command) {
3251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int native_key_code = ui::KeycodeConverter::CodeToNativeKeycode(code);
32668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
32768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int modifiers = 0;
32868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
32968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // The order of these key down events shouldn't matter for our simulation.
33068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // For our simulation we can use either the left keys or the right keys.
33168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (control) {
332f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    modifiers |= blink::WebInputEvent::ControlKey;
3331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    InjectRawKeyEvent(web_contents,
3341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      blink::WebInputEvent::RawKeyDown,
3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      ui::VKEY_CONTROL,
3361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      ui::KeycodeConverter::CodeToNativeKeycode("ControlLeft"),
3371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      modifiers);
33868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
33968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
34068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (shift) {
341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    modifiers |= blink::WebInputEvent::ShiftKey;
3421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    InjectRawKeyEvent(web_contents,
3431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      blink::WebInputEvent::RawKeyDown,
3441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      ui::VKEY_SHIFT,
3451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      ui::KeycodeConverter::CodeToNativeKeycode("ShiftLeft"),
3461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      modifiers);
34768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
34868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
34968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (alt) {
350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    modifiers |= blink::WebInputEvent::AltKey;
3511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    InjectRawKeyEvent(web_contents,
3521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      blink::WebInputEvent::RawKeyDown,
3531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      ui::VKEY_MENU,
3541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      ui::KeycodeConverter::CodeToNativeKeycode("AltLeft"),
3551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      modifiers);
35668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
35758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
35868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (command) {
359f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    modifiers |= blink::WebInputEvent::MetaKey;
3601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    InjectRawKeyEvent(web_contents,
3611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      blink::WebInputEvent::RawKeyDown,
3621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      ui::VKEY_COMMAND,
3631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      ui::KeycodeConverter::CodeToNativeKeycode("OSLeft"),
3641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      modifiers);
36568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
36668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
36768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  InjectRawKeyEvent(
36868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      web_contents,
369f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      blink::WebInputEvent::RawKeyDown,
37058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      key_code,
37158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      native_key_code,
37268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      modifiers);
37368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
37468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  InjectRawKeyEvent(
37568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      web_contents,
376f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      blink::WebInputEvent::Char,
37758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      key_code,
37858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      native_key_code,
37968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      modifiers);
38068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
38168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  InjectRawKeyEvent(
38268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      web_contents,
383f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      blink::WebInputEvent::KeyUp,
38458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      key_code,
38558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      native_key_code,
38668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      modifiers);
38768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
38868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // The order of these key releases shouldn't matter for our simulation.
38968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (control) {
390f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    modifiers &= ~blink::WebInputEvent::ControlKey;
3911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    InjectRawKeyEvent(web_contents,
3921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      blink::WebInputEvent::KeyUp,
3931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      ui::VKEY_CONTROL,
3941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      ui::KeycodeConverter::CodeToNativeKeycode("ControlLeft"),
3951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      modifiers);
39668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
39768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
39868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (shift) {
399f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    modifiers &= ~blink::WebInputEvent::ShiftKey;
4001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    InjectRawKeyEvent(web_contents,
4011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      blink::WebInputEvent::KeyUp,
4021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      ui::VKEY_SHIFT,
4031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      ui::KeycodeConverter::CodeToNativeKeycode("ShiftLeft"),
4041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      modifiers);
40568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
40668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
40768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (alt) {
408f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    modifiers &= ~blink::WebInputEvent::AltKey;
4091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    InjectRawKeyEvent(web_contents,
4101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      blink::WebInputEvent::KeyUp,
4111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      ui::VKEY_MENU,
4121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      ui::KeycodeConverter::CodeToNativeKeycode("AltLeft"),
4131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      modifiers);
41468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
41568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
41668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (command) {
417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    modifiers &= ~blink::WebInputEvent::MetaKey;
4181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    InjectRawKeyEvent(web_contents,
4191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      blink::WebInputEvent::KeyUp,
4201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      ui::VKEY_COMMAND,
4211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      ui::KeycodeConverter::CodeToNativeKeycode("OSLeft"),
4221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      modifiers);
42368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
42468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
42568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ASSERT_EQ(modifiers, 0);
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace internal {
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
430a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ToRenderFrameHost::ToRenderFrameHost(WebContents* web_contents)
431a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : render_frame_host_(web_contents->GetMainFrame()) {
432a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
433a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
434a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ToRenderFrameHost::ToRenderFrameHost(RenderViewHost* render_view_host)
435a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : render_frame_host_(render_view_host->GetMainFrame()) {
436a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
437a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
438a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ToRenderFrameHost::ToRenderFrameHost(RenderFrameHost* render_frame_host)
439a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : render_frame_host_(render_frame_host) {
440a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
441a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace internal
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
444a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ExecuteScript(const internal::ToRenderFrameHost& adapter,
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   const std::string& script) {
446a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::string new_script =
447a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      script + ";window.domAutomationController.send(0);";
448a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return ExecuteScriptHelper(adapter.render_frame_host(), new_script, NULL);
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
451a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ExecuteScriptAndExtractInt(const internal::ToRenderFrameHost& adapter,
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                const std::string& script, int* result) {
453a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(result);
454a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<base::Value> value;
455a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!ExecuteScriptHelper(adapter.render_frame_host(), script, &value) ||
456a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      !value.get()) {
457a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
458a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
459a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
460a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return value->GetAsInteger(result);
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
463a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ExecuteScriptAndExtractBool(const internal::ToRenderFrameHost& adapter,
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 const std::string& script, bool* result) {
465a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(result);
466a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<base::Value> value;
467a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!ExecuteScriptHelper(adapter.render_frame_host(), script, &value) ||
468a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      !value.get()) {
469a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
470a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
471a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
472a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return value->GetAsBoolean(result);
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
475a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ExecuteScriptAndExtractString(const internal::ToRenderFrameHost& adapter,
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   const std::string& script,
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   std::string* result) {
478a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(result);
479a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<base::Value> value;
480a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!ExecuteScriptHelper(adapter.render_frame_host(), script, &value) ||
481a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      !value.get()) {
482a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
483a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
484a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
485a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return value->GetAsString(result);
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
48823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)namespace {
48923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void AddToSetIfFrameMatchesPredicate(
49023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    std::set<RenderFrameHost*>* frame_set,
49123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const base::Callback<bool(RenderFrameHost*)>& predicate,
49223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    RenderFrameHost* host) {
49323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (predicate.Run(host))
49423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    frame_set->insert(host);
49523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
49623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
49723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
49823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)RenderFrameHost* FrameMatchingPredicate(
49923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    WebContents* web_contents,
50023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const base::Callback<bool(RenderFrameHost*)>& predicate) {
50123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  std::set<RenderFrameHost*> frame_set;
50223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  web_contents->ForEachFrame(
50323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      base::Bind(&AddToSetIfFrameMatchesPredicate, &frame_set, predicate));
50423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  DCHECK_EQ(1U, frame_set.size());
50523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return *frame_set.begin();
50623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
50723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
50823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)bool FrameMatchesName(const std::string& name, RenderFrameHost* frame) {
50923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return frame->GetFrameName() == name;
51023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
51123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
51223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)bool FrameIsChildOfMainFrame(RenderFrameHost* frame) {
51323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return frame->GetParent() && !frame->GetParent()->GetParent();
51423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
51523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
51623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)bool FrameHasSourceUrl(const GURL& url, RenderFrameHost* frame) {
51723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return frame->GetLastCommittedURL() == url;
51823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
51923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
520a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ExecuteWebUIResourceTest(WebContents* web_contents,
521a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              const std::vector<int>& js_resource_ids) {
5223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Inject WebUI test runner script first prior to other scripts required to
5233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // run the test as scripts may depend on it being declared.
5243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::vector<int> ids;
5253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ids.push_back(IDR_WEBUI_JS_WEBUI_RESOURCE_TEST);
5263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ids.insert(ids.end(), js_resource_ids.begin(), js_resource_ids.end());
5273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::string script;
5293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  for (std::vector<int>::iterator iter = ids.begin();
5303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)       iter != ids.end();
5313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)       ++iter) {
5323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ResourceBundle::GetSharedInstance().GetRawDataResource(*iter)
5333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        .AppendToString(&script);
5343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    script.append("\n");
5353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
53623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (!ExecuteScript(web_contents, script))
5373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
5383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
53923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  DOMMessageQueue message_queue;
54023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (!ExecuteScript(web_contents, "runTests()"))
5413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
5423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::string message;
5443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  do {
5453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (!message_queue.WaitForMessage(&message))
5463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      return false;
5473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  } while (message.compare("\"PENDING\"") == 0);
5483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return message.compare("\"SUCCESS\"") == 0;
5503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
5513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetCookies(BrowserContext* browser_context, const GURL& url) {
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string cookies;
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WaitableEvent event(true, false);
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestContextGetter* context_getter =
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser_context->GetRequestContext();
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::IO, FROM_HERE,
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&GetCookiesOnIOThread, url,
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 make_scoped_refptr(context_getter), &event, &cookies));
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event.Wait();
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return cookies;
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SetCookie(BrowserContext* browser_context,
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               const GURL& url,
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               const std::string& value) {
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool result = false;
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WaitableEvent event(true, false);
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestContextGetter* context_getter =
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser_context->GetRequestContext();
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::IO, FROM_HERE,
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&SetCookieOnIOThread, url, value,
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 make_scoped_refptr(context_getter), &event, &result));
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event.Wait();
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void FetchHistogramsFromChildProcesses() {
58303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_refptr<content::MessageLoopRunner> runner = new MessageLoopRunner;
58403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
58503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  FetchHistogramsAsynchronously(
58603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::MessageLoop::current(),
58703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      runner->QuitClosure(),
58803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      // If this call times out, it means that a child process is not
58903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      // responding, which is something we should not ignore.  The timeout is
59003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      // set to be longer than the normal browser test timeout so that it will
59103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      // be prempted by the normal timeout.
59203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      TestTimeouts::action_max_timeout());
59303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  runner->Run();
59403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
59503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TitleWatcher::TitleWatcher(WebContents* web_contents,
597a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                           const base::string16& expected_title)
5984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    : WebContentsObserver(web_contents),
5994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      message_loop_runner_(new MessageLoopRunner) {
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(web_contents != NULL);
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected_titles_.push_back(expected_title);
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
604a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void TitleWatcher::AlsoWaitForTitle(const base::string16& expected_title) {
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected_titles_.push_back(expected_title);
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TitleWatcher::~TitleWatcher() {
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
611a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const base::string16& TitleWatcher::WaitAndGetTitle() {
6125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestTitle();
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_loop_runner_->Run();
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return observed_title_;
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void TitleWatcher::DidStopLoading(RenderViewHost* render_view_host) {
6184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // When navigating through the history, the restored NavigationEntry's title
6194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // will be used. If the entry ends up having the same title after we return
6204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // to it, as will usually be the case, then WebContentsObserver::TitleSet
6214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // will then be suppressed, since the NavigationEntry's title hasn't changed.
6224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  TestTitle();
6234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
6244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void TitleWatcher::TitleWasSet(NavigationEntry* entry, bool explicit_set) {
6264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  TestTitle();
6274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void TitleWatcher::TestTitle() {
630a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<base::string16>::const_iterator it =
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::find(expected_titles_.begin(),
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                expected_titles_.end(),
6334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                web_contents()->GetTitle());
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (it == expected_titles_.end())
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observed_title_ = *it;
6384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  message_loop_runner_->Quit();
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)WebContentsDestroyedWatcher::WebContentsDestroyedWatcher(
6428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    WebContents* web_contents)
6438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    : WebContentsObserver(web_contents),
6448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      message_loop_runner_(new MessageLoopRunner) {
6458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  EXPECT_TRUE(web_contents != NULL);
6468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
6478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
6488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)WebContentsDestroyedWatcher::~WebContentsDestroyedWatcher() {
6498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
6508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
6518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void WebContentsDestroyedWatcher::Wait() {
6528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  message_loop_runner_->Run();
6538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
6548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
655010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void WebContentsDestroyedWatcher::WebContentsDestroyed() {
6568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  message_loop_runner_->Quit();
6578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
6588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
6595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)RenderProcessHostWatcher::RenderProcessHostWatcher(
6605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    RenderProcessHost* render_process_host, WatchType type)
6615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : render_process_host_(render_process_host),
6625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      type_(type),
6635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      message_loop_runner_(new MessageLoopRunner) {
6645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  render_process_host_->AddObserver(this);
6655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
6665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)RenderProcessHostWatcher::RenderProcessHostWatcher(
6685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    WebContents* web_contents, WatchType type)
6695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : render_process_host_(web_contents->GetRenderProcessHost()),
6705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      type_(type),
6715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      message_loop_runner_(new MessageLoopRunner) {
6725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  render_process_host_->AddObserver(this);
6735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
6745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)RenderProcessHostWatcher::~RenderProcessHostWatcher() {
6765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (render_process_host_)
6775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    render_process_host_->RemoveObserver(this);
6785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
6795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void RenderProcessHostWatcher::Wait() {
6815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  message_loop_runner_->Run();
6825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
6835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void RenderProcessHostWatcher::RenderProcessExited(
6855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    RenderProcessHost* host,
6865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::ProcessHandle handle,
6875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::TerminationStatus status,
6885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int exit_code) {
6895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (type_ == WATCH_FOR_PROCESS_EXIT)
6905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    message_loop_runner_->Quit();
6915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
6925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void RenderProcessHostWatcher::RenderProcessHostDestroyed(
6945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    RenderProcessHost* host) {
6955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  render_process_host_ = NULL;
6965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (type_ == WATCH_FOR_HOST_DESTRUCTION)
6975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    message_loop_runner_->Quit();
6985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
6995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
700effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochDOMMessageQueue::DOMMessageQueue() {
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  registrar_.Add(this, NOTIFICATION_DOM_OPERATION_RESPONSE,
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 NotificationService::AllSources());
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DOMMessageQueue::~DOMMessageQueue() {}
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DOMMessageQueue::Observe(int type,
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const NotificationSource& source,
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const NotificationDetails& details) {
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Details<DomOperationNotificationDetails> dom_op_details(details);
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_queue_.push(dom_op_details->json);
7121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (message_loop_runner_.get())
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_loop_runner_->Quit();
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DOMMessageQueue::ClearQueue() {
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_queue_ = std::queue<std::string>();
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DOMMessageQueue::WaitForMessage(std::string* message) {
721effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK(message);
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (message_queue_.empty()) {
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This will be quit when a new message comes in.
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_loop_runner_ = new MessageLoopRunner;
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_loop_runner_->Run();
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The queue should not be empty, unless we were quit because of a timeout.
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (message_queue_.empty())
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
730effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  *message = message_queue_.front();
731eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  message_queue_.pop();
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
736