// Copyright 2016 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 <vector>

#include "base/strings/string_util.h"
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/host_zoom_map.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
#include "content/public/common/page_zoom.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/shell/browser/shell.h"
#include "content/test/content_browser_test_utils_internal.h"
#include "net/dns/mock_host_resolver.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

namespace content {

// This class contains basic tests of zoom functionality.
class ZoomBrowserTest : public ContentBrowserTest {
 public:
  ZoomBrowserTest() {}

 protected:
  void SetUpOnMainThread() override {
    host_resolver()->AddRule("*", "127.0.0.1");
    SetupCrossSiteRedirector(embedded_test_server());
    ASSERT_TRUE(embedded_test_server()->Start());
  }

  WebContentsImpl* web_contents() {
    return static_cast<WebContentsImpl*>(shell()->web_contents());
  }
};


// This class contains tests to make sure that subframes zoom in a manner
// consistent with the top-level frame, even when the subframes are cross-site.
// Particular things we want to make sure of:
//
// * Subframes should always have the same zoom level as their main frame, even
// if the subframe's domain has a different zoom level stored in HostZoomMap.
//
// * The condition above should continue to hold after a navigation of the
// subframe.
//
// * Zoom changes applied to the mainframe should propagate to all subframes,
// regardless of whether they are same site or cross-site to the frame they are
// children of.
//
// The tests in this file rely on the notion that, when a page zooms, that
// subframes have both (1) a change in their frame rect, and (2) a change in
// their frame's scale. Since the page should scale as a unit, this means the
// innerWidth value of any subframe should be the same before and after the
// zoom (though it may transiently take on a different value). The
// FrameSizeObserver serves to watch for onresize events, and observes when
// the innerWidth is correctly set.
class IFrameZoomBrowserTest : public ContentBrowserTest {
 public:
  IFrameZoomBrowserTest() {}

 protected:
  void SetUpOnMainThread() override {
    host_resolver()->AddRule("*", "127.0.0.1");
    SetupCrossSiteRedirector(embedded_test_server());
    ASSERT_TRUE(embedded_test_server()->Start());
  }

  WebContentsImpl* web_contents() {
    return static_cast<WebContentsImpl*>(shell()->web_contents());
  }
};

namespace {

const double kTolerance = 0.1;  // In CSS pixels.

double GetMainframeWindowBorder(const ToRenderFrameHost& adapter) {
  double border;
  const char kGetMainframeBorder[] = "window.domAutomationController.send("
      "window.outerWidth - window.innerWidth"
      ");";
  EXPECT_TRUE(
      ExecuteScriptAndExtractDouble(adapter, kGetMainframeBorder, &border));
  return border;
}

double GetMainFrameZoomFactor(const ToRenderFrameHost& adapter, double border) {
  double zoom_factor;
  EXPECT_TRUE(ExecuteScriptAndExtractDouble(
      adapter,
      JsReplace("window.domAutomationController.send("
                "   (window.outerWidth - $1) / window.innerWidth);",
                border),
      &zoom_factor));
  return zoom_factor;
}

double GetSubframeWidth(const ToRenderFrameHost& adapter) {
  double width;
  EXPECT_TRUE(ExecuteScriptAndExtractDouble(
      adapter, "window.domAutomationController.send(window.innerWidth);",
      &width));
  return width;
}

// This struct is used to track changes to subframes after a main frame zoom
// change, so that we can test subframe inner widths with assurance that all the
// changes have finished propagating.
struct FrameResizeObserver {
  FrameResizeObserver(RenderFrameHost* host,
                      std::string label,
                      double inner_width,
                      double tolerance)
      : frame_host(host),
        msg_label(std::move(label)),
        zoomed_correctly(false),
        expected_inner_width(inner_width),
        tolerance(tolerance) {
    SetupOnResizeCallback(host, msg_label);
  }

  void SetupOnResizeCallback(const ToRenderFrameHost& adapter,
                             const std::string& label) {
    const char kOnResizeCallbackSetup[] =
        "document.body.onresize = function(){"
        "  window.domAutomationController.send('%s ' + window.innerWidth);"
        "};";
    EXPECT_TRUE(ExecuteScript(
        adapter, base::StringPrintf(kOnResizeCallbackSetup, label.c_str())));
  }

  void Check(const std::string& status_msg) {
    if (!base::StartsWith(status_msg, msg_label, base::CompareCase::SENSITIVE))
      return;

    double inner_width = std::stod(status_msg.substr(msg_label.length() + 1));
    zoomed_correctly = std::abs(expected_inner_width - inner_width) < tolerance;
  }

  FrameResizeObserver* toThis() {return this;}

  RenderFrameHost* frame_host;
  std::string msg_label;
  bool zoomed_correctly;
  double expected_inner_width;
  double tolerance;
};

// This struct is used to wait until a resize has occurred.
struct ResizeObserver {
  ResizeObserver(RenderFrameHost* host)
      : frame_host(host) {
    SetupOnResizeCallback(host);
  }

  void SetupOnResizeCallback(const ToRenderFrameHost& adapter) {
    const char kOnResizeCallbackSetup[] =
        "document.body.onresize = function(){"
        "  window.domAutomationController.send('Resized');"
        "};";
    EXPECT_TRUE(ExecuteScript(
        adapter, kOnResizeCallbackSetup));
  }

  bool IsResizeCallback(const std::string& status_msg) {
    return status_msg == "Resized";
  }

  RenderFrameHost* frame_host;
};

void WaitForResize(DOMMessageQueue& msg_queue, ResizeObserver& observer) {
  std::string status;
  while (msg_queue.WaitForMessage(&status)) {
    // Strip the double quotes from the message.
    status = status.substr(1, status.length() -2);
    if (observer.IsResizeCallback(status))
      break;
  }
}

void WaitAndCheckFrameZoom(
    DOMMessageQueue& msg_queue,
    std::vector<FrameResizeObserver>& frame_observers) {
  std::string status;
  while (msg_queue.WaitForMessage(&status)) {
    // Strip the double quotes from the message.
    status = status.substr(1, status.length() -2);

    bool all_zoomed_correctly = true;

    // Use auto& to operate on a reference, and not a copy.
    for (auto& observer : frame_observers) {
      observer.Check(status);
      all_zoomed_correctly = all_zoomed_correctly && observer.zoomed_correctly;
    }

    if (all_zoomed_correctly)
      break;
  }
}

}  // namespace

IN_PROC_BROWSER_TEST_F(ZoomBrowserTest, ZoomPreservedOnReload) {
  std::string top_level_host("a.com");

  GURL main_url(embedded_test_server()->GetURL(
      top_level_host, "/cross_site_iframe_factory.html?a(b(a))"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  NavigationEntry* entry =
      web_contents()->GetController().GetLastCommittedEntry();
  ASSERT_TRUE(entry);
  GURL loaded_url = HostZoomMap::GetURLFromEntry(entry);
  EXPECT_EQ(top_level_host, loaded_url.host());

  FrameTreeNode* root =
      static_cast<WebContentsImpl*>(web_contents())->GetFrameTree()->root();
  double main_frame_window_border = GetMainframeWindowBorder(web_contents());

  HostZoomMap* host_zoom_map = HostZoomMap::GetForWebContents(web_contents());
  double default_zoom_level = host_zoom_map->GetDefaultZoomLevel();
  EXPECT_EQ(0.0, default_zoom_level);

  EXPECT_DOUBLE_EQ(
      1.0, GetMainFrameZoomFactor(web_contents(), main_frame_window_border));

  const double new_zoom_factor = 2.5;

  // Set the new zoom, wait for the page to be resized, and sanity-check that
  // the zoom was applied.
  {
    DOMMessageQueue msg_queue;
    ResizeObserver observer(root->current_frame_host());

    const double new_zoom_level =
        default_zoom_level + ZoomFactorToZoomLevel(new_zoom_factor);
    host_zoom_map->SetZoomLevelForHost(top_level_host, new_zoom_level);

    WaitForResize(msg_queue, observer);
  }

  // Make this comparison approximate for Nexus5X test;
  // https://crbug.com/622858.
  EXPECT_NEAR(
      new_zoom_factor,
      GetMainFrameZoomFactor(web_contents(), main_frame_window_border),
      0.01);

  // Now the actual test: Reload the page and check that the main frame is
  // still properly zoomed.
  WindowedNotificationObserver load_stop_observer(
      NOTIFICATION_LOAD_STOP,
      NotificationService::AllSources());
  shell()->Reload();
  load_stop_observer.Wait();

  EXPECT_NEAR(
      new_zoom_factor,
      GetMainFrameZoomFactor(web_contents(), main_frame_window_border),
      0.01);
}

IN_PROC_BROWSER_TEST_F(IFrameZoomBrowserTest, SubframesZoomProperly) {
  std::string top_level_host("a.com");
  GURL main_url(embedded_test_server()->GetURL(
      top_level_host, "/cross_site_iframe_factory.html?a(b(a))"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  NavigationEntry* entry =
      web_contents()->GetController().GetLastCommittedEntry();
  ASSERT_TRUE(entry);
  GURL loaded_url = HostZoomMap::GetURLFromEntry(entry);
  EXPECT_EQ(top_level_host, loaded_url.host());

  FrameTreeNode* root =
      static_cast<WebContentsImpl*>(web_contents())->GetFrameTree()->root();
  RenderFrameHostImpl* child = root->child_at(0)->current_frame_host();
  RenderFrameHostImpl* grandchild =
      root->child_at(0)->child_at(0)->current_frame_host();

  // The following calls must be made when the page's scale factor = 1.0.
  double scale_one_child_width = GetSubframeWidth(child);
  double scale_one_grandchild_width = GetSubframeWidth(grandchild);
  double main_frame_window_border = GetMainframeWindowBorder(web_contents());

  HostZoomMap* host_zoom_map = HostZoomMap::GetForWebContents(web_contents());
  double default_zoom_level = host_zoom_map->GetDefaultZoomLevel();
  EXPECT_EQ(0.0, default_zoom_level);

  EXPECT_DOUBLE_EQ(
      1.0, GetMainFrameZoomFactor(web_contents(), main_frame_window_border));

  const double new_zoom_factor = 2.5;
  {
    DOMMessageQueue msg_queue;

    std::vector<FrameResizeObserver> frame_observers;
    frame_observers.emplace_back(child, "child",
                                 scale_one_child_width, kTolerance);
    frame_observers.emplace_back(grandchild, "grandchild",
                                 scale_one_grandchild_width, kTolerance);

    const double new_zoom_level =
        default_zoom_level + ZoomFactorToZoomLevel(new_zoom_factor);
    host_zoom_map->SetZoomLevelForHost(top_level_host, new_zoom_level);

    WaitAndCheckFrameZoom(msg_queue, frame_observers);
  }

  // Make this comparison approximate for Nexus5X test;
  // https://crbug.com/622858.
  EXPECT_NEAR(
      new_zoom_factor,
      GetMainFrameZoomFactor(web_contents(), main_frame_window_border),
      0.01);
}

IN_PROC_BROWSER_TEST_F(IFrameZoomBrowserTest, SubframesDontZoomIndependently) {
  std::string top_level_host("a.com");
  GURL main_url(embedded_test_server()->GetURL(
      top_level_host, "/cross_site_iframe_factory.html?a(b(a))"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  NavigationEntry* entry =
      web_contents()->GetController().GetLastCommittedEntry();
  ASSERT_TRUE(entry);
  GURL loaded_url = HostZoomMap::GetURLFromEntry(entry);
  EXPECT_EQ(top_level_host, loaded_url.host());

  FrameTreeNode* root =
      static_cast<WebContentsImpl*>(web_contents())->GetFrameTree()->root();
  RenderFrameHostImpl* child = root->child_at(0)->current_frame_host();
  RenderFrameHostImpl* grandchild =
      root->child_at(0)->child_at(0)->current_frame_host();

  // The following calls must be made when the page's scale factor = 1.0.
  double scale_one_child_width = GetSubframeWidth(child);
  double scale_one_grandchild_width = GetSubframeWidth(grandchild);
  double main_frame_window_border = GetMainframeWindowBorder(web_contents());

  HostZoomMap* host_zoom_map = HostZoomMap::GetForWebContents(web_contents());
  double default_zoom_level = host_zoom_map->GetDefaultZoomLevel();
  EXPECT_EQ(0.0, default_zoom_level);

  EXPECT_DOUBLE_EQ(
      1.0, GetMainFrameZoomFactor(web_contents(), main_frame_window_border));

  const double new_zoom_factor = 2.0;
  const double new_zoom_level =
      default_zoom_level + ZoomFactorToZoomLevel(new_zoom_factor);

  // This should not cause the nested iframe to change its zoom.
  host_zoom_map->SetZoomLevelForHost("b.com", new_zoom_level);

  EXPECT_DOUBLE_EQ(
      1.0, GetMainFrameZoomFactor(web_contents(), main_frame_window_border));
  EXPECT_EQ(scale_one_child_width, GetSubframeWidth(child));
  EXPECT_EQ(scale_one_grandchild_width, GetSubframeWidth(grandchild));

  // We exclude the remainder of this test on Android since Android does not
  // set page zoom levels for loading pages.
  // See RenderFrameImpl::SetHostZoomLevel().
#if !defined(OS_ANDROID)
  // When we navigate so that b.com is the top-level site, then it has the
  // expected zoom.
  GURL new_url = embedded_test_server()->GetURL("b.com", "/title1.html");
  EXPECT_TRUE(NavigateToURL(shell(), new_url));
  EXPECT_DOUBLE_EQ(
      new_zoom_factor,
      GetMainFrameZoomFactor(web_contents(), main_frame_window_border));
#endif
}

IN_PROC_BROWSER_TEST_F(IFrameZoomBrowserTest, AllFramesGetDefaultZoom) {
  std::string top_level_host("a.com");
  GURL main_url(embedded_test_server()->GetURL(
      top_level_host, "/cross_site_iframe_factory.html?a(b(a))"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  NavigationEntry* entry =
      web_contents()->GetController().GetLastCommittedEntry();
  ASSERT_TRUE(entry);
  GURL loaded_url = HostZoomMap::GetURLFromEntry(entry);
  EXPECT_EQ(top_level_host, loaded_url.host());

  FrameTreeNode* root =
      static_cast<WebContentsImpl*>(web_contents())->GetFrameTree()->root();
  RenderFrameHostImpl* child = root->child_at(0)->current_frame_host();
  RenderFrameHostImpl* grandchild =
      root->child_at(0)->child_at(0)->current_frame_host();

  // The following calls must be made when the page's scale factor = 1.0.
  double scale_one_child_width = GetSubframeWidth(child);
  double scale_one_grandchild_width = GetSubframeWidth(grandchild);
  double main_frame_window_border = GetMainframeWindowBorder(web_contents());

  HostZoomMap* host_zoom_map = HostZoomMap::GetForWebContents(web_contents());
  double default_zoom_level = host_zoom_map->GetDefaultZoomLevel();
  EXPECT_EQ(0.0, default_zoom_level);

  EXPECT_DOUBLE_EQ(
      1.0, GetMainFrameZoomFactor(web_contents(), main_frame_window_border));

  const double new_default_zoom_factor = 2.0;
  {
    DOMMessageQueue msg_queue;

    std::vector<FrameResizeObserver> frame_observers;
    frame_observers.emplace_back(child, "child",
                                 scale_one_child_width, kTolerance);
    frame_observers.emplace_back(grandchild, "grandchild",
                                 scale_one_grandchild_width, kTolerance);

    const double new_default_zoom_level =
        default_zoom_level + ZoomFactorToZoomLevel(new_default_zoom_factor);

    host_zoom_map->SetZoomLevelForHost("b.com", new_default_zoom_level + 1.0);
    host_zoom_map->SetDefaultZoomLevel(new_default_zoom_level);

    WaitAndCheckFrameZoom(msg_queue, frame_observers);
  }
  // Make this comparison approximate for Nexus5X test;
  // https://crbug.com/622858.
  EXPECT_NEAR(
      new_default_zoom_factor,
      GetMainFrameZoomFactor(web_contents(), main_frame_window_border),
      0.01
  );
}

IN_PROC_BROWSER_TEST_F(IFrameZoomBrowserTest, SiblingFramesZoom) {
  std::string top_level_host("a.com");
  GURL main_url(embedded_test_server()->GetURL(
      top_level_host, "/cross_site_iframe_factory.html?a(b,b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  NavigationEntry* entry =
      web_contents()->GetController().GetLastCommittedEntry();
  ASSERT_TRUE(entry);
  GURL loaded_url = HostZoomMap::GetURLFromEntry(entry);
  EXPECT_EQ(top_level_host, loaded_url.host());

  FrameTreeNode* root =
      static_cast<WebContentsImpl*>(web_contents())->GetFrameTree()->root();
  RenderFrameHostImpl* child1 = root->child_at(0)->current_frame_host();
  RenderFrameHostImpl* child2 = root->child_at(1)->current_frame_host();

  // The following calls must be made when the page's scale factor = 1.0.
  double scale_one_child1_width = GetSubframeWidth(child1);
  double scale_one_child2_width = GetSubframeWidth(child2);
  double main_frame_window_border = GetMainframeWindowBorder(web_contents());

  HostZoomMap* host_zoom_map = HostZoomMap::GetForWebContents(web_contents());
  double default_zoom_level = host_zoom_map->GetDefaultZoomLevel();
  EXPECT_EQ(0.0, default_zoom_level);

  EXPECT_DOUBLE_EQ(
      1.0, GetMainFrameZoomFactor(web_contents(), main_frame_window_border));

  const double new_zoom_factor = 2.5;
  {
    DOMMessageQueue msg_queue;

    std::vector<FrameResizeObserver> frame_observers;
    frame_observers.emplace_back(child1, "child1",
                                 scale_one_child1_width, kTolerance);
    frame_observers.emplace_back(child2, "child2",
                                 scale_one_child2_width, kTolerance);

    const double new_zoom_level =
        default_zoom_level + ZoomFactorToZoomLevel(new_zoom_factor);
    host_zoom_map->SetZoomLevelForHost(top_level_host, new_zoom_level);

    WaitAndCheckFrameZoom(msg_queue, frame_observers);
  }

  // Make this comparison approximate for Nexus5X test;
  // https://crbug.com/622858.
  EXPECT_NEAR(
      new_zoom_factor,
      GetMainFrameZoomFactor(web_contents(), main_frame_window_border),
      0.01);
}

IN_PROC_BROWSER_TEST_F(IFrameZoomBrowserTest, SubframeRetainsZoomOnNavigation) {
  std::string top_level_host("a.com");
  GURL main_url(embedded_test_server()->GetURL(
      top_level_host, "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  NavigationEntry* entry =
      web_contents()->GetController().GetLastCommittedEntry();
  ASSERT_TRUE(entry);
  GURL loaded_url = HostZoomMap::GetURLFromEntry(entry);
  EXPECT_EQ(top_level_host, loaded_url.host());

  FrameTreeNode* root =
      static_cast<WebContentsImpl*>(web_contents())->GetFrameTree()->root();
  RenderFrameHostImpl* child = root->child_at(0)->current_frame_host();

  // The following calls must be made when the page's scale factor = 1.0.
  double scale_one_child_width = GetSubframeWidth(child);
  double main_frame_window_border = GetMainframeWindowBorder(web_contents());

  HostZoomMap* host_zoom_map = HostZoomMap::GetForWebContents(web_contents());
  double default_zoom_level = host_zoom_map->GetDefaultZoomLevel();
  EXPECT_EQ(0.0, default_zoom_level);

  EXPECT_DOUBLE_EQ(
      1.0, GetMainFrameZoomFactor(web_contents(), main_frame_window_border));

  const double new_zoom_factor = 0.5;
  {
    DOMMessageQueue msg_queue;

    std::vector<FrameResizeObserver> frame_observers;
    frame_observers.emplace_back(child, "child",
                                 scale_one_child_width, kTolerance);

    const double new_zoom_level =
        default_zoom_level + ZoomFactorToZoomLevel(new_zoom_factor);
    host_zoom_map->SetZoomLevelForHost(top_level_host, new_zoom_level);

    WaitAndCheckFrameZoom(msg_queue, frame_observers);
  }

  // Make this comparison approximate for Nexus5X test;
  // https://crbug.com/622858.
  EXPECT_NEAR(
      new_zoom_factor,
      GetMainFrameZoomFactor(web_contents(), main_frame_window_border),
      0.01
  );

  // Navigate child frame cross site, and make sure zoom is the same.
  TestNavigationObserver observer(web_contents());
  GURL url = embedded_test_server()->GetURL("c.com", "/title1.html");
  NavigateFrameToURL(root->child_at(0), url);
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(url, observer.last_navigation_url());

  // Check that the child frame maintained the same scale after navigating
  // cross-site.
  double new_child_width =
      GetSubframeWidth(root->child_at(0)->current_frame_host());
  EXPECT_EQ(scale_one_child_width, new_child_width);
}

// http://crbug.com/609213
#if !defined(OS_ANDROID)
IN_PROC_BROWSER_TEST_F(IFrameZoomBrowserTest,
                       RedirectToPageWithSubframeZoomsCorrectly) {
  std::string initial_host("a.com");
  std::string redirected_host("b.com");
  EXPECT_TRUE(NavigateToURL(shell(), GURL(embedded_test_server()->GetURL(
                                         initial_host, "/title2.html"))));
  double main_frame_window_border = GetMainframeWindowBorder(web_contents());
  EXPECT_DOUBLE_EQ(
      1.0, GetMainFrameZoomFactor(web_contents(), main_frame_window_border));

  // Set a zoom level for b.com before we navigate to it.
  const double kZoomFactorForRedirectedHost = 1.5;
  HostZoomMap* host_zoom_map = HostZoomMap::GetForWebContents(web_contents());
  host_zoom_map->SetZoomLevelForHost(
      redirected_host, ZoomFactorToZoomLevel(kZoomFactorForRedirectedHost));

  // Navigation to a.com doesn't change the zoom level, but when it redirects
  // to b.com, and then a subframe loads, the zoom should change.
  GURL redirect_url(embedded_test_server()->GetURL(
      redirected_host, "/cross_site_iframe_factory.html?b(b)"));
  GURL url(embedded_test_server()->GetURL(
      initial_host, "/client-redirect?" + redirect_url.spec()));

  NavigateToURLBlockUntilNavigationsComplete(shell(), url, 2);
  EXPECT_TRUE(IsLastCommittedEntryOfPageType(web_contents(), PAGE_TYPE_NORMAL));
  EXPECT_EQ(redirect_url, web_contents()->GetLastCommittedURL());

  EXPECT_NEAR(kZoomFactorForRedirectedHost,
              GetMainFrameZoomFactor(web_contents(), main_frame_window_border),
              0.01);
}
#endif

// Tests that on cross-site navigation from a page that has a subframe, the
// appropriate zoom is applied to the new page.
// crbug.com/673065
// Note: We exclude the this test on Android since Android does not set page
// zoom levels for loading pages.
// See RenderFrameImpl::SetHostZoomLevel().
#if !defined(OS_ANDROID)
IN_PROC_BROWSER_TEST_F(IFrameZoomBrowserTest,
                       SubframesDontBreakConnectionToRenderer) {
  std::string top_level_host("a.com");
  GURL main_url(embedded_test_server()->GetURL(
      top_level_host, "/page_with_iframe_and_link.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  NavigationEntry* entry =
      web_contents()->GetController().GetLastCommittedEntry();
  ASSERT_TRUE(entry);
  GURL loaded_url = HostZoomMap::GetURLFromEntry(entry);
  EXPECT_EQ(top_level_host, loaded_url.host());

  // The following calls must be made when the page's scale factor = 1.0.
  double main_frame_window_border = GetMainframeWindowBorder(web_contents());

  HostZoomMap* host_zoom_map = HostZoomMap::GetForWebContents(web_contents());
  double default_zoom_level = host_zoom_map->GetDefaultZoomLevel();
  EXPECT_EQ(0.0, default_zoom_level);
  EXPECT_DOUBLE_EQ(
      1.0, GetMainFrameZoomFactor(web_contents(), main_frame_window_border));

  // Set a zoom for a host that will be navigated to below.
  const double new_zoom_factor = 2.0;
  const double new_zoom_level =
      default_zoom_level + ZoomFactorToZoomLevel(new_zoom_factor);
  host_zoom_map->SetZoomLevelForHost("foo.com", new_zoom_level);

  // Navigate forward in the same RFH to a site with that host via a
  // renderer-initiated navigation.
  {
    const char kReplacePortNumber[] =
        "window.domAutomationController.send(setPortNumber(%d));";
    uint16_t port_number = embedded_test_server()->port();
    bool success = false;
    EXPECT_TRUE(ExecuteScriptAndExtractBool(
        shell(), base::StringPrintf(kReplacePortNumber, port_number),
        &success));
    TestNavigationObserver observer(shell()->web_contents());
    GURL url = embedded_test_server()->GetURL("foo.com", "/title2.html");
    success = false;
    EXPECT_TRUE(ExecuteScriptAndExtractBool(
        shell(), "window.domAutomationController.send(clickCrossSiteLink());",
        &success));
    EXPECT_TRUE(success);
    EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
    EXPECT_EQ(url, observer.last_navigation_url());
    EXPECT_TRUE(observer.last_navigation_succeeded());
  }

  // Check that the requested zoom has been applied to the new site.
  // NOTE: Local observation on Linux has shown that this comparison has to be
  // approximate. As the common failure mode would be that the zoom is ~1
  // instead of ~2, this approximation shouldn't be problematic.
  EXPECT_NEAR(
      new_zoom_factor,
      GetMainFrameZoomFactor(web_contents(), main_frame_window_border),
      .1);
}
#endif

}  // namespace content
