// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/basictypes.h"

#include "base/memory/shared_memory.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/windows_version.h"
#include "content/common/ssl_status_serialization.h"
#include "content/common/view_messages.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "content/public/browser/web_ui_controller_factory.h"
#include "content/public/common/bindings_policy.h"
#include "content/public/common/page_zoom.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/url_utils.h"
#include "content/public/renderer/document_state.h"
#include "content/public/renderer/history_item_serialization.h"
#include "content/public/renderer/navigation_state.h"
#include "content/public/test/render_view_test.h"
#include "content/renderer/render_view_impl.h"
#include "content/shell/browser/shell_content_browser_client.h"
#include "content/shell/common/shell_content_client.h"
#include "content/test/mock_keyboard.h"
#include "net/base/net_errors.h"
#include "net/cert/cert_status_flags.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/WebData.h"
#include "third_party/WebKit/public/platform/WebHTTPBody.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/WebURLError.h"
#include "third_party/WebKit/public/platform/WebURLResponse.h"
#include "third_party/WebKit/public/web/WebDataSource.h"
#include "third_party/WebKit/public/web/WebFrame.h"
#include "third_party/WebKit/public/web/WebHistoryItem.h"
#include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
#include "third_party/WebKit/public/web/WebView.h"
#include "third_party/WebKit/public/web/WebWindowFeatures.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/gfx/codec/jpeg_codec.h"
#include "ui/gfx/range/range.h"

#if defined(OS_LINUX) && !defined(USE_AURA)
#include "ui/base/gtk/event_synthesis_gtk.h"
#endif

#if defined(USE_AURA)
#include "ui/events/event.h"
#endif

#if defined(USE_AURA) && defined(USE_X11)
#include <X11/Xlib.h>
#include "ui/events/event_constants.h"
#include "ui/events/keycodes/keyboard_code_conversion.h"
#include "ui/events/test/events_test_utils_x11.h"
#endif

#if defined(USE_OZONE)
#include "ui/events/keycodes/keyboard_code_conversion.h"
#endif

using blink::WebFrame;
using blink::WebInputEvent;
using blink::WebMouseEvent;
using blink::WebRuntimeFeatures;
using blink::WebString;
using blink::WebTextDirection;
using blink::WebURLError;

namespace content  {

namespace {

#if (defined(USE_AURA) && defined(USE_X11)) || defined(USE_OZONE)
// Converts MockKeyboard::Modifiers to ui::EventFlags.
int ConvertMockKeyboardModifier(MockKeyboard::Modifiers modifiers) {
  static struct ModifierMap {
    MockKeyboard::Modifiers src;
    int dst;
  } kModifierMap[] = {
    { MockKeyboard::LEFT_SHIFT, ui::EF_SHIFT_DOWN },
    { MockKeyboard::RIGHT_SHIFT, ui::EF_SHIFT_DOWN },
    { MockKeyboard::LEFT_CONTROL, ui::EF_CONTROL_DOWN },
    { MockKeyboard::RIGHT_CONTROL, ui::EF_CONTROL_DOWN },
    { MockKeyboard::LEFT_ALT,  ui::EF_ALT_DOWN },
    { MockKeyboard::RIGHT_ALT, ui::EF_ALT_DOWN },
  };
  int flags = 0;
  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kModifierMap); ++i) {
    if (kModifierMap[i].src & modifiers) {
      flags |= kModifierMap[i].dst;
    }
  }
  return flags;
}
#endif

class WebUITestWebUIControllerFactory : public WebUIControllerFactory {
 public:
  virtual WebUIController* CreateWebUIControllerForURL(
      WebUI* web_ui, const GURL& url) const OVERRIDE {
    return NULL;
  }
  virtual WebUI::TypeID GetWebUIType(BrowserContext* browser_context,
                                     const GURL& url) const OVERRIDE {
    return WebUI::kNoWebUI;
  }
  virtual bool UseWebUIForURL(BrowserContext* browser_context,
                              const GURL& url) const OVERRIDE {
    return HasWebUIScheme(url);
  }
  virtual bool UseWebUIBindingsForURL(BrowserContext* browser_context,
                                      const GURL& url) const OVERRIDE {
    return HasWebUIScheme(url);
  }
};

}  // namespace

class RenderViewImplTest : public RenderViewTest {
 public:
  RenderViewImplTest() {
    // Attach a pseudo keyboard device to this object.
    mock_keyboard_.reset(new MockKeyboard());
  }

  virtual ~RenderViewImplTest() {}

  virtual void SetUp() OVERRIDE {
    RenderViewTest::SetUp();
    // Enable Blink's experimental and test only features so that test code
    // does not have to bother enabling each feature.
    WebRuntimeFeatures::enableExperimentalFeatures(true);
    WebRuntimeFeatures::enableTestOnlyFeatures(true);
  }

  RenderViewImpl* view() {
    return static_cast<RenderViewImpl*>(view_);
  }

  // Sends IPC messages that emulates a key-press event.
  int SendKeyEvent(MockKeyboard::Layout layout,
                   int key_code,
                   MockKeyboard::Modifiers modifiers,
                   base::string16* output) {
#if defined(OS_WIN)
    // Retrieve the Unicode character for the given tuple (keyboard-layout,
    // key-code, and modifiers).
    // Exit when a keyboard-layout driver cannot assign a Unicode character to
    // the tuple to prevent sending an invalid key code to the RenderView
    // object.
    CHECK(mock_keyboard_.get());
    CHECK(output);
    int length = mock_keyboard_->GetCharacters(layout, key_code, modifiers,
                                               output);
    if (length != 1)
      return -1;

    // Create IPC messages from Windows messages and send them to our
    // back-end.
    // A keyboard event of Windows consists of three Windows messages:
    // WM_KEYDOWN, WM_CHAR, and WM_KEYUP.
    // WM_KEYDOWN and WM_KEYUP sends virtual-key codes. On the other hand,
    // WM_CHAR sends a composed Unicode character.
    MSG msg1 = { NULL, WM_KEYDOWN, key_code, 0 };
#if defined(USE_AURA)
    ui::KeyEvent evt1(msg1, false);
    NativeWebKeyboardEvent keydown_event(&evt1);
#else
    NativeWebKeyboardEvent keydown_event(msg1);
#endif
    SendNativeKeyEvent(keydown_event);

    MSG msg2 = { NULL, WM_CHAR, (*output)[0], 0 };
#if defined(USE_AURA)
    ui::KeyEvent evt2(msg2, true);
    NativeWebKeyboardEvent char_event(&evt2);
#else
    NativeWebKeyboardEvent char_event(msg2);
#endif
    SendNativeKeyEvent(char_event);

    MSG msg3 = { NULL, WM_KEYUP, key_code, 0 };
#if defined(USE_AURA)
    ui::KeyEvent evt3(msg3, false);
    NativeWebKeyboardEvent keyup_event(&evt3);
#else
    NativeWebKeyboardEvent keyup_event(msg3);
#endif
    SendNativeKeyEvent(keyup_event);

    return length;
#elif defined(USE_AURA) && defined(USE_X11)
    // We ignore |layout|, which means we are only testing the layout of the
    // current locale. TODO(mazda): fix this to respect |layout|.
    CHECK(output);
    const int flags = ConvertMockKeyboardModifier(modifiers);

    ui::ScopedXI2Event xevent;
    xevent.InitKeyEvent(ui::ET_KEY_PRESSED,
                        static_cast<ui::KeyboardCode>(key_code),
                        flags);
    ui::KeyEvent event1(xevent, false);
    NativeWebKeyboardEvent keydown_event(&event1);
    SendNativeKeyEvent(keydown_event);

    xevent.InitKeyEvent(ui::ET_KEY_PRESSED,
                        static_cast<ui::KeyboardCode>(key_code),
                        flags);
    ui::KeyEvent event2(xevent, true);
    NativeWebKeyboardEvent char_event(&event2);
    SendNativeKeyEvent(char_event);

    xevent.InitKeyEvent(ui::ET_KEY_RELEASED,
                        static_cast<ui::KeyboardCode>(key_code),
                        flags);
    ui::KeyEvent event3(xevent, false);
    NativeWebKeyboardEvent keyup_event(&event3);
    SendNativeKeyEvent(keyup_event);

    long c = GetCharacterFromKeyCode(static_cast<ui::KeyboardCode>(key_code),
                                     flags);
    output->assign(1, static_cast<char16>(c));
    return 1;
#elif defined(USE_OZONE)
    const int flags = ConvertMockKeyboardModifier(modifiers);

    // Ozone's native events are ui::Events. So first create the "native" event,
    // then create the actual ui::KeyEvent with the native event.
    ui::KeyEvent keydown_native_event(ui::ET_KEY_PRESSED,
                                   static_cast<ui::KeyboardCode>(key_code),
                                   flags,
                                   true);
    ui::KeyEvent keydown_event(&keydown_native_event, false);
    NativeWebKeyboardEvent keydown_web_event(&keydown_event);
    SendNativeKeyEvent(keydown_web_event);

    ui::KeyEvent char_native_event(ui::ET_KEY_PRESSED,
                                   static_cast<ui::KeyboardCode>(key_code),
                                   flags,
                                   true);
    ui::KeyEvent char_event(&char_native_event, true);
    NativeWebKeyboardEvent char_web_event(&char_event);
    SendNativeKeyEvent(char_web_event);

    ui::KeyEvent keyup_native_event(ui::ET_KEY_RELEASED,
                                    static_cast<ui::KeyboardCode>(key_code),
                                    flags,
                                    true);
    ui::KeyEvent keyup_event(&keyup_native_event, false);
    NativeWebKeyboardEvent keyup_web_event(&keyup_event);
    SendNativeKeyEvent(keyup_web_event);

    long c = GetCharacterFromKeyCode(static_cast<ui::KeyboardCode>(key_code),
                                     flags);
    output->assign(1, static_cast<char16>(c));
    return 1;
#elif defined(TOOLKIT_GTK)
    // We ignore |layout|, which means we are only testing the layout of the
    // current locale. TODO(estade): fix this to respect |layout|.
    std::vector<GdkEvent*> events;
    ui::SynthesizeKeyPressEvents(
        NULL, static_cast<ui::KeyboardCode>(key_code),
        modifiers & (MockKeyboard::LEFT_CONTROL | MockKeyboard::RIGHT_CONTROL),
        modifiers & (MockKeyboard::LEFT_SHIFT | MockKeyboard::RIGHT_SHIFT),
        modifiers & (MockKeyboard::LEFT_ALT | MockKeyboard::RIGHT_ALT),
        &events);

    guint32 unicode_key = 0;
    for (size_t i = 0; i < events.size(); ++i) {
      // Only send the up/down events for key press itself (skip the up/down
      // events for the modifier keys).
      if ((i + 1) == (events.size() / 2) || i == (events.size() / 2)) {
        unicode_key = gdk_keyval_to_unicode(events[i]->key.keyval);
        NativeWebKeyboardEvent webkit_event(events[i]);
        SendNativeKeyEvent(webkit_event);

        // Need to add a char event after the key down.
        if (webkit_event.type == blink::WebInputEvent::RawKeyDown) {
          NativeWebKeyboardEvent char_event = webkit_event;
          char_event.type = blink::WebInputEvent::Char;
          char_event.skip_in_browser = true;
          SendNativeKeyEvent(char_event);
        }
      }
      gdk_event_free(events[i]);
    }

    output->assign(1, static_cast<char16>(unicode_key));
    return 1;
#else
    NOTIMPLEMENTED();
    return L'\0';
#endif
  }

 private:
  scoped_ptr<MockKeyboard> mock_keyboard_;
};

// Test that we get form state change notifications when input fields change.
TEST_F(RenderViewImplTest, DISABLED_OnNavStateChanged) {
  // Don't want any delay for form state sync changes. This will still post a
  // message so updates will get coalesced, but as soon as we spin the message
  // loop, it will generate an update.
  view()->set_send_content_state_immediately(true);

  LoadHTML("<input type=\"text\" id=\"elt_text\"></input>");

  // We should NOT have gotten a form state change notification yet.
  EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
      ViewHostMsg_UpdateState::ID));
  render_thread_->sink().ClearMessages();

  // Change the value of the input. We should have gotten an update state
  // notification. We need to spin the message loop to catch this update.
  ExecuteJavaScript("document.getElementById('elt_text').value = 'foo';");
  ProcessPendingMessages();
  EXPECT_TRUE(render_thread_->sink().GetUniqueMessageMatching(
      ViewHostMsg_UpdateState::ID));
}

TEST_F(RenderViewImplTest, OnNavigationHttpPost) {
  ViewMsg_Navigate_Params nav_params;

  // An http url will trigger a resource load so cannot be used here.
  nav_params.url = GURL("data:text/html,<div>Page</div>");
  nav_params.navigation_type = ViewMsg_Navigate_Type::NORMAL;
  nav_params.transition = PAGE_TRANSITION_TYPED;
  nav_params.page_id = -1;
  nav_params.is_post = true;

  // Set up post data.
  const unsigned char* raw_data = reinterpret_cast<const unsigned char*>(
      "post \0\ndata");
  const unsigned int length = 11;
  const std::vector<unsigned char> post_data(raw_data, raw_data + length);
  nav_params.browser_initiated_post_data = post_data;

  view()->OnNavigate(nav_params);
  ProcessPendingMessages();

  const IPC::Message* frame_navigate_msg =
      render_thread_->sink().GetUniqueMessageMatching(
          ViewHostMsg_FrameNavigate::ID);
  EXPECT_TRUE(frame_navigate_msg);

  ViewHostMsg_FrameNavigate::Param host_nav_params;
  ViewHostMsg_FrameNavigate::Read(frame_navigate_msg, &host_nav_params);
  EXPECT_TRUE(host_nav_params.a.is_post);

  // Check post data sent to browser matches
  EXPECT_TRUE(host_nav_params.a.page_state.IsValid());
  const blink::WebHistoryItem item = PageStateToHistoryItem(
      host_nav_params.a.page_state);
  blink::WebHTTPBody body = item.httpBody();
  blink::WebHTTPBody::Element element;
  bool successful = body.elementAt(0, element);
  EXPECT_TRUE(successful);
  EXPECT_EQ(blink::WebHTTPBody::Element::TypeData, element.type);
  EXPECT_EQ(length, element.data.size());
  EXPECT_EQ(0, memcmp(raw_data, element.data.data(), length));
}

TEST_F(RenderViewImplTest, DecideNavigationPolicy) {
  WebUITestWebUIControllerFactory factory;
  WebUIControllerFactory::RegisterFactory(&factory);

  DocumentState state;
  state.set_navigation_state(NavigationState::CreateContentInitiated());

  // Navigations to normal HTTP URLs can be handled locally.
  blink::WebURLRequest request(GURL("http://foo.com"));
  blink::WebNavigationPolicy policy = view()->decidePolicyForNavigation(
      GetMainFrame(),
      &state,
      request,
      blink::WebNavigationTypeLinkClicked,
      blink::WebNavigationPolicyCurrentTab,
      false);
  EXPECT_EQ(blink::WebNavigationPolicyCurrentTab, policy);

  // Verify that form posts to WebUI URLs will be sent to the browser process.
  blink::WebURLRequest form_request(GURL("chrome://foo"));
  form_request.setHTTPMethod("POST");
  policy = view()->decidePolicyForNavigation(
      GetMainFrame(),
      &state,
      form_request,
      blink::WebNavigationTypeFormSubmitted,
      blink::WebNavigationPolicyCurrentTab,
      false);
  EXPECT_EQ(blink::WebNavigationPolicyIgnore, policy);

  // Verify that popup links to WebUI URLs also are sent to browser.
  blink::WebURLRequest popup_request(GURL("chrome://foo"));
  policy = view()->decidePolicyForNavigation(
      GetMainFrame(),
      &state,
      popup_request,
      blink::WebNavigationTypeLinkClicked,
      blink::WebNavigationPolicyNewForegroundTab,
      false);
  EXPECT_EQ(blink::WebNavigationPolicyIgnore, policy);
}

TEST_F(RenderViewImplTest, DecideNavigationPolicyHandlesAllTopLevel) {
  DocumentState state;
  state.set_navigation_state(NavigationState::CreateContentInitiated());

  RendererPreferences prefs = view()->renderer_preferences();
  prefs.browser_handles_all_top_level_requests = true;
  view()->OnSetRendererPrefs(prefs);

  const blink::WebNavigationType kNavTypes[] = {
    blink::WebNavigationTypeLinkClicked,
    blink::WebNavigationTypeFormSubmitted,
    blink::WebNavigationTypeBackForward,
    blink::WebNavigationTypeReload,
    blink::WebNavigationTypeFormResubmitted,
    blink::WebNavigationTypeOther,
  };

  blink::WebURLRequest request(GURL("http://foo.com"));
  for (size_t i = 0; i < arraysize(kNavTypes); ++i) {
    blink::WebNavigationPolicy policy = view()->decidePolicyForNavigation(
        GetMainFrame(),
        &state,
        request,
        kNavTypes[i],
        blink::WebNavigationPolicyCurrentTab,
        false);
    EXPECT_EQ(blink::WebNavigationPolicyIgnore, policy);
  }
}

TEST_F(RenderViewImplTest, DecideNavigationPolicyForWebUI) {
  // Enable bindings to simulate a WebUI view.
  view()->OnAllowBindings(BINDINGS_POLICY_WEB_UI);

  DocumentState state;
  state.set_navigation_state(NavigationState::CreateContentInitiated());

  // Navigations to normal HTTP URLs will be sent to browser process.
  blink::WebURLRequest request(GURL("http://foo.com"));
  blink::WebNavigationPolicy policy = view()->decidePolicyForNavigation(
      GetMainFrame(),
      &state,
      request,
      blink::WebNavigationTypeLinkClicked,
      blink::WebNavigationPolicyCurrentTab,
      false);
  EXPECT_EQ(blink::WebNavigationPolicyIgnore, policy);

  // Navigations to WebUI URLs will also be sent to browser process.
  blink::WebURLRequest webui_request(GURL("chrome://foo"));
  policy = view()->decidePolicyForNavigation(
      GetMainFrame(),
      &state,
      webui_request,
      blink::WebNavigationTypeLinkClicked,
      blink::WebNavigationPolicyCurrentTab,
      false);
  EXPECT_EQ(blink::WebNavigationPolicyIgnore, policy);

  // Verify that form posts to data URLs will be sent to the browser process.
  blink::WebURLRequest data_request(GURL("data:text/html,foo"));
  data_request.setHTTPMethod("POST");
  policy = view()->decidePolicyForNavigation(
      GetMainFrame(),
      &state,
      data_request,
      blink::WebNavigationTypeFormSubmitted,
      blink::WebNavigationPolicyCurrentTab,
      false);
  EXPECT_EQ(blink::WebNavigationPolicyIgnore, policy);

  // Verify that a popup that creates a view first and then navigates to a
  // normal HTTP URL will be sent to the browser process, even though the
  // new view does not have any enabled_bindings_.
  blink::WebURLRequest popup_request(GURL("http://foo.com"));
  blink::WebView* new_web_view = view()->createView(
      GetMainFrame(), popup_request, blink::WebWindowFeatures(), "foo",
      blink::WebNavigationPolicyNewForegroundTab, false);
  RenderViewImpl* new_view = RenderViewImpl::FromWebView(new_web_view);
  policy = new_view->decidePolicyForNavigation(
      new_web_view->mainFrame(),
      &state,
      popup_request,
      blink::WebNavigationTypeLinkClicked,
      blink::WebNavigationPolicyNewForegroundTab,
      false);
  EXPECT_EQ(blink::WebNavigationPolicyIgnore, policy);

  // Clean up after the new view so we don't leak it.
  new_view->Close();
  new_view->Release();
}

// Ensure the RenderViewImpl sends an ACK to a SwapOut request, even if it is
// already swapped out.  http://crbug.com/93427.
TEST_F(RenderViewImplTest, SendSwapOutACK) {
  LoadHTML("<div>Page A</div>");
  int initial_page_id = view()->GetPageId();

  // Respond to a swap out request.
  view()->OnSwapOut();

  // Ensure the swap out commits synchronously.
  EXPECT_NE(initial_page_id, view()->GetPageId());

  // Check for a valid OnSwapOutACK.
  const IPC::Message* msg = render_thread_->sink().GetUniqueMessageMatching(
      ViewHostMsg_SwapOut_ACK::ID);
  ASSERT_TRUE(msg);

  // It is possible to get another swap out request.  Ensure that we send
  // an ACK, even if we don't have to do anything else.
  render_thread_->sink().ClearMessages();
  view()->OnSwapOut();
  const IPC::Message* msg2 = render_thread_->sink().GetUniqueMessageMatching(
      ViewHostMsg_SwapOut_ACK::ID);
  ASSERT_TRUE(msg2);

  // If we navigate back to this RenderView, ensure we don't send a state
  // update for the swapped out URL.  (http://crbug.com/72235)
  ViewMsg_Navigate_Params nav_params;
  nav_params.url = GURL("data:text/html,<div>Page B</div>");
  nav_params.navigation_type = ViewMsg_Navigate_Type::NORMAL;
  nav_params.transition = PAGE_TRANSITION_TYPED;
  nav_params.current_history_list_length = 1;
  nav_params.current_history_list_offset = 0;
  nav_params.pending_history_list_offset = 1;
  nav_params.page_id = -1;
  view()->OnNavigate(nav_params);
  ProcessPendingMessages();
  const IPC::Message* msg3 = render_thread_->sink().GetUniqueMessageMatching(
      ViewHostMsg_UpdateState::ID);
  EXPECT_FALSE(msg3);
}

// Ensure the RenderViewImpl reloads the previous page if a reload request
// arrives while it is showing swappedout://.  http://crbug.com/143155.
TEST_F(RenderViewImplTest, ReloadWhileSwappedOut) {
  // Load page A.
  LoadHTML("<div>Page A</div>");

  // Load page B, which will trigger an UpdateState message for page A.
  LoadHTML("<div>Page B</div>");

  // Check for a valid UpdateState message for page A.
  ProcessPendingMessages();
  const IPC::Message* msg_A = render_thread_->sink().GetUniqueMessageMatching(
      ViewHostMsg_UpdateState::ID);
  ASSERT_TRUE(msg_A);
  int page_id_A;
  PageState state_A;
  ViewHostMsg_UpdateState::Read(msg_A, &page_id_A, &state_A);
  EXPECT_EQ(1, page_id_A);
  render_thread_->sink().ClearMessages();

  // Back to page A (page_id 1) and commit.
  ViewMsg_Navigate_Params params_A;
  params_A.navigation_type = ViewMsg_Navigate_Type::NORMAL;
  params_A.transition = PAGE_TRANSITION_FORWARD_BACK;
  params_A.current_history_list_length = 2;
  params_A.current_history_list_offset = 1;
  params_A.pending_history_list_offset = 0;
  params_A.page_id = 1;
  params_A.page_state = state_A;
  view()->OnNavigate(params_A);
  ProcessPendingMessages();

  // Respond to a swap out request.
  view()->OnSwapOut();

  // Check for a OnSwapOutACK.
  const IPC::Message* msg = render_thread_->sink().GetUniqueMessageMatching(
      ViewHostMsg_SwapOut_ACK::ID);
  ASSERT_TRUE(msg);
  render_thread_->sink().ClearMessages();

  // It is possible to get a reload request at this point, containing the
  // params.page_state of the initial page (e.g., if the new page fails the
  // provisional load in the renderer process, after we unload the old page).
  // Ensure the old page gets reloaded, not swappedout://.
  ViewMsg_Navigate_Params nav_params;
  nav_params.url = GURL("data:text/html,<div>Page A</div>");
  nav_params.navigation_type = ViewMsg_Navigate_Type::RELOAD;
  nav_params.transition = PAGE_TRANSITION_RELOAD;
  nav_params.current_history_list_length = 2;
  nav_params.current_history_list_offset = 0;
  nav_params.pending_history_list_offset = 0;
  nav_params.page_id = 1;
  nav_params.page_state = state_A;
  view()->OnNavigate(nav_params);
  ProcessPendingMessages();

  // Verify page A committed, not swappedout://.
  const IPC::Message* frame_navigate_msg =
      render_thread_->sink().GetUniqueMessageMatching(
          ViewHostMsg_FrameNavigate::ID);
  EXPECT_TRUE(frame_navigate_msg);

  // Read URL out of the parent trait of the params object.
  ViewHostMsg_FrameNavigate::Param commit_params;
  ViewHostMsg_FrameNavigate::Read(frame_navigate_msg, &commit_params);
  EXPECT_NE(GURL("swappedout://"), commit_params.a.url);
}


// Test that we get the correct UpdateState message when we go back twice
// quickly without committing.  Regression test for http://crbug.com/58082.
// Disabled: http://crbug.com/157357 .
TEST_F(RenderViewImplTest,  DISABLED_LastCommittedUpdateState) {
  // Load page A.
  LoadHTML("<div>Page A</div>");

  // Load page B, which will trigger an UpdateState message for page A.
  LoadHTML("<div>Page B</div>");

  // Check for a valid UpdateState message for page A.
  ProcessPendingMessages();
  const IPC::Message* msg_A = render_thread_->sink().GetUniqueMessageMatching(
      ViewHostMsg_UpdateState::ID);
  ASSERT_TRUE(msg_A);
  int page_id_A;
  PageState state_A;
  ViewHostMsg_UpdateState::Read(msg_A, &page_id_A, &state_A);
  EXPECT_EQ(1, page_id_A);
  render_thread_->sink().ClearMessages();

  // Load page C, which will trigger an UpdateState message for page B.
  LoadHTML("<div>Page C</div>");

  // Check for a valid UpdateState for page B.
  ProcessPendingMessages();
  const IPC::Message* msg_B = render_thread_->sink().GetUniqueMessageMatching(
      ViewHostMsg_UpdateState::ID);
  ASSERT_TRUE(msg_B);
  int page_id_B;
  PageState state_B;
  ViewHostMsg_UpdateState::Read(msg_B, &page_id_B, &state_B);
  EXPECT_EQ(2, page_id_B);
  EXPECT_NE(state_A, state_B);
  render_thread_->sink().ClearMessages();

  // Load page D, which will trigger an UpdateState message for page C.
  LoadHTML("<div>Page D</div>");

  // Check for a valid UpdateState for page C.
  ProcessPendingMessages();
  const IPC::Message* msg_C = render_thread_->sink().GetUniqueMessageMatching(
      ViewHostMsg_UpdateState::ID);
  ASSERT_TRUE(msg_C);
  int page_id_C;
  PageState state_C;
  ViewHostMsg_UpdateState::Read(msg_C, &page_id_C, &state_C);
  EXPECT_EQ(3, page_id_C);
  EXPECT_NE(state_B, state_C);
  render_thread_->sink().ClearMessages();

  // Go back to C and commit, preparing for our real test.
  ViewMsg_Navigate_Params params_C;
  params_C.navigation_type = ViewMsg_Navigate_Type::NORMAL;
  params_C.transition = PAGE_TRANSITION_FORWARD_BACK;
  params_C.current_history_list_length = 4;
  params_C.current_history_list_offset = 3;
  params_C.pending_history_list_offset = 2;
  params_C.page_id = 3;
  params_C.page_state = state_C;
  view()->OnNavigate(params_C);
  ProcessPendingMessages();
  render_thread_->sink().ClearMessages();

  // Go back twice quickly, such that page B does not have a chance to commit.
  // This leads to two changes to the back/forward list but only one change to
  // the RenderView's page ID.

  // Back to page B (page_id 2), without committing.
  ViewMsg_Navigate_Params params_B;
  params_B.navigation_type = ViewMsg_Navigate_Type::NORMAL;
  params_B.transition = PAGE_TRANSITION_FORWARD_BACK;
  params_B.current_history_list_length = 4;
  params_B.current_history_list_offset = 2;
  params_B.pending_history_list_offset = 1;
  params_B.page_id = 2;
  params_B.page_state = state_B;
  view()->OnNavigate(params_B);

  // Back to page A (page_id 1) and commit.
  ViewMsg_Navigate_Params params;
  params.navigation_type = ViewMsg_Navigate_Type::NORMAL;
  params.transition = PAGE_TRANSITION_FORWARD_BACK;
  params_B.current_history_list_length = 4;
  params_B.current_history_list_offset = 2;
  params_B.pending_history_list_offset = 0;
  params.page_id = 1;
  params.page_state = state_A;
  view()->OnNavigate(params);
  ProcessPendingMessages();

  // Now ensure that the UpdateState message we receive is consistent
  // and represents page C in both page_id and state.
  const IPC::Message* msg = render_thread_->sink().GetUniqueMessageMatching(
      ViewHostMsg_UpdateState::ID);
  ASSERT_TRUE(msg);
  int page_id;
  PageState state;
  ViewHostMsg_UpdateState::Read(msg, &page_id, &state);
  EXPECT_EQ(page_id_C, page_id);
  EXPECT_NE(state_A, state);
  EXPECT_NE(state_B, state);
  EXPECT_EQ(state_C, state);
}

// Test that the history_page_ids_ list can reveal when a stale back/forward
// navigation arrives from the browser and can be ignored.  See
// http://crbug.com/86758.
TEST_F(RenderViewImplTest, StaleNavigationsIgnored) {
  // Load page A.
  LoadHTML("<div>Page A</div>");
  EXPECT_EQ(1, view()->history_list_length_);
  EXPECT_EQ(0, view()->history_list_offset_);
  EXPECT_EQ(1, view()->history_page_ids_[0]);

  // Load page B, which will trigger an UpdateState message for page A.
  LoadHTML("<div>Page B</div>");
  EXPECT_EQ(2, view()->history_list_length_);
  EXPECT_EQ(1, view()->history_list_offset_);
  EXPECT_EQ(2, view()->history_page_ids_[1]);

  // Check for a valid UpdateState message for page A.
  ProcessPendingMessages();
  const IPC::Message* msg_A = render_thread_->sink().GetUniqueMessageMatching(
      ViewHostMsg_UpdateState::ID);
  ASSERT_TRUE(msg_A);
  int page_id_A;
  PageState state_A;
  ViewHostMsg_UpdateState::Read(msg_A, &page_id_A, &state_A);
  EXPECT_EQ(1, page_id_A);
  render_thread_->sink().ClearMessages();

  // Back to page A (page_id 1) and commit.
  ViewMsg_Navigate_Params params_A;
  params_A.navigation_type = ViewMsg_Navigate_Type::NORMAL;
  params_A.transition = PAGE_TRANSITION_FORWARD_BACK;
  params_A.current_history_list_length = 2;
  params_A.current_history_list_offset = 1;
  params_A.pending_history_list_offset = 0;
  params_A.page_id = 1;
  params_A.page_state = state_A;
  view()->OnNavigate(params_A);
  ProcessPendingMessages();

  // A new navigation commits, clearing the forward history.
  LoadHTML("<div>Page C</div>");
  EXPECT_EQ(2, view()->history_list_length_);
  EXPECT_EQ(1, view()->history_list_offset_);
  EXPECT_EQ(3, view()->history_page_ids_[1]);

  // The browser then sends a stale navigation to B, which should be ignored.
  ViewMsg_Navigate_Params params_B;
  params_B.navigation_type = ViewMsg_Navigate_Type::NORMAL;
  params_B.transition = PAGE_TRANSITION_FORWARD_BACK;
  params_B.current_history_list_length = 2;
  params_B.current_history_list_offset = 0;
  params_B.pending_history_list_offset = 1;
  params_B.page_id = 2;
  params_B.page_state = state_A;  // Doesn't matter, just has to be present.
  view()->OnNavigate(params_B);

  // State should be unchanged.
  EXPECT_EQ(2, view()->history_list_length_);
  EXPECT_EQ(1, view()->history_list_offset_);
  EXPECT_EQ(3, view()->history_page_ids_[1]);
}

// Test that we do not ignore navigations after the entry limit is reached,
// in which case the browser starts dropping entries from the front.  In this
// case, we'll see a page_id mismatch but the RenderView's id will be older,
// not newer, than params.page_id.  Use this as a cue that we should update the
// state and not treat it like a navigation to a cropped forward history item.
// See http://crbug.com/89798.
TEST_F(RenderViewImplTest, DontIgnoreBackAfterNavEntryLimit) {
  // Load page A.
  LoadHTML("<div>Page A</div>");
  EXPECT_EQ(1, view()->history_list_length_);
  EXPECT_EQ(0, view()->history_list_offset_);
  EXPECT_EQ(1, view()->history_page_ids_[0]);

  // Load page B, which will trigger an UpdateState message for page A.
  LoadHTML("<div>Page B</div>");
  EXPECT_EQ(2, view()->history_list_length_);
  EXPECT_EQ(1, view()->history_list_offset_);
  EXPECT_EQ(2, view()->history_page_ids_[1]);

  // Check for a valid UpdateState message for page A.
  ProcessPendingMessages();
  const IPC::Message* msg_A = render_thread_->sink().GetUniqueMessageMatching(
      ViewHostMsg_UpdateState::ID);
  ASSERT_TRUE(msg_A);
  int page_id_A;
  PageState state_A;
  ViewHostMsg_UpdateState::Read(msg_A, &page_id_A, &state_A);
  EXPECT_EQ(1, page_id_A);
  render_thread_->sink().ClearMessages();

  // Load page C, which will trigger an UpdateState message for page B.
  LoadHTML("<div>Page C</div>");
  EXPECT_EQ(3, view()->history_list_length_);
  EXPECT_EQ(2, view()->history_list_offset_);
  EXPECT_EQ(3, view()->history_page_ids_[2]);

  // Check for a valid UpdateState message for page B.
  ProcessPendingMessages();
  const IPC::Message* msg_B = render_thread_->sink().GetUniqueMessageMatching(
      ViewHostMsg_UpdateState::ID);
  ASSERT_TRUE(msg_B);
  int page_id_B;
  PageState state_B;
  ViewHostMsg_UpdateState::Read(msg_B, &page_id_B, &state_B);
  EXPECT_EQ(2, page_id_B);
  render_thread_->sink().ClearMessages();

  // Suppose the browser has limited the number of NavigationEntries to 2.
  // It has now dropped the first entry, but the renderer isn't notified.
  // Ensure that going back to page B (page_id 2) at offset 0 is successful.
  ViewMsg_Navigate_Params params_B;
  params_B.navigation_type = ViewMsg_Navigate_Type::NORMAL;
  params_B.transition = PAGE_TRANSITION_FORWARD_BACK;
  params_B.current_history_list_length = 2;
  params_B.current_history_list_offset = 1;
  params_B.pending_history_list_offset = 0;
  params_B.page_id = 2;
  params_B.page_state = state_B;
  view()->OnNavigate(params_B);
  ProcessPendingMessages();

  EXPECT_EQ(2, view()->history_list_length_);
  EXPECT_EQ(0, view()->history_list_offset_);
  EXPECT_EQ(2, view()->history_page_ids_[0]);
}

// Test that our IME backend sends a notification message when the input focus
// changes.
TEST_F(RenderViewImplTest, OnImeTypeChanged) {
  // Enable our IME backend code.
  view()->OnSetInputMethodActive(true);

  // Load an HTML page consisting of two input fields.
  view()->set_send_content_state_immediately(true);
  LoadHTML("<html>"
           "<head>"
           "</head>"
           "<body>"
           "<input id=\"test1\" type=\"text\" value=\"some text\"></input>"
           "<input id=\"test2\" type=\"password\"></input>"
           "<input id=\"test3\" type=\"text\" inputmode=\"verbatim\"></input>"
           "<input id=\"test4\" type=\"text\" inputmode=\"latin\"></input>"
           "<input id=\"test5\" type=\"text\" inputmode=\"latin-name\"></input>"
           "<input id=\"test6\" type=\"text\" inputmode=\"latin-prose\">"
               "</input>"
           "<input id=\"test7\" type=\"text\" inputmode=\"full-width-latin\">"
               "</input>"
           "<input id=\"test8\" type=\"text\" inputmode=\"kana\"></input>"
           "<input id=\"test9\" type=\"text\" inputmode=\"katakana\"></input>"
           "<input id=\"test10\" type=\"text\" inputmode=\"numeric\"></input>"
           "<input id=\"test11\" type=\"text\" inputmode=\"tel\"></input>"
           "<input id=\"test12\" type=\"text\" inputmode=\"email\"></input>"
           "<input id=\"test13\" type=\"text\" inputmode=\"url\"></input>"
           "<input id=\"test14\" type=\"text\" inputmode=\"unknown\"></input>"
           "<input id=\"test15\" type=\"text\" inputmode=\"verbatim\"></input>"
           "</body>"
           "</html>");
  render_thread_->sink().ClearMessages();

  struct InputModeTestCase {
    const char* input_id;
    ui::TextInputMode expected_mode;
  };
  static const InputModeTestCase kInputModeTestCases[] = {
     {"test1", ui::TEXT_INPUT_MODE_DEFAULT},
     {"test3", ui::TEXT_INPUT_MODE_VERBATIM},
     {"test4", ui::TEXT_INPUT_MODE_LATIN},
     {"test5", ui::TEXT_INPUT_MODE_LATIN_NAME},
     {"test6", ui::TEXT_INPUT_MODE_LATIN_PROSE},
     {"test7", ui::TEXT_INPUT_MODE_FULL_WIDTH_LATIN},
     {"test8", ui::TEXT_INPUT_MODE_KANA},
     {"test9", ui::TEXT_INPUT_MODE_KATAKANA},
     {"test10", ui::TEXT_INPUT_MODE_NUMERIC},
     {"test11", ui::TEXT_INPUT_MODE_TEL},
     {"test12", ui::TEXT_INPUT_MODE_EMAIL},
     {"test13", ui::TEXT_INPUT_MODE_URL},
     {"test14", ui::TEXT_INPUT_MODE_DEFAULT},
     {"test15", ui::TEXT_INPUT_MODE_VERBATIM},
  };

  const int kRepeatCount = 10;
  for (int i = 0; i < kRepeatCount; i++) {
    // Move the input focus to the first <input> element, where we should
    // activate IMEs.
    ExecuteJavaScript("document.getElementById('test1').focus();");
    ProcessPendingMessages();
    render_thread_->sink().ClearMessages();

    // Update the IME status and verify if our IME backend sends an IPC message
    // to activate IMEs.
    view()->UpdateTextInputType();
    const IPC::Message* msg = render_thread_->sink().GetMessageAt(0);
    EXPECT_TRUE(msg != NULL);
    EXPECT_EQ(ViewHostMsg_TextInputTypeChanged::ID, msg->type());
    ui::TextInputType type;
    bool can_compose_inline = false;
    ui::TextInputMode input_mode = ui::TEXT_INPUT_MODE_DEFAULT;
    ViewHostMsg_TextInputTypeChanged::Read(msg,
                                           &type,
                                           &input_mode,
                                           &can_compose_inline);
    EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT, type);
    EXPECT_EQ(true, can_compose_inline);

    // Move the input focus to the second <input> element, where we should
    // de-activate IMEs.
    ExecuteJavaScript("document.getElementById('test2').focus();");
    ProcessPendingMessages();
    render_thread_->sink().ClearMessages();

    // Update the IME status and verify if our IME backend sends an IPC message
    // to de-activate IMEs.
    view()->UpdateTextInputType();
    msg = render_thread_->sink().GetMessageAt(0);
    EXPECT_TRUE(msg != NULL);
    EXPECT_EQ(ViewHostMsg_TextInputTypeChanged::ID, msg->type());
    ViewHostMsg_TextInputTypeChanged::Read(msg,
                                           &type,
                                           &input_mode,
                                           &can_compose_inline);
    EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD, type);

    for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kInputModeTestCases); i++) {
      const InputModeTestCase* test_case = &kInputModeTestCases[i];
      std::string javascript =
          base::StringPrintf("document.getElementById('%s').focus();",
                             test_case->input_id);
      // Move the input focus to the target <input> element, where we should
      // activate IMEs.
      ExecuteJavaScriptAndReturnIntValue(ASCIIToUTF16(javascript), NULL);
      ProcessPendingMessages();
      render_thread_->sink().ClearMessages();

      // Update the IME status and verify if our IME backend sends an IPC
      // message to activate IMEs.
      view()->UpdateTextInputType();
      const IPC::Message* msg = render_thread_->sink().GetMessageAt(0);
      EXPECT_TRUE(msg != NULL);
      EXPECT_EQ(ViewHostMsg_TextInputTypeChanged::ID, msg->type());
      ViewHostMsg_TextInputTypeChanged::Read(msg,
                                            &type,
                                            &input_mode,
                                            &can_compose_inline);
      EXPECT_EQ(test_case->expected_mode, input_mode);
    }
  }
}

// Test that our IME backend can compose CJK words.
// Our IME front-end sends many platform-independent messages to the IME backend
// while it composes CJK words. This test sends the minimal messages captured
// on my local environment directly to the IME backend to verify if the backend
// can compose CJK words without any problems.
// This test uses an array of command sets because an IME composotion does not
// only depends on IME events, but also depends on window events, e.g. moving
// the window focus while composing a CJK text. To handle such complicated
// cases, this test should not only call IME-related functions in the
// RenderWidget class, but also call some RenderWidget members, e.g.
// ExecuteJavaScript(), RenderWidget::OnSetFocus(), etc.
TEST_F(RenderViewImplTest, ImeComposition) {
  enum ImeCommand {
    IME_INITIALIZE,
    IME_SETINPUTMODE,
    IME_SETFOCUS,
    IME_SETCOMPOSITION,
    IME_CONFIRMCOMPOSITION,
    IME_CANCELCOMPOSITION
  };
  struct ImeMessage {
    ImeCommand command;
    bool enable;
    int selection_start;
    int selection_end;
    const wchar_t* ime_string;
    const wchar_t* result;
  };
  static const ImeMessage kImeMessages[] = {
    // Scenario 1: input a Chinese word with Microsoft IME (on Vista).
    {IME_INITIALIZE, true, 0, 0, NULL, NULL},
    {IME_SETINPUTMODE, true, 0, 0, NULL, NULL},
    {IME_SETFOCUS, true, 0, 0, NULL, NULL},
    {IME_SETCOMPOSITION, false, 1, 1, L"n", L"n"},
    {IME_SETCOMPOSITION, false, 2, 2, L"ni", L"ni"},
    {IME_SETCOMPOSITION, false, 3, 3, L"nih", L"nih"},
    {IME_SETCOMPOSITION, false, 4, 4, L"niha", L"niha"},
    {IME_SETCOMPOSITION, false, 5, 5, L"nihao", L"nihao"},
    {IME_CONFIRMCOMPOSITION, false, -1, -1, L"\x4F60\x597D", L"\x4F60\x597D"},
    // Scenario 2: input a Japanese word with Microsoft IME (on Vista).
    {IME_INITIALIZE, true, 0, 0, NULL, NULL},
    {IME_SETINPUTMODE, true, 0, 0, NULL, NULL},
    {IME_SETFOCUS, true, 0, 0, NULL, NULL},
    {IME_SETCOMPOSITION, false, 0, 1, L"\xFF4B", L"\xFF4B"},
    {IME_SETCOMPOSITION, false, 0, 1, L"\x304B", L"\x304B"},
    {IME_SETCOMPOSITION, false, 0, 2, L"\x304B\xFF4E", L"\x304B\xFF4E"},
    {IME_SETCOMPOSITION, false, 0, 3, L"\x304B\x3093\xFF4A",
     L"\x304B\x3093\xFF4A"},
    {IME_SETCOMPOSITION, false, 0, 3, L"\x304B\x3093\x3058",
     L"\x304B\x3093\x3058"},
    {IME_SETCOMPOSITION, false, 0, 2, L"\x611F\x3058", L"\x611F\x3058"},
    {IME_SETCOMPOSITION, false, 0, 2, L"\x6F22\x5B57", L"\x6F22\x5B57"},
    {IME_CONFIRMCOMPOSITION, false, -1, -1, L"", L"\x6F22\x5B57"},
    {IME_CANCELCOMPOSITION, false, -1, -1, L"", L"\x6F22\x5B57"},
    // Scenario 3: input a Korean word with Microsot IME (on Vista).
    {IME_INITIALIZE, true, 0, 0, NULL, NULL},
    {IME_SETINPUTMODE, true, 0, 0, NULL, NULL},
    {IME_SETFOCUS, true, 0, 0, NULL, NULL},
    {IME_SETCOMPOSITION, false, 0, 1, L"\x3147", L"\x3147"},
    {IME_SETCOMPOSITION, false, 0, 1, L"\xC544", L"\xC544"},
    {IME_SETCOMPOSITION, false, 0, 1, L"\xC548", L"\xC548"},
    {IME_CONFIRMCOMPOSITION, false, -1, -1, L"", L"\xC548"},
    {IME_SETCOMPOSITION, false, 0, 1, L"\x3134", L"\xC548\x3134"},
    {IME_SETCOMPOSITION, false, 0, 1, L"\xB140", L"\xC548\xB140"},
    {IME_SETCOMPOSITION, false, 0, 1, L"\xB155", L"\xC548\xB155"},
    {IME_CANCELCOMPOSITION, false, -1, -1, L"", L"\xC548"},
    {IME_SETCOMPOSITION, false, 0, 1, L"\xB155", L"\xC548\xB155"},
    {IME_CONFIRMCOMPOSITION, false, -1, -1, L"", L"\xC548\xB155"},
  };

  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kImeMessages); i++) {
    const ImeMessage* ime_message = &kImeMessages[i];
    switch (ime_message->command) {
      case IME_INITIALIZE:
        // Load an HTML page consisting of a content-editable <div> element,
        // and move the input focus to the <div> element, where we can use
        // IMEs.
        view()->OnSetInputMethodActive(ime_message->enable);
        view()->set_send_content_state_immediately(true);
        LoadHTML("<html>"
                "<head>"
                "</head>"
                "<body>"
                "<div id=\"test1\" contenteditable=\"true\"></div>"
                "</body>"
                "</html>");
        ExecuteJavaScript("document.getElementById('test1').focus();");
        break;

      case IME_SETINPUTMODE:
        // Activate (or deactivate) our IME back-end.
        view()->OnSetInputMethodActive(ime_message->enable);
        break;

      case IME_SETFOCUS:
        // Update the window focus.
        view()->OnSetFocus(ime_message->enable);
        break;

      case IME_SETCOMPOSITION:
        view()->OnImeSetComposition(
            WideToUTF16Hack(ime_message->ime_string),
            std::vector<blink::WebCompositionUnderline>(),
            ime_message->selection_start,
            ime_message->selection_end);
        break;

      case IME_CONFIRMCOMPOSITION:
        view()->OnImeConfirmComposition(
            WideToUTF16Hack(ime_message->ime_string),
            gfx::Range::InvalidRange(),
            false);
        break;

      case IME_CANCELCOMPOSITION:
        view()->OnImeSetComposition(
            base::string16(),
            std::vector<blink::WebCompositionUnderline>(),
            0, 0);
        break;
    }

    // Update the status of our IME back-end.
    // TODO(hbono): we should verify messages to be sent from the back-end.
    view()->UpdateTextInputType();
    ProcessPendingMessages();
    render_thread_->sink().ClearMessages();

    if (ime_message->result) {
      // Retrieve the content of this page and compare it with the expected
      // result.
      const int kMaxOutputCharacters = 128;
      std::wstring output = UTF16ToWideHack(
          GetMainFrame()->contentAsText(kMaxOutputCharacters));
      EXPECT_EQ(output, ime_message->result);
    }
  }
}

// Test that the RenderView::OnSetTextDirection() function can change the text
// direction of the selected input element.
TEST_F(RenderViewImplTest, OnSetTextDirection) {
  // Load an HTML page consisting of a <textarea> element and a <div> element.
  // This test changes the text direction of the <textarea> element, and
  // writes the values of its 'dir' attribute and its 'direction' property to
  // verify that the text direction is changed.
  view()->set_send_content_state_immediately(true);
  LoadHTML("<html>"
           "<head>"
           "</head>"
           "<body>"
           "<textarea id=\"test\"></textarea>"
           "<div id=\"result\" contenteditable=\"true\"></div>"
           "</body>"
           "</html>");
  render_thread_->sink().ClearMessages();

  static const struct {
    WebTextDirection direction;
    const wchar_t* expected_result;
  } kTextDirection[] = {
    { blink::WebTextDirectionRightToLeft, L"\x000A" L"rtl,rtl" },
    { blink::WebTextDirectionLeftToRight, L"\x000A" L"ltr,ltr" },
  };
  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTextDirection); ++i) {
    // Set the text direction of the <textarea> element.
    ExecuteJavaScript("document.getElementById('test').focus();");
    view()->OnSetTextDirection(kTextDirection[i].direction);

    // Write the values of its DOM 'dir' attribute and its CSS 'direction'
    // property to the <div> element.
    ExecuteJavaScript("var result = document.getElementById('result');"
                      "var node = document.getElementById('test');"
                      "var style = getComputedStyle(node, null);"
                      "result.innerText ="
                      "    node.getAttribute('dir') + ',' +"
                      "    style.getPropertyValue('direction');");

    // Copy the document content to std::wstring and compare with the
    // expected result.
    const int kMaxOutputCharacters = 16;
    std::wstring output = UTF16ToWideHack(
        GetMainFrame()->contentAsText(kMaxOutputCharacters));
    EXPECT_EQ(output, kTextDirection[i].expected_result);
  }
}

// see http://crbug.com/238750
#if defined(OS_WIN)
#define MAYBE_OnHandleKeyboardEvent DISABLED_OnHandleKeyboardEvent
#else
#define MAYBE_OnHandleKeyboardEvent OnHandleKeyboardEvent
#endif

// Test that we can receive correct DOM events when we send input events
// through the RenderWidget::OnHandleInputEvent() function.
TEST_F(RenderViewImplTest, MAYBE_OnHandleKeyboardEvent) {
#if !defined(OS_MACOSX)
  // Load an HTML page consisting of one <input> element and three
  // contentediable <div> elements.
  // The <input> element is used for sending keyboard events, and the <div>
  // elements are used for writing DOM events in the following format:
  //   "<keyCode>,<shiftKey>,<controlKey>,<altKey>".
  // TODO(hbono): <http://crbug.com/2215> Our WebKit port set |ev.metaKey| to
  // true when pressing an alt key, i.e. the |ev.metaKey| value is not
  // trustworthy. We will check the |ev.metaKey| value when this issue is fixed.
  view()->set_send_content_state_immediately(true);
  LoadHTML("<html>"
           "<head>"
           "<title></title>"
           "<script type='text/javascript' language='javascript'>"
           "function OnKeyEvent(ev) {"
           "  var result = document.getElementById(ev.type);"
           "  result.innerText ="
           "      (ev.which || ev.keyCode) + ',' +"
           "      ev.shiftKey + ',' +"
           "      ev.ctrlKey + ',' +"
           "      ev.altKey;"
           "  return true;"
           "}"
           "</script>"
           "</head>"
           "<body>"
           "<input id='test' type='text'"
           "    onkeydown='return OnKeyEvent(event);'"
           "    onkeypress='return OnKeyEvent(event);'"
           "    onkeyup='return OnKeyEvent(event);'>"
           "</input>"
           "<div id='keydown' contenteditable='true'>"
           "</div>"
           "<div id='keypress' contenteditable='true'>"
           "</div>"
           "<div id='keyup' contenteditable='true'>"
           "</div>"
           "</body>"
           "</html>");
  ExecuteJavaScript("document.getElementById('test').focus();");
  render_thread_->sink().ClearMessages();

  static const MockKeyboard::Layout kLayouts[] = {
#if defined(OS_WIN)
    // Since we ignore the mock keyboard layout on Linux and instead just use
    // the screen's keyboard layout, these trivially pass. They are commented
    // out to avoid the illusion that they work.
    MockKeyboard::LAYOUT_ARABIC,
    MockKeyboard::LAYOUT_CANADIAN_FRENCH,
    MockKeyboard::LAYOUT_FRENCH,
    MockKeyboard::LAYOUT_HEBREW,
    MockKeyboard::LAYOUT_RUSSIAN,
#endif
    MockKeyboard::LAYOUT_UNITED_STATES,
  };

  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kLayouts); ++i) {
    // For each key code, we send three keyboard events.
    //  * we press only the key;
    //  * we press the key and a left-shift key, and;
    //  * we press the key and a right-alt (AltGr) key.
    // For each modifiers, we need a string used for formatting its expected
    // result. (See the above comment for its format.)
    static const struct {
      MockKeyboard::Modifiers modifiers;
      const char* expected_result;
    } kModifierData[] = {
      {MockKeyboard::NONE,       "false,false,false"},
      {MockKeyboard::LEFT_SHIFT, "true,false,false"},
#if defined(OS_WIN)
      {MockKeyboard::RIGHT_ALT,  "false,false,true"},
#endif
    };

    MockKeyboard::Layout layout = kLayouts[i];
    for (size_t j = 0; j < ARRAYSIZE_UNSAFE(kModifierData); ++j) {
      // Virtual key codes used for this test.
      static const int kKeyCodes[] = {
        '0', '1', '2', '3', '4', '5', '6', '7',
        '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
        'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
        'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
        'W', 'X', 'Y', 'Z',
        ui::VKEY_OEM_1,
        ui::VKEY_OEM_PLUS,
        ui::VKEY_OEM_COMMA,
        ui::VKEY_OEM_MINUS,
        ui::VKEY_OEM_PERIOD,
        ui::VKEY_OEM_2,
        ui::VKEY_OEM_3,
        ui::VKEY_OEM_4,
        ui::VKEY_OEM_5,
        ui::VKEY_OEM_6,
        ui::VKEY_OEM_7,
#if defined(OS_WIN)
        // Not sure how to handle this key on Linux.
        ui::VKEY_OEM_8,
#endif
      };

      MockKeyboard::Modifiers modifiers = kModifierData[j].modifiers;
      for (size_t k = 0; k < ARRAYSIZE_UNSAFE(kKeyCodes); ++k) {
        // Send a keyboard event to the RenderView object.
        // We should test a keyboard event only when the given keyboard-layout
        // driver is installed in a PC and the driver can assign a Unicode
        // charcter for the given tuple (key-code and modifiers).
        int key_code = kKeyCodes[k];
        base::string16 char_code;
        if (SendKeyEvent(layout, key_code, modifiers, &char_code) < 0)
          continue;

        // Create an expected result from the virtual-key code, the character
        // code, and the modifier-key status.
        // We format a string that emulates a DOM-event string produced hy
        // our JavaScript function. (See the above comment for the format.)
        static char expected_result[1024];
        expected_result[0] = 0;
        base::snprintf(&expected_result[0],
                       sizeof(expected_result),
                       "\n"       // texts in the <input> element
                       "%d,%s\n"  // texts in the first <div> element
                       "%d,%s\n"  // texts in the second <div> element
                       "%d,%s",   // texts in the third <div> element
                       key_code, kModifierData[j].expected_result,
                       static_cast<int>(char_code[0]),
                       kModifierData[j].expected_result,
                       key_code, kModifierData[j].expected_result);

        // Retrieve the text in the test page and compare it with the expected
        // text created from a virtual-key code, a character code, and the
        // modifier-key status.
        const int kMaxOutputCharacters = 1024;
        std::string output = UTF16ToUTF8(
            GetMainFrame()->contentAsText(kMaxOutputCharacters));
        EXPECT_EQ(expected_result, output);
      }
    }
  }
#else
  NOTIMPLEMENTED();
#endif
}

// Test that our EditorClientImpl class can insert characters when we send
// keyboard events through the RenderWidget::OnHandleInputEvent() function.
// This test is for preventing regressions caused only when we use non-US
// keyboards, such as Issue 10846.
// see http://crbug.com/244562
#if defined(OS_WIN)
#define MAYBE_InsertCharacters DISABLED_InsertCharacters
#else
#define MAYBE_InsertCharacters InsertCharacters
#endif
TEST_F(RenderViewImplTest, MAYBE_InsertCharacters) {
#if !defined(OS_MACOSX)
  static const struct {
    MockKeyboard::Layout layout;
    const wchar_t* expected_result;
  } kLayouts[] = {
#if 0
    // Disabled these keyboard layouts because buildbots do not have their
    // keyboard-layout drivers installed.
    {MockKeyboard::LAYOUT_ARABIC,
     L"\x0030\x0031\x0032\x0033\x0034\x0035\x0036\x0037"
     L"\x0038\x0039\x0634\x0624\x064a\x062b\x0628\x0644"
     L"\x0627\x0647\x062a\x0646\x0645\x0629\x0649\x062e"
     L"\x062d\x0636\x0642\x0633\x0641\x0639\x0631\x0635"
     L"\x0621\x063a\x0626\x0643\x003d\x0648\x002d\x0632"
     L"\x0638\x0630\x062c\x005c\x062f\x0637\x0028\x0021"
     L"\x0040\x0023\x0024\x0025\x005e\x0026\x002a\x0029"
     L"\x0650\x007d\x005d\x064f\x005b\x0623\x00f7\x0640"
     L"\x060c\x002f\x2019\x0622\x00d7\x061b\x064e\x064c"
     L"\x064d\x2018\x007b\x064b\x0652\x0625\x007e\x003a"
     L"\x002b\x002c\x005f\x002e\x061f\x0651\x003c\x007c"
     L"\x003e\x0022\x0030\x0031\x0032\x0033\x0034\x0035"
     L"\x0036\x0037\x0038\x0039\x0634\x0624\x064a\x062b"
     L"\x0628\x0644\x0627\x0647\x062a\x0646\x0645\x0629"
     L"\x0649\x062e\x062d\x0636\x0642\x0633\x0641\x0639"
     L"\x0631\x0635\x0621\x063a\x0626\x0643\x003d\x0648"
     L"\x002d\x0632\x0638\x0630\x062c\x005c\x062f\x0637"
    },
    {MockKeyboard::LAYOUT_HEBREW,
     L"\x0030\x0031\x0032\x0033\x0034\x0035\x0036\x0037"
     L"\x0038\x0039\x05e9\x05e0\x05d1\x05d2\x05e7\x05db"
     L"\x05e2\x05d9\x05df\x05d7\x05dc\x05da\x05e6\x05de"
     L"\x05dd\x05e4\x002f\x05e8\x05d3\x05d0\x05d5\x05d4"
     L"\x0027\x05e1\x05d8\x05d6\x05e3\x003d\x05ea\x002d"
     L"\x05e5\x002e\x003b\x005d\x005c\x005b\x002c\x0028"
     L"\x0021\x0040\x0023\x0024\x0025\x005e\x0026\x002a"
     L"\x0029\x0041\x0042\x0043\x0044\x0045\x0046\x0047"
     L"\x0048\x0049\x004a\x004b\x004c\x004d\x004e\x004f"
     L"\x0050\x0051\x0052\x0053\x0054\x0055\x0056\x0057"
     L"\x0058\x0059\x005a\x003a\x002b\x003e\x005f\x003c"
     L"\x003f\x007e\x007d\x007c\x007b\x0022\x0030\x0031"
     L"\x0032\x0033\x0034\x0035\x0036\x0037\x0038\x0039"
     L"\x05e9\x05e0\x05d1\x05d2\x05e7\x05db\x05e2\x05d9"
     L"\x05df\x05d7\x05dc\x05da\x05e6\x05de\x05dd\x05e4"
     L"\x002f\x05e8\x05d3\x05d0\x05d5\x05d4\x0027\x05e1"
     L"\x05d8\x05d6\x05e3\x003d\x05ea\x002d\x05e5\x002e"
     L"\x003b\x005d\x005c\x005b\x002c"
    },
#endif
#if defined(OS_WIN)
    // On Linux, the only way to test alternate keyboard layouts is to change
    // the keyboard layout of the whole screen. I'm worried about the side
    // effects this may have on the buildbots.
    {MockKeyboard::LAYOUT_CANADIAN_FRENCH,
     L"\x0030\x0031\x0032\x0033\x0034\x0035\x0036\x0037"
     L"\x0038\x0039\x0061\x0062\x0063\x0064\x0065\x0066"
     L"\x0067\x0068\x0069\x006a\x006b\x006c\x006d\x006e"
     L"\x006f\x0070\x0071\x0072\x0073\x0074\x0075\x0076"
     L"\x0077\x0078\x0079\x007a\x003b\x003d\x002c\x002d"
     L"\x002e\x00e9\x003c\x0029\x0021\x0022\x002f\x0024"
     L"\x0025\x003f\x0026\x002a\x0028\x0041\x0042\x0043"
     L"\x0044\x0045\x0046\x0047\x0048\x0049\x004a\x004b"
     L"\x004c\x004d\x004e\x004f\x0050\x0051\x0052\x0053"
     L"\x0054\x0055\x0056\x0057\x0058\x0059\x005a\x003a"
     L"\x002b\x0027\x005f\x002e\x00c9\x003e\x0030\x0031"
     L"\x0032\x0033\x0034\x0035\x0036\x0037\x0038\x0039"
     L"\x0061\x0062\x0063\x0064\x0065\x0066\x0067\x0068"
     L"\x0069\x006a\x006b\x006c\x006d\x006e\x006f\x0070"
     L"\x0071\x0072\x0073\x0074\x0075\x0076\x0077\x0078"
     L"\x0079\x007a\x003b\x003d\x002c\x002d\x002e\x00e9"
     L"\x003c"
    },
    {MockKeyboard::LAYOUT_FRENCH,
     L"\x00e0\x0026\x00e9\x0022\x0027\x0028\x002d\x00e8"
     L"\x005f\x00e7\x0061\x0062\x0063\x0064\x0065\x0066"
     L"\x0067\x0068\x0069\x006a\x006b\x006c\x006d\x006e"
     L"\x006f\x0070\x0071\x0072\x0073\x0074\x0075\x0076"
     L"\x0077\x0078\x0079\x007a\x0024\x003d\x002c\x003b"
     L"\x003a\x00f9\x0029\x002a\x0021\x0030\x0031\x0032"
     L"\x0033\x0034\x0035\x0036\x0037\x0038\x0039\x0041"
     L"\x0042\x0043\x0044\x0045\x0046\x0047\x0048\x0049"
     L"\x004a\x004b\x004c\x004d\x004e\x004f\x0050\x0051"
     L"\x0052\x0053\x0054\x0055\x0056\x0057\x0058\x0059"
     L"\x005a\x00a3\x002b\x003f\x002e\x002f\x0025\x00b0"
     L"\x00b5\x00e0\x0026\x00e9\x0022\x0027\x0028\x002d"
     L"\x00e8\x005f\x00e7\x0061\x0062\x0063\x0064\x0065"
     L"\x0066\x0067\x0068\x0069\x006a\x006b\x006c\x006d"
     L"\x006e\x006f\x0070\x0071\x0072\x0073\x0074\x0075"
     L"\x0076\x0077\x0078\x0079\x007a\x0024\x003d\x002c"
     L"\x003b\x003a\x00f9\x0029\x002a\x0021"
    },
    {MockKeyboard::LAYOUT_RUSSIAN,
     L"\x0030\x0031\x0032\x0033\x0034\x0035\x0036\x0037"
     L"\x0038\x0039\x0444\x0438\x0441\x0432\x0443\x0430"
     L"\x043f\x0440\x0448\x043e\x043b\x0434\x044c\x0442"
     L"\x0449\x0437\x0439\x043a\x044b\x0435\x0433\x043c"
     L"\x0446\x0447\x043d\x044f\x0436\x003d\x0431\x002d"
     L"\x044e\x002e\x0451\x0445\x005c\x044a\x044d\x0029"
     L"\x0021\x0022\x2116\x003b\x0025\x003a\x003f\x002a"
     L"\x0028\x0424\x0418\x0421\x0412\x0423\x0410\x041f"
     L"\x0420\x0428\x041e\x041b\x0414\x042c\x0422\x0429"
     L"\x0417\x0419\x041a\x042b\x0415\x0413\x041c\x0426"
     L"\x0427\x041d\x042f\x0416\x002b\x0411\x005f\x042e"
     L"\x002c\x0401\x0425\x002f\x042a\x042d\x0030\x0031"
     L"\x0032\x0033\x0034\x0035\x0036\x0037\x0038\x0039"
     L"\x0444\x0438\x0441\x0432\x0443\x0430\x043f\x0440"
     L"\x0448\x043e\x043b\x0434\x044c\x0442\x0449\x0437"
     L"\x0439\x043a\x044b\x0435\x0433\x043c\x0446\x0447"
     L"\x043d\x044f\x0436\x003d\x0431\x002d\x044e\x002e"
     L"\x0451\x0445\x005c\x044a\x044d"
    },
#endif  // defined(OS_WIN)
    {MockKeyboard::LAYOUT_UNITED_STATES,
     L"\x0030\x0031\x0032\x0033\x0034\x0035\x0036\x0037"
     L"\x0038\x0039\x0061\x0062\x0063\x0064\x0065\x0066"
     L"\x0067\x0068\x0069\x006a\x006b\x006c\x006d\x006e"
     L"\x006f\x0070\x0071\x0072\x0073\x0074\x0075\x0076"
     L"\x0077\x0078\x0079\x007a\x003b\x003d\x002c\x002d"
     L"\x002e\x002f\x0060\x005b\x005c\x005d\x0027\x0029"
     L"\x0021\x0040\x0023\x0024\x0025\x005e\x0026\x002a"
     L"\x0028\x0041\x0042\x0043\x0044\x0045\x0046\x0047"
     L"\x0048\x0049\x004a\x004b\x004c\x004d\x004e\x004f"
     L"\x0050\x0051\x0052\x0053\x0054\x0055\x0056\x0057"
     L"\x0058\x0059\x005a\x003a\x002b\x003c\x005f\x003e"
     L"\x003f\x007e\x007b\x007c\x007d\x0022"
#if defined(OS_WIN)
     // This is ifdefed out for Linux to correspond to the fact that we don't
     // test alt+keystroke for now.
     L"\x0030\x0031\x0032\x0033\x0034\x0035\x0036\x0037"
     L"\x0038\x0039\x0061\x0062\x0063\x0064\x0065\x0066"
     L"\x0067\x0068\x0069\x006a\x006b\x006c\x006d\x006e"
     L"\x006f\x0070\x0071\x0072\x0073\x0074\x0075\x0076"
     L"\x0077\x0078\x0079\x007a\x003b\x003d\x002c\x002d"
     L"\x002e\x002f\x0060\x005b\x005c\x005d\x0027"
#endif
    },
  };

  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kLayouts); ++i) {
    // Load an HTML page consisting of one <div> element.
    // This <div> element is used by the EditorClientImpl class to insert
    // characters received through the RenderWidget::OnHandleInputEvent()
    // function.
    view()->set_send_content_state_immediately(true);
    LoadHTML("<html>"
             "<head>"
             "<title></title>"
             "</head>"
             "<body>"
             "<div id='test' contenteditable='true'>"
             "</div>"
             "</body>"
             "</html>");
    ExecuteJavaScript("document.getElementById('test').focus();");
    render_thread_->sink().ClearMessages();

    // For each key code, we send three keyboard events.
    //  * Pressing only the key;
    //  * Pressing the key and a left-shift key, and;
    //  * Pressing the key and a right-alt (AltGr) key.
    static const MockKeyboard::Modifiers kModifiers[] = {
      MockKeyboard::NONE,
      MockKeyboard::LEFT_SHIFT,
#if defined(OS_WIN)
      MockKeyboard::RIGHT_ALT,
#endif
    };

    MockKeyboard::Layout layout = kLayouts[i].layout;
    for (size_t j = 0; j < ARRAYSIZE_UNSAFE(kModifiers); ++j) {
      // Virtual key codes used for this test.
      static const int kKeyCodes[] = {
        '0', '1', '2', '3', '4', '5', '6', '7',
        '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
        'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
        'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
        'W', 'X', 'Y', 'Z',
        ui::VKEY_OEM_1,
        ui::VKEY_OEM_PLUS,
        ui::VKEY_OEM_COMMA,
        ui::VKEY_OEM_MINUS,
        ui::VKEY_OEM_PERIOD,
        ui::VKEY_OEM_2,
        ui::VKEY_OEM_3,
        ui::VKEY_OEM_4,
        ui::VKEY_OEM_5,
        ui::VKEY_OEM_6,
        ui::VKEY_OEM_7,
#if defined(OS_WIN)
        // Unclear how to handle this on Linux.
        ui::VKEY_OEM_8,
#endif
      };

      MockKeyboard::Modifiers modifiers = kModifiers[j];
      for (size_t k = 0; k < ARRAYSIZE_UNSAFE(kKeyCodes); ++k) {
        // Send a keyboard event to the RenderView object.
        // We should test a keyboard event only when the given keyboard-layout
        // driver is installed in a PC and the driver can assign a Unicode
        // charcter for the given tuple (layout, key-code, and modifiers).
        int key_code = kKeyCodes[k];
        base::string16 char_code;
        if (SendKeyEvent(layout, key_code, modifiers, &char_code) < 0)
          continue;
      }
    }

    // Retrieve the text in the test page and compare it with the expected
    // text created from a virtual-key code, a character code, and the
    // modifier-key status.
    const int kMaxOutputCharacters = 4096;
    std::wstring output = UTF16ToWideHack(
        GetMainFrame()->contentAsText(kMaxOutputCharacters));
    EXPECT_EQ(kLayouts[i].expected_result, output);
  }
#else
  NOTIMPLEMENTED();
#endif
}

// Crashy, http://crbug.com/53247.
TEST_F(RenderViewImplTest, DISABLED_DidFailProvisionalLoadWithErrorForError) {
  GetMainFrame()->enableViewSourceMode(true);
  WebURLError error;
  error.domain = WebString::fromUTF8(net::kErrorDomain);
  error.reason = net::ERR_FILE_NOT_FOUND;
  error.unreachableURL = GURL("http://foo");
  WebFrame* web_frame = GetMainFrame();

  // Start a load that will reach provisional state synchronously,
  // but won't complete synchronously.
  ViewMsg_Navigate_Params params;
  params.page_id = -1;
  params.navigation_type = ViewMsg_Navigate_Type::NORMAL;
  params.url = GURL("data:text/html,test data");
  view()->OnNavigate(params);

  // An error occurred.
  view()->didFailProvisionalLoad(web_frame, error);
  // Frame should exit view-source mode.
  EXPECT_FALSE(web_frame->isViewSourceModeEnabled());
}

TEST_F(RenderViewImplTest, DidFailProvisionalLoadWithErrorForCancellation) {
  GetMainFrame()->enableViewSourceMode(true);
  WebURLError error;
  error.domain = WebString::fromUTF8(net::kErrorDomain);
  error.reason = net::ERR_ABORTED;
  error.unreachableURL = GURL("http://foo");
  WebFrame* web_frame = GetMainFrame();

  // Start a load that will reach provisional state synchronously,
  // but won't complete synchronously.
  ViewMsg_Navigate_Params params;
  params.page_id = -1;
  params.navigation_type = ViewMsg_Navigate_Type::NORMAL;
  params.url = GURL("data:text/html,test data");
  view()->OnNavigate(params);

  // A cancellation occurred.
  view()->didFailProvisionalLoad(web_frame, error);
  // Frame should stay in view-source mode.
  EXPECT_TRUE(web_frame->isViewSourceModeEnabled());
}

// Regression test for http://crbug.com/41562
TEST_F(RenderViewImplTest, UpdateTargetURLWithInvalidURL) {
  const GURL invalid_gurl("http://");
  view()->setMouseOverURL(blink::WebURL(invalid_gurl));
  EXPECT_EQ(invalid_gurl, view()->target_url_);
}

TEST_F(RenderViewImplTest, SetHistoryLengthAndPrune) {
  int expected_page_id = -1;

  // No history to merge and no committed pages.
  view()->OnSetHistoryLengthAndPrune(0, -1);
  EXPECT_EQ(0, view()->history_list_length_);
  EXPECT_EQ(-1, view()->history_list_offset_);

  // History to merge and no committed pages.
  view()->OnSetHistoryLengthAndPrune(2, -1);
  EXPECT_EQ(2, view()->history_list_length_);
  EXPECT_EQ(1, view()->history_list_offset_);
  EXPECT_EQ(-1, view()->history_page_ids_[0]);
  EXPECT_EQ(-1, view()->history_page_ids_[1]);
  ClearHistory();

  // No history to merge and a committed page to be kept.
  view()->didCommitProvisionalLoad(GetMainFrame(), true);
  expected_page_id = view()->page_id_;
  view()->OnSetHistoryLengthAndPrune(0, expected_page_id);
  EXPECT_EQ(1, view()->history_list_length_);
  EXPECT_EQ(0, view()->history_list_offset_);
  EXPECT_EQ(expected_page_id, view()->history_page_ids_[0]);
  ClearHistory();

  // No history to merge and a committed page to be pruned.
  view()->didCommitProvisionalLoad(GetMainFrame(), true);
  expected_page_id = view()->page_id_;
  view()->OnSetHistoryLengthAndPrune(0, expected_page_id + 1);
  EXPECT_EQ(0, view()->history_list_length_);
  EXPECT_EQ(-1, view()->history_list_offset_);
  ClearHistory();

  // No history to merge and a committed page that the browser was unaware of.
  view()->didCommitProvisionalLoad(GetMainFrame(), true);
  expected_page_id = view()->page_id_;
  view()->OnSetHistoryLengthAndPrune(0, -1);
  EXPECT_EQ(1, view()->history_list_length_);
  EXPECT_EQ(0, view()->history_list_offset_);
  EXPECT_EQ(expected_page_id, view()->history_page_ids_[0]);
  ClearHistory();

  // History to merge and a committed page to be kept.
  view()->didCommitProvisionalLoad(GetMainFrame(), true);
  expected_page_id = view()->page_id_;
  view()->OnSetHistoryLengthAndPrune(2, expected_page_id);
  EXPECT_EQ(3, view()->history_list_length_);
  EXPECT_EQ(2, view()->history_list_offset_);
  EXPECT_EQ(-1, view()->history_page_ids_[0]);
  EXPECT_EQ(-1, view()->history_page_ids_[1]);
  EXPECT_EQ(expected_page_id, view()->history_page_ids_[2]);
  ClearHistory();

  // History to merge and a committed page to be pruned.
  view()->didCommitProvisionalLoad(GetMainFrame(), true);
  expected_page_id = view()->page_id_;
  view()->OnSetHistoryLengthAndPrune(2, expected_page_id + 1);
  EXPECT_EQ(2, view()->history_list_length_);
  EXPECT_EQ(1, view()->history_list_offset_);
  EXPECT_EQ(-1, view()->history_page_ids_[0]);
  EXPECT_EQ(-1, view()->history_page_ids_[1]);
  ClearHistory();

  // History to merge and a committed page that the browser was unaware of.
  view()->didCommitProvisionalLoad(GetMainFrame(), true);
  expected_page_id = view()->page_id_;
  view()->OnSetHistoryLengthAndPrune(2, -1);
  EXPECT_EQ(3, view()->history_list_length_);
  EXPECT_EQ(2, view()->history_list_offset_);
  EXPECT_EQ(-1, view()->history_page_ids_[0]);
  EXPECT_EQ(-1, view()->history_page_ids_[1]);
  EXPECT_EQ(expected_page_id, view()->history_page_ids_[2]);
  ClearHistory();

  int expected_page_id_2 = -1;

  // No history to merge and two committed pages, both to be kept.
  view()->didCommitProvisionalLoad(GetMainFrame(), true);
  expected_page_id = view()->page_id_;
  view()->didCommitProvisionalLoad(GetMainFrame(), true);
  expected_page_id_2 = view()->page_id_;
  EXPECT_GT(expected_page_id_2, expected_page_id);
  view()->OnSetHistoryLengthAndPrune(0, expected_page_id);
  EXPECT_EQ(2, view()->history_list_length_);
  EXPECT_EQ(1, view()->history_list_offset_);
  EXPECT_EQ(expected_page_id, view()->history_page_ids_[0]);
  EXPECT_EQ(expected_page_id_2, view()->history_page_ids_[1]);
  ClearHistory();

  // No history to merge and two committed pages, and only the second is kept.
  view()->didCommitProvisionalLoad(GetMainFrame(), true);
  expected_page_id = view()->page_id_;
  view()->didCommitProvisionalLoad(GetMainFrame(), true);
  expected_page_id_2 = view()->page_id_;
  EXPECT_GT(expected_page_id_2, expected_page_id);
  view()->OnSetHistoryLengthAndPrune(0, expected_page_id_2);
  EXPECT_EQ(1, view()->history_list_length_);
  EXPECT_EQ(0, view()->history_list_offset_);
  EXPECT_EQ(expected_page_id_2, view()->history_page_ids_[0]);
  ClearHistory();

  // No history to merge and two committed pages, both of which the browser was
  // unaware of.
  view()->didCommitProvisionalLoad(GetMainFrame(), true);
  expected_page_id = view()->page_id_;
  view()->didCommitProvisionalLoad(GetMainFrame(), true);
  expected_page_id_2 = view()->page_id_;
  EXPECT_GT(expected_page_id_2, expected_page_id);
  view()->OnSetHistoryLengthAndPrune(0, -1);
  EXPECT_EQ(2, view()->history_list_length_);
  EXPECT_EQ(1, view()->history_list_offset_);
  EXPECT_EQ(expected_page_id, view()->history_page_ids_[0]);
  EXPECT_EQ(expected_page_id_2, view()->history_page_ids_[1]);
  ClearHistory();

  // History to merge and two committed pages, both to be kept.
  view()->didCommitProvisionalLoad(GetMainFrame(), true);
  expected_page_id = view()->page_id_;
  view()->didCommitProvisionalLoad(GetMainFrame(), true);
  expected_page_id_2 = view()->page_id_;
  EXPECT_GT(expected_page_id_2, expected_page_id);
  view()->OnSetHistoryLengthAndPrune(2, expected_page_id);
  EXPECT_EQ(4, view()->history_list_length_);
  EXPECT_EQ(3, view()->history_list_offset_);
  EXPECT_EQ(-1, view()->history_page_ids_[0]);
  EXPECT_EQ(-1, view()->history_page_ids_[1]);
  EXPECT_EQ(expected_page_id, view()->history_page_ids_[2]);
  EXPECT_EQ(expected_page_id_2, view()->history_page_ids_[3]);
  ClearHistory();

  // History to merge and two committed pages, and only the second is kept.
  view()->didCommitProvisionalLoad(GetMainFrame(), true);
  expected_page_id = view()->page_id_;
  view()->didCommitProvisionalLoad(GetMainFrame(), true);
  expected_page_id_2 = view()->page_id_;
  EXPECT_GT(expected_page_id_2, expected_page_id);
  view()->OnSetHistoryLengthAndPrune(2, expected_page_id_2);
  EXPECT_EQ(3, view()->history_list_length_);
  EXPECT_EQ(2, view()->history_list_offset_);
  EXPECT_EQ(-1, view()->history_page_ids_[0]);
  EXPECT_EQ(-1, view()->history_page_ids_[1]);
  EXPECT_EQ(expected_page_id_2, view()->history_page_ids_[2]);
  ClearHistory();

  // History to merge and two committed pages, both of which the browser was
  // unaware of.
  view()->didCommitProvisionalLoad(GetMainFrame(), true);
  expected_page_id = view()->page_id_;
  view()->didCommitProvisionalLoad(GetMainFrame(), true);
  expected_page_id_2 = view()->page_id_;
  EXPECT_GT(expected_page_id_2, expected_page_id);
  view()->OnSetHistoryLengthAndPrune(2, -1);
  EXPECT_EQ(4, view()->history_list_length_);
  EXPECT_EQ(3, view()->history_list_offset_);
  EXPECT_EQ(-1, view()->history_page_ids_[0]);
  EXPECT_EQ(-1, view()->history_page_ids_[1]);
  EXPECT_EQ(expected_page_id, view()->history_page_ids_[2]);
  EXPECT_EQ(expected_page_id_2, view()->history_page_ids_[3]);
}

TEST_F(RenderViewImplTest, ContextMenu) {
  LoadHTML("<div>Page A</div>");

  // Create a right click in the center of the iframe. (I'm hoping this will
  // make this a bit more robust in case of some other formatting or other bug.)
  WebMouseEvent mouse_event;
  mouse_event.type = WebInputEvent::MouseDown;
  mouse_event.button = WebMouseEvent::ButtonRight;
  mouse_event.x = 250;
  mouse_event.y = 250;
  mouse_event.globalX = 250;
  mouse_event.globalY = 250;

  SendWebMouseEvent(mouse_event);

  // Now simulate the corresponding up event which should display the menu
  mouse_event.type = WebInputEvent::MouseUp;
  SendWebMouseEvent(mouse_event);

  EXPECT_TRUE(render_thread_->sink().GetUniqueMessageMatching(
      ViewHostMsg_ContextMenu::ID));
}

TEST_F(RenderViewImplTest, TestBackForward) {
  LoadHTML("<div id=pagename>Page A</div>");
  blink::WebHistoryItem page_a_item = GetMainFrame()->currentHistoryItem();
  int was_page_a = -1;
  base::string16 check_page_a =
      ASCIIToUTF16(
          "Number(document.getElementById('pagename').innerHTML == 'Page A')");
  EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(check_page_a, &was_page_a));
  EXPECT_EQ(1, was_page_a);

  LoadHTML("<div id=pagename>Page B</div>");
  int was_page_b = -1;
  base::string16 check_page_b =
      ASCIIToUTF16(
          "Number(document.getElementById('pagename').innerHTML == 'Page B')");
  EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(check_page_b, &was_page_b));
  EXPECT_EQ(1, was_page_b);

  LoadHTML("<div id=pagename>Page C</div>");
  int was_page_c = -1;
  base::string16 check_page_c =
      ASCIIToUTF16(
          "Number(document.getElementById('pagename').innerHTML == 'Page C')");
  EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(check_page_c, &was_page_c));
  EXPECT_EQ(1, was_page_b);

  blink::WebHistoryItem forward_item = GetMainFrame()->currentHistoryItem();
  GoBack(GetMainFrame()->previousHistoryItem());
  EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(check_page_b, &was_page_b));
  EXPECT_EQ(1, was_page_b);

  GoForward(forward_item);
  EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(check_page_c, &was_page_c));
  EXPECT_EQ(1, was_page_c);

  GoBack(GetMainFrame()->previousHistoryItem());
  EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(check_page_b, &was_page_b));
  EXPECT_EQ(1, was_page_b);

  forward_item = GetMainFrame()->currentHistoryItem();
  GoBack(page_a_item);
  EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(check_page_a, &was_page_a));
  EXPECT_EQ(1, was_page_a);

  GoForward(forward_item);
  EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(check_page_b, &was_page_b));
  EXPECT_EQ(1, was_page_b);
}

#if defined(OS_MACOSX) || defined(OS_WIN) || defined(USE_AURA)
TEST_F(RenderViewImplTest, GetCompositionCharacterBoundsTest) {

#if defined(OS_WIN)
  // http://crbug.com/304193
  if (base::win::GetVersion() < base::win::VERSION_VISTA)
    return;
#endif

  LoadHTML("<textarea id=\"test\"></textarea>");
  ExecuteJavaScript("document.getElementById('test').focus();");

  const base::string16 empty_string = UTF8ToUTF16("");
  const std::vector<blink::WebCompositionUnderline> empty_underline;
  std::vector<gfx::Rect> bounds;
  view()->OnSetFocus(true);
  view()->OnSetInputMethodActive(true);

  // ASCII composition
  const base::string16 ascii_composition = UTF8ToUTF16("aiueo");
  view()->OnImeSetComposition(ascii_composition, empty_underline, 0, 0);
  view()->GetCompositionCharacterBounds(&bounds);
  ASSERT_EQ(ascii_composition.size(), bounds.size());
  for (size_t i = 0; i < bounds.size(); ++i)
    EXPECT_LT(0, bounds[i].width());
  view()->OnImeConfirmComposition(
      empty_string, gfx::Range::InvalidRange(), false);

  // Non surrogate pair unicode character.
  const base::string16 unicode_composition = UTF8ToUTF16(
      "\xE3\x81\x82\xE3\x81\x84\xE3\x81\x86\xE3\x81\x88\xE3\x81\x8A");
  view()->OnImeSetComposition(unicode_composition, empty_underline, 0, 0);
  view()->GetCompositionCharacterBounds(&bounds);
  ASSERT_EQ(unicode_composition.size(), bounds.size());
  for (size_t i = 0; i < bounds.size(); ++i)
    EXPECT_LT(0, bounds[i].width());
  view()->OnImeConfirmComposition(
      empty_string, gfx::Range::InvalidRange(), false);

  // Surrogate pair character.
  const base::string16 surrogate_pair_char = UTF8ToUTF16("\xF0\xA0\xAE\x9F");
  view()->OnImeSetComposition(surrogate_pair_char,
                              empty_underline,
                              0,
                              0);
  view()->GetCompositionCharacterBounds(&bounds);
  ASSERT_EQ(surrogate_pair_char.size(), bounds.size());
  EXPECT_LT(0, bounds[0].width());
  EXPECT_EQ(0, bounds[1].width());
  view()->OnImeConfirmComposition(
      empty_string, gfx::Range::InvalidRange(), false);

  // Mixed string.
  const base::string16 surrogate_pair_mixed_composition =
      surrogate_pair_char + UTF8ToUTF16("\xE3\x81\x82") + surrogate_pair_char +
      UTF8ToUTF16("b") + surrogate_pair_char;
  const size_t utf16_length = 8UL;
  const bool is_surrogate_pair_empty_rect[8] = {
    false, true, false, false, true, false, false, true };
  view()->OnImeSetComposition(surrogate_pair_mixed_composition,
                              empty_underline,
                              0,
                              0);
  view()->GetCompositionCharacterBounds(&bounds);
  ASSERT_EQ(utf16_length, bounds.size());
  for (size_t i = 0; i < utf16_length; ++i) {
    if (is_surrogate_pair_empty_rect[i]) {
      EXPECT_EQ(0, bounds[i].width());
    } else {
      EXPECT_LT(0, bounds[i].width());
    }
  }
  view()->OnImeConfirmComposition(
      empty_string, gfx::Range::InvalidRange(), false);
}
#endif

TEST_F(RenderViewImplTest, ZoomLimit) {
  const double kMinZoomLevel = ZoomFactorToZoomLevel(kMinimumZoomFactor);
  const double kMaxZoomLevel = ZoomFactorToZoomLevel(kMaximumZoomFactor);

  ViewMsg_Navigate_Params params;
  params.page_id = -1;
  params.navigation_type = ViewMsg_Navigate_Type::NORMAL;

  // Verifies navigation to a URL with preset zoom level indeed sets the level.
  // Regression test for http://crbug.com/139559, where the level was not
  // properly set when it is out of the default zoom limits of WebView.
  params.url = GURL("data:text/html,min_zoomlimit_test");
  view()->OnSetZoomLevelForLoadingURL(params.url, kMinZoomLevel);
  view()->OnNavigate(params);
  ProcessPendingMessages();
  EXPECT_DOUBLE_EQ(kMinZoomLevel, view()->GetWebView()->zoomLevel());

  // It should work even when the zoom limit is temporarily changed in the page.
  view()->GetWebView()->zoomLimitsChanged(ZoomFactorToZoomLevel(1.0),
                                          ZoomFactorToZoomLevel(1.0));
  params.url = GURL("data:text/html,max_zoomlimit_test");
  view()->OnSetZoomLevelForLoadingURL(params.url, kMaxZoomLevel);
  view()->OnNavigate(params);
  ProcessPendingMessages();
  EXPECT_DOUBLE_EQ(kMaxZoomLevel, view()->GetWebView()->zoomLevel());
}

TEST_F(RenderViewImplTest, SetEditableSelectionAndComposition) {
  // Load an HTML page consisting of an input field.
  LoadHTML("<html>"
           "<head>"
           "</head>"
           "<body>"
           "<input id=\"test1\" value=\"some test text hello\"></input>"
           "</body>"
           "</html>");
  ExecuteJavaScript("document.getElementById('test1').focus();");
  view()->OnSetEditableSelectionOffsets(4, 8);
  const std::vector<blink::WebCompositionUnderline> empty_underline;
  view()->OnSetCompositionFromExistingText(7, 10, empty_underline);
  blink::WebTextInputInfo info = view()->webview()->textInputInfo();
  EXPECT_EQ(4, info.selectionStart);
  EXPECT_EQ(8, info.selectionEnd);
  EXPECT_EQ(7, info.compositionStart);
  EXPECT_EQ(10, info.compositionEnd);
  view()->OnUnselect();
  info = view()->webview()->textInputInfo();
  EXPECT_EQ(0, info.selectionStart);
  EXPECT_EQ(0, info.selectionEnd);
}


TEST_F(RenderViewImplTest, OnExtendSelectionAndDelete) {
  // Load an HTML page consisting of an input field.
  LoadHTML("<html>"
           "<head>"
           "</head>"
           "<body>"
           "<input id=\"test1\" value=\"abcdefghijklmnopqrstuvwxyz\"></input>"
           "</body>"
           "</html>");
  ExecuteJavaScript("document.getElementById('test1').focus();");
  view()->OnSetEditableSelectionOffsets(10, 10);
  view()->OnExtendSelectionAndDelete(3, 4);
  blink::WebTextInputInfo info = view()->webview()->textInputInfo();
  EXPECT_EQ("abcdefgopqrstuvwxyz", info.value);
  EXPECT_EQ(7, info.selectionStart);
  EXPECT_EQ(7, info.selectionEnd);
  view()->OnSetEditableSelectionOffsets(4, 8);
  view()->OnExtendSelectionAndDelete(2, 5);
  info = view()->webview()->textInputInfo();
  EXPECT_EQ("abuvwxyz", info.value);
  EXPECT_EQ(2, info.selectionStart);
  EXPECT_EQ(2, info.selectionEnd);
}

// Test that the navigating specific frames works correctly.
TEST_F(RenderViewImplTest, NavigateFrame) {
  // Load page A.
  LoadHTML("hello <iframe srcdoc='fail' name='frame'></iframe>");

  // Navigate the frame only.
  ViewMsg_Navigate_Params nav_params;
  nav_params.url = GURL("data:text/html,world");
  nav_params.navigation_type = ViewMsg_Navigate_Type::NORMAL;
  nav_params.transition = PAGE_TRANSITION_TYPED;
  nav_params.current_history_list_length = 1;
  nav_params.current_history_list_offset = 0;
  nav_params.pending_history_list_offset = 1;
  nav_params.page_id = -1;
  nav_params.frame_to_navigate = "frame";
  view()->OnNavigate(nav_params);
  ProcessPendingMessages();

  // Copy the document content to std::wstring and compare with the
  // expected result.
  const int kMaxOutputCharacters = 256;
  std::wstring output = UTF16ToWideHack(
      GetMainFrame()->contentAsText(kMaxOutputCharacters));
  EXPECT_EQ(output, L"hello \n\nworld");
}

// This test ensures that a RenderFrame object is created for the top level
// frame in the RenderView.
TEST_F(RenderViewImplTest, BasicRenderFrame) {
  EXPECT_TRUE(view()->main_render_frame_.get());
}

TEST_F(RenderViewImplTest, GetSSLStatusOfFrame) {
  LoadHTML("<!DOCTYPE html><html><body></body></html>");

  WebFrame* frame = GetMainFrame();
  SSLStatus ssl_status = view()->GetSSLStatusOfFrame(frame);
  EXPECT_FALSE(net::IsCertStatusError(ssl_status.cert_status));

  const_cast<blink::WebURLResponse&>(frame->dataSource()->response()).
      setSecurityInfo(
          SerializeSecurityInfo(0, net::CERT_STATUS_ALL_ERRORS, 0, 0,
                                SignedCertificateTimestampIDStatusList()));
  ssl_status = view()->GetSSLStatusOfFrame(frame);
  EXPECT_TRUE(net::IsCertStatusError(ssl_status.cert_status));
}

TEST_F(RenderViewImplTest, MessageOrderInDidChangeSelection) {
  view()->OnSetInputMethodActive(true);
  view()->set_send_content_state_immediately(true);
  LoadHTML("<textarea id=\"test\"></textarea>");

  view()->handling_input_event_ = true;
  ExecuteJavaScript("document.getElementById('test').focus();");

  bool is_input_type_called = false;
  bool is_selection_called = false;
  size_t last_input_type = 0;
  size_t last_selection = 0;

  for (size_t i = 0; i < render_thread_->sink().message_count(); ++i) {
    const uint32 type = render_thread_->sink().GetMessageAt(i)->type();
    if (type == ViewHostMsg_TextInputTypeChanged::ID) {
      is_input_type_called = true;
      last_input_type = i;
    } else if (type == ViewHostMsg_SelectionChanged::ID) {
      is_selection_called = true;
      last_selection = i;
    }
  }

  EXPECT_TRUE(is_input_type_called);
  EXPECT_TRUE(is_selection_called);

  // InputTypeChange shold be called earlier than SelectionChanged.
  EXPECT_LT(last_input_type, last_selection);
}

class SuppressErrorPageTest : public RenderViewTest {
 public:
  virtual void SetUp() OVERRIDE {
    SetRendererClientForTesting(&client_);
    RenderViewTest::SetUp();
  }

  RenderViewImpl* view() {
    return static_cast<RenderViewImpl*>(view_);
  }

 private:
  class TestContentRendererClient : public ContentRendererClient {
   public:
    virtual bool ShouldSuppressErrorPage(const GURL& url) OVERRIDE {
      return url == GURL("http://example.com/suppress");
    }

    virtual void GetNavigationErrorStrings(
        blink::WebFrame* frame,
        const blink::WebURLRequest& failed_request,
        const blink::WebURLError& error,
        const std::string& accept_languages,
        std::string* error_html,
        base::string16* error_description) OVERRIDE {
      if (error_html)
        *error_html = "A suffusion of yellow.";
    }
  };

  TestContentRendererClient client_;
};

#if defined(OS_ANDROID)
// Crashing on Android: http://crbug.com/311341
#define MAYBE_Suppresses DISABLED_Suppresses
#else
#define MAYBE_Suppresses Suppresses
#endif

TEST_F(SuppressErrorPageTest, MAYBE_Suppresses) {
  WebURLError error;
  error.domain = WebString::fromUTF8(net::kErrorDomain);
  error.reason = net::ERR_FILE_NOT_FOUND;
  error.unreachableURL = GURL("http://example.com/suppress");
  WebFrame* web_frame = GetMainFrame();

  // Start a load that will reach provisional state synchronously,
  // but won't complete synchronously.
  ViewMsg_Navigate_Params params;
  params.page_id = -1;
  params.navigation_type = ViewMsg_Navigate_Type::NORMAL;
  params.url = GURL("data:text/html,test data");
  view()->OnNavigate(params);

  // An error occurred.
  view()->didFailProvisionalLoad(web_frame, error);
  const int kMaxOutputCharacters = 22;
  EXPECT_EQ("", UTF16ToASCII(web_frame->contentAsText(kMaxOutputCharacters)));
}

#if defined(OS_ANDROID)
// Crashing on Android: http://crbug.com/311341
#define MAYBE_DoesNotSuppress DISABLED_DoesNotSuppress
#else
#define MAYBE_DoesNotSuppress DoesNotSuppress
#endif

TEST_F(SuppressErrorPageTest, MAYBE_DoesNotSuppress) {
  WebURLError error;
  error.domain = WebString::fromUTF8(net::kErrorDomain);
  error.reason = net::ERR_FILE_NOT_FOUND;
  error.unreachableURL = GURL("http://example.com/dont-suppress");
  WebFrame* web_frame = GetMainFrame();

  // Start a load that will reach provisional state synchronously,
  // but won't complete synchronously.
  ViewMsg_Navigate_Params params;
  params.page_id = -1;
  params.navigation_type = ViewMsg_Navigate_Type::NORMAL;
  params.url = GURL("data:text/html,test data");
  view()->OnNavigate(params);

  // An error occurred.
  view()->didFailProvisionalLoad(web_frame, error);
  ProcessPendingMessages();
  const int kMaxOutputCharacters = 22;
  EXPECT_EQ("A suffusion of yellow.",
            UTF16ToASCII(web_frame->contentAsText(kMaxOutputCharacters)));
}

// Tests if IME API's candidatewindow* events sent from browser are handled
// in renderer.
TEST_F(RenderViewImplTest, SendCandidateWindowEvents) {
  // Sends an HTML with an <input> element and scripts to the renderer.
  // The script handles all 3 of candidatewindow* events for an
  // InputMethodContext object and once it received 'show', 'update', 'hide'
  // should appear in the result div.
  LoadHTML("<input id='test'>"
           "<div id='result'>Result: </div>"
           "<script>"
           "window.onload = function() {"
           "  var result = document.getElementById('result');"
           "  var test = document.getElementById('test');"
           "  test.focus();"
           "  var context = test.inputMethodContext;"
           "  if (context) {"
           "    context.oncandidatewindowshow = function() {"
           "        result.innerText += 'show'; };"
           "    context.oncandidatewindowupdate = function(){"
           "        result.innerText += 'update'; };"
           "    context.oncandidatewindowhide = function(){"
           "        result.innerText += 'hide'; };"
           "  }"
           "};"
           "</script>");

  // Fire candidatewindow events.
  view()->OnCandidateWindowShown();
  view()->OnCandidateWindowUpdated();
  view()->OnCandidateWindowHidden();

  // Retrieve the content and check if it is expected.
  const int kMaxOutputCharacters = 50;
  std::string output = UTF16ToUTF8(
      GetMainFrame()->contentAsText(kMaxOutputCharacters));
  EXPECT_EQ(output, "\nResult:showupdatehide");
}

}  // namespace content
