// 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/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 "third_party/blink/public/common/page/page_zoom.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 + blink::PageZoomFactorToZoomLevel(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 + blink::PageZoomFactorToZoomLevel(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 + blink::PageZoomFactorToZoomLevel(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));

  // 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));
}

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 +
        blink::PageZoomFactorToZoomLevel(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 + blink::PageZoomFactorToZoomLevel(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 + blink::PageZoomFactorToZoomLevel(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
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,
      blink::PageZoomFactorToZoomLevel(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);
}

// 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
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 + blink::PageZoomFactorToZoomLevel(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);
}

}  // namespace content
