render_view_test.cc revision bb1529ce867d8845a77ec7cdf3e3003ef1771a40
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/render_view_test.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/run_loop.h"
8bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "content/common/dom_storage/dom_storage_types.h"
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/common/input_messages.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/view_messages.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/native_web_keyboard_event.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/renderer_preferences.h"
1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "content/public/renderer/history_item_serialization.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/render_thread_impl.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/render_view_impl.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/renderer_main_platform_delegate.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/renderer_webkitplatformsupport_impl.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/test/mock_render_process.h"
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLRequest.h"
207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebFrame.h"
217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebHistoryItem.h"
227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebInputEvent.h"
237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebKit.h"
247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebScreenInfo.h"
257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebScriptController.h"
267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebScriptSource.h"
277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebView.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "webkit/glue/webkit_glue.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebFrame;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebInputEvent;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebMouseEvent;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebScriptController;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebScriptSource;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebString;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebURLRequest;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int32 kOpenerId = -2;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int32 kRouteId = 5;
42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const int32 kMainFrameRouteId = 6;
43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const int32 kNewWindowRouteId = 7;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int32 kSurfaceId = 42;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class RendererWebKitPlatformSupportImplNoSandboxImpl
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : public RendererWebKitPlatformSupportImpl {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual WebKit::WebSandboxSupport* sandboxSupport() {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RenderViewTest::RendererWebKitPlatformSupportImplNoSandbox::
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RendererWebKitPlatformSupportImplNoSandbox() {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  webkit_platform_support_.reset(
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new RendererWebKitPlatformSupportImplNoSandboxImpl());
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RenderViewTest::RendererWebKitPlatformSupportImplNoSandbox::
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~RendererWebKitPlatformSupportImplNoSandbox() {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebKit::Platform*
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RenderViewTest::RendererWebKitPlatformSupportImplNoSandbox::Get() {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return webkit_platform_support_.get();
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RenderViewTest::RenderViewTest()
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : view_(NULL) {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RenderViewTest::~RenderViewTest() {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderViewTest::ProcessPendingMessages() {
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  msg_loop_.PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  msg_loop_.Run();
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebFrame* RenderViewTest::GetMainFrame() {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return view_->GetWebView()->mainFrame();
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderViewTest::ExecuteJavaScript(const char* js) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetMainFrame()->executeScript(WebScriptSource(WebString::fromUTF8(js)));
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RenderViewTest::ExecuteJavaScriptAndReturnIntValue(
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const string16& script,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int* int_result) {
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  v8::HandleScope handle_scope;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  v8::Handle<v8::Value> result =
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetMainFrame()->executeScriptAndReturnValue(WebScriptSource(script));
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result.IsEmpty() || !result->IsInt32())
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (int_result)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *int_result = result->Int32Value();
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderViewTest::LoadHTML(const char* html) {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string url_str = "data:text/html;charset=utf-8,";
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  url_str.append(html);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url(url_str);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetMainFrame()->loadRequest(WebURLRequest(url));
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The load actually happens asynchronously, so we pump messages to process
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the pending continuation.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProcessPendingMessages();
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderViewTest::GoBack(const WebKit::WebHistoryItem& item) {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GoToOffset(-1, item);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderViewTest::GoForward(const WebKit::WebHistoryItem& item) {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GoToOffset(1, item);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderViewTest::SetUp() {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Subclasses can set the ContentClient's renderer before calling
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // RenderViewTest::SetUp().
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ContentRendererClient* old_client =
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SetRendererClientForTesting(&content_renderer_client_);
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (old_client)
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SetRendererClientForTesting(old_client);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Subclasses can set render_thread_ with their own implementation before
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // calling RenderViewTest::SetUp().
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!render_thread_)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    render_thread_.reset(new MockRenderThread());
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  render_thread_->set_routing_id(kRouteId);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  render_thread_->set_surface_id(kSurfaceId);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  render_thread_->set_new_window_routing_id(kNewWindowRouteId);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  command_line_.reset(new CommandLine(CommandLine::NO_PROGRAM));
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params_.reset(new MainFunctionParams(*command_line_));
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  platform_.reset(new RendererMainPlatformDelegate(*params_));
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  platform_->PlatformInitialize();
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Setting flags and really doing anything with WebKit is fairly fragile and
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // hacky, but this is the world we live in...
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  webkit_glue::SetJavaScriptFlags(" --expose-gc");
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebKit::initialize(webkit_platform_support_.Get());
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that we register any necessary schemes when initializing WebKit,
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // since we are using a MockRenderThread.
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderThreadImpl::RegisterSchemes();
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This check is needed because when run under content_browsertests,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ResourceBundle isn't initialized (since we have to use a diferent test
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // suite implementation than for content_unittests). For browser_tests, this
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is already initialized.
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ResourceBundle::HasSharedInstance())
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ResourceBundle::InitSharedInstanceWithLocale("en-US", NULL);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mock_process_.reset(new MockRenderProcess);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This needs to pass the mock render thread to the view.
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderViewImpl* view = RenderViewImpl::Create(
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kOpenerId,
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      RendererPreferences(),
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      WebPreferences(),
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new SharedRenderViewCounter(0),
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kRouteId,
174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      kMainFrameRouteId,
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kSurfaceId,
176bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      kInvalidSessionStorageNamespaceId,
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      string16(),
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WebKit::WebScreenInfo(),
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      AccessibilityModeOff,
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      true);
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  view->AddRef();
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  view_ = view;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderViewTest::TearDown() {
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Try very hard to collect garbage before shutting down.
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetMainFrame()->collectGarbage();
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetMainFrame()->collectGarbage();
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run the loop so the release task from the renderwidget executes.
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProcessPendingMessages();
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  render_thread_->SendCloseMessage();
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  view_ = NULL;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mock_process_.reset();
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After telling the view to close and resetting mock_process_ we may get
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // some new tasks which need to be processed before shutting down WebKit
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (http://crbug.com/21508).
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::RunLoop().RunUntilIdle();
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebKit::shutdown();
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  platform_->PlatformUninitialize();
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  platform_.reset();
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params_.reset();
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  command_line_.reset();
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderViewTest::SendNativeKeyEvent(
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const NativeWebKeyboardEvent& key_event) {
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendWebKeyboardEvent(key_event);
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderViewTest::SendWebKeyboardEvent(
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebKit::WebKeyboardEvent& key_event) {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_);
221b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  impl->OnMessageReceived(
22290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      InputMsg_HandleInputEvent(0, &key_event, ui::LatencyInfo(), false));
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderViewTest::SendWebMouseEvent(
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebKit::WebMouseEvent& mouse_event) {
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_);
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  impl->OnMessageReceived(
22990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      InputMsg_HandleInputEvent(0, &mouse_event, ui::LatencyInfo(), false));
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kGetCoordinatesScript =
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "(function() {"
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  function GetCoordinates(elem) {"
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    if (!elem)"
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "      return [ 0, 0];"
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    var coordinates = [ elem.offsetLeft, elem.offsetTop];"
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    var parent_coordinates = GetCoordinates(elem.offsetParent);"
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    coordinates[0] += parent_coordinates[0];"
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    coordinates[1] += parent_coordinates[1];"
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    return coordinates;"
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  };"
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  var elem = document.getElementById('$1');"
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  if (!elem)"
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    return null;"
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  var bounds = GetCoordinates(elem);"
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  bounds[2] = elem.offsetWidth;"
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  bounds[3] = elem.offsetHeight;"
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  return bounds;"
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "})();";
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect RenderViewTest::GetElementBounds(const std::string& element_id) {
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> params;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.push_back(element_id);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string script =
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ReplaceStringPlaceholders(kGetCoordinatesScript, params, NULL);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  v8::HandleScope handle_scope;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  v8::Handle<v8::Value>  value = GetMainFrame()->executeScriptAndReturnValue(
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WebScriptSource(WebString::fromUTF8(script)));
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (value.IsEmpty() || !value->IsArray())
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return gfx::Rect();
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  v8::Handle<v8::Array> array = value.As<v8::Array>();
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (array->Length() != 4)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return gfx::Rect();
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<int> coords;
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 4; ++i) {
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    v8::Handle<v8::Number> index = v8::Number::New(i);
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    v8::Local<v8::Value> value = array->Get(index);
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (value.IsEmpty() || !value->IsInt32())
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Rect();
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    coords.push_back(value->Int32Value());
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gfx::Rect(coords[0], coords[1], coords[2], coords[3]);
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RenderViewTest::SimulateElementClick(const std::string& element_id) {
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect bounds = GetElementBounds(element_id);
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bounds.IsEmpty())
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebMouseEvent mouse_event;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_event.type = WebInputEvent::MouseDown;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_event.button = WebMouseEvent::ButtonLeft;
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_event.x = bounds.CenterPoint().x();
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_event.y = bounds.CenterPoint().y();
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_event.clickCount = 1;
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<IPC::Message> input_message(
28890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      new InputMsg_HandleInputEvent(0, &mouse_event, ui::LatencyInfo(), false));
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  impl->OnMessageReceived(*input_message);
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderViewTest::SetFocused(const WebKit::WebNode& node) {
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_);
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  impl->focusedNodeChanged(node);
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderViewTest::ClearHistory() {
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  impl->page_id_ = -1;
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  impl->history_list_offset_ = -1;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  impl->history_list_length_ = 0;
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  impl->history_page_ids_.clear();
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderViewTest::Reload(const GURL& url) {
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ViewMsg_Navigate_Params params;
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = url;
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.navigation_type = ViewMsg_Navigate_Type::RELOAD;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_);
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  impl->OnNavigate(params);
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32 RenderViewTest::GetNavigationIPCType() {
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ViewHostMsg_FrameNavigate::ID;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderViewTest::Resize(gfx::Size new_size,
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            gfx::Rect resizer_rect,
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            bool is_fullscreen) {
32290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ViewMsg_Resize_Params params;
32390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.screen_info = WebKit::WebScreenInfo();
32490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.new_size = new_size;
32590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.physical_backing_size = new_size;
32690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.overdraw_bottom_height = 0.f;
32790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.resizer_rect = resizer_rect;
32890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.is_fullscreen = is_fullscreen;
32990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<IPC::Message> resize_message(new ViewMsg_Resize(0, params));
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OnMessageReceived(*resize_message);
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RenderViewTest::OnMessageReceived(const IPC::Message& msg) {
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_);
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return impl->OnMessageReceived(msg);
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderViewTest::DidNavigateWithinPage(WebKit::WebFrame* frame,
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           bool is_new_navigation) {
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  impl->didNavigateWithinPage(frame, is_new_navigation);
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderViewTest::SendContentStateImmediately() {
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_);
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  impl->set_send_content_state_immediately(true);
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebKit::WebWidget* RenderViewTest::GetWebWidget() {
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_);
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return impl->webwidget();
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderViewTest::GoToOffset(int offset,
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const WebKit::WebHistoryItem& history_item) {
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_);
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int history_list_length = impl->historyBackListCount() +
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            impl->historyForwardListCount() + 1;
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pending_offset = offset + impl->history_list_offset();
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ViewMsg_Navigate_Params navigate_params;
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  navigate_params.navigation_type = ViewMsg_Navigate_Type::NORMAL;
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  navigate_params.transition = PAGE_TRANSITION_FORWARD_BACK;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  navigate_params.current_history_list_length = history_list_length;
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  navigate_params.current_history_list_offset = impl->history_list_offset();
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  navigate_params.pending_history_list_offset = pending_offset;
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  navigate_params.page_id = impl->GetPageId() + offset;
36990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  navigate_params.page_state = HistoryItemToPageState(history_item);
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  navigate_params.request_time = base::Time::Now();
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ViewMsg_Navigate navigate_message(impl->GetRoutingID(), navigate_params);
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OnMessageReceived(navigate_message);
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The load actually happens asynchronously, so we pump messages to process
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the pending continuation.
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProcessPendingMessages();
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
381