Home | History | Annotate | Download | only in renderer_host
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "base/path_service.h"
      6 #include "base/strings/utf_string_conversions.h"
      7 #include "base/time/time.h"
      8 #include "base/values.h"
      9 #include "content/browser/frame_host/render_frame_host_impl.h"
     10 #include "content/browser/renderer_host/render_view_host_impl.h"
     11 #include "content/browser/web_contents/web_contents_impl.h"
     12 #include "content/common/view_messages.h"
     13 #include "content/public/browser/notification_types.h"
     14 #include "content/public/browser/web_contents_observer.h"
     15 #include "content/public/common/content_paths.h"
     16 #include "content/public/common/frame_navigate_params.h"
     17 #include "content/public/test/browser_test_utils.h"
     18 #include "content/public/test/content_browser_test.h"
     19 #include "content/public/test/content_browser_test_utils.h"
     20 #include "content/shell/browser/shell.h"
     21 #include "net/base/filename_util.h"
     22 #include "net/base/host_port_pair.h"
     23 #include "net/test/embedded_test_server/embedded_test_server.h"
     24 
     25 namespace content {
     26 
     27 class RenderViewHostTest : public ContentBrowserTest {
     28  public:
     29   RenderViewHostTest() {}
     30 };
     31 
     32 class RenderViewHostTestWebContentsObserver : public WebContentsObserver {
     33  public:
     34   explicit RenderViewHostTestWebContentsObserver(WebContents* web_contents)
     35       : WebContentsObserver(web_contents),
     36         navigation_count_(0) {}
     37   virtual ~RenderViewHostTestWebContentsObserver() {}
     38 
     39   virtual void DidNavigateMainFrame(
     40       const LoadCommittedDetails& details,
     41       const FrameNavigateParams& params) OVERRIDE {
     42     observed_socket_address_ = params.socket_address;
     43     base_url_ = params.base_url;
     44     ++navigation_count_;
     45   }
     46 
     47   const net::HostPortPair& observed_socket_address() const {
     48     return observed_socket_address_;
     49   }
     50 
     51   GURL base_url() const {
     52     return base_url_;
     53   }
     54 
     55   int navigation_count() const { return navigation_count_; }
     56 
     57  private:
     58   net::HostPortPair observed_socket_address_;
     59   GURL base_url_;
     60   int navigation_count_;
     61 
     62   DISALLOW_COPY_AND_ASSIGN(RenderViewHostTestWebContentsObserver);
     63 };
     64 
     65 IN_PROC_BROWSER_TEST_F(RenderViewHostTest, FrameNavigateSocketAddress) {
     66   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
     67   RenderViewHostTestWebContentsObserver observer(shell()->web_contents());
     68 
     69   GURL test_url = embedded_test_server()->GetURL("/simple_page.html");
     70   NavigateToURL(shell(), test_url);
     71 
     72   EXPECT_EQ(net::HostPortPair::FromURL(
     73                 embedded_test_server()->base_url()).ToString(),
     74             observer.observed_socket_address().ToString());
     75   EXPECT_EQ(1, observer.navigation_count());
     76 }
     77 
     78 IN_PROC_BROWSER_TEST_F(RenderViewHostTest, BaseURLParam) {
     79   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
     80   RenderViewHostTestWebContentsObserver observer(shell()->web_contents());
     81 
     82   // Base URL is not set if it is the same as the URL.
     83   GURL test_url = embedded_test_server()->GetURL("/simple_page.html");
     84   NavigateToURL(shell(), test_url);
     85   EXPECT_TRUE(observer.base_url().is_empty());
     86   EXPECT_EQ(1, observer.navigation_count());
     87 
     88   // But should be set to the original page when reading MHTML.
     89   base::FilePath content_test_data_dir;
     90   ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &content_test_data_dir));
     91   test_url = net::FilePathToFileURL(
     92       content_test_data_dir.AppendASCII("google.mht"));
     93   NavigateToURL(shell(), test_url);
     94   EXPECT_EQ("http://www.google.com/", observer.base_url().spec());
     95 }
     96 
     97 // This test ensures a RenderFrameHost object is created for the top level frame
     98 // in each RenderViewHost.
     99 IN_PROC_BROWSER_TEST_F(RenderViewHostTest, BasicRenderFrameHost) {
    100   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    101 
    102   GURL test_url = embedded_test_server()->GetURL("/simple_page.html");
    103   NavigateToURL(shell(), test_url);
    104 
    105   FrameTreeNode* old_root = static_cast<WebContentsImpl*>(
    106       shell()->web_contents())->GetFrameTree()->root();
    107   EXPECT_TRUE(old_root->current_frame_host());
    108 
    109   ShellAddedObserver new_shell_observer;
    110   EXPECT_TRUE(ExecuteScript(shell()->web_contents(), "window.open();"));
    111   Shell* new_shell = new_shell_observer.GetShell();
    112   FrameTreeNode* new_root = static_cast<WebContentsImpl*>(
    113       new_shell->web_contents())->GetFrameTree()->root();
    114 
    115   EXPECT_TRUE(new_root->current_frame_host());
    116   EXPECT_NE(old_root->current_frame_host()->routing_id(),
    117             new_root->current_frame_host()->routing_id());
    118 }
    119 
    120 IN_PROC_BROWSER_TEST_F(RenderViewHostTest, IsFocusedElementEditable) {
    121   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    122 
    123   GURL test_url = embedded_test_server()->GetURL("/touch_selection.html");
    124   NavigateToURL(shell(), test_url);
    125 
    126   RenderViewHost* rvh = shell()->web_contents()->GetRenderViewHost();
    127   EXPECT_FALSE(rvh->IsFocusedElementEditable());
    128   EXPECT_TRUE(ExecuteScript(shell()->web_contents(), "focus_textfield();"));
    129   EXPECT_TRUE(rvh->IsFocusedElementEditable());
    130 }
    131 
    132 IN_PROC_BROWSER_TEST_F(RenderViewHostTest, ReleaseSessionOnCloseACK) {
    133   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    134   GURL test_url = embedded_test_server()->GetURL(
    135       "/access-session-storage.html");
    136   NavigateToURL(shell(), test_url);
    137 
    138   // Make a new Shell, a seperate tab with it's own session namespace and
    139   // have it start loading a url but still be in progress.
    140   ShellAddedObserver new_shell_observer;
    141   EXPECT_TRUE(ExecuteScript(shell()->web_contents(), "window.open();"));
    142   Shell* new_shell = new_shell_observer.GetShell();
    143   new_shell->LoadURL(test_url);
    144   RenderViewHost* rvh = new_shell->web_contents()->GetRenderViewHost();
    145   SiteInstance* site_instance = rvh->GetSiteInstance();
    146   scoped_refptr<SessionStorageNamespace> session_namespace =
    147       rvh->GetDelegate()->GetSessionStorageNamespace(site_instance);
    148   EXPECT_FALSE(session_namespace->HasOneRef());
    149 
    150   // Close it, or rather start the close operation. The session namespace
    151   // should remain until RPH gets an ACK from the renderer about having
    152   // closed the view.
    153   new_shell->Close();
    154   EXPECT_FALSE(session_namespace->HasOneRef());
    155 
    156   // Do something that causes ipc queues to flush and tasks in
    157   // flight to complete such that we should have received the ACK.
    158   NavigateToURL(shell(), test_url);
    159 
    160   // Verify we have the only remaining reference to the namespace.
    161   EXPECT_TRUE(session_namespace->HasOneRef());
    162 }
    163 
    164 }  // namespace content
    165