// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <fuchsia/element/cpp/fidl.h>
#include <lib/ui/scenic/cpp/view_token_pair.h>
#include <lib/zx/time.h>

#include "base/fuchsia/fuchsia_logging.h"
#include "base/fuchsia/mem_buffer_util.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/test_future.h"
#include "base/test/test_timeouts.h"
#include "build/build_config.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/test_utils.h"
#include "fuchsia_web/common/string_util.h"
#include "fuchsia_web/common/test/fit_adapter.h"
#include "fuchsia_web/common/test/frame_for_test.h"
#include "fuchsia_web/common/test/frame_test_util.h"
#include "fuchsia_web/common/test/test_navigation_listener.h"
#include "fuchsia_web/webengine/browser/context_impl.h"
#include "fuchsia_web/webengine/browser/fake_semantics_manager.h"
#include "fuchsia_web/webengine/browser/frame_impl.h"
#include "fuchsia_web/webengine/browser/frame_impl_browser_test_base.h"
#include "net/test/embedded_test_server/request_handler_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/ozone/public/ozone_platform.h"

using testing::_;
using testing::AllOf;
using testing::AtLeast;
using testing::Contains;
using testing::Field;
using testing::InvokeWithoutArgs;
using testing::Key;
using testing::Mock;
using testing::Not;

// Use a shorter name for NavigationState, because it is referenced frequently
// in this file.
using NavigationDetails = fuchsia::web::NavigationState;
using OnNavigationStateChangedCallback =
    fuchsia::web::NavigationEventListener::OnNavigationStateChangedCallback;

namespace {

constexpr char kPage1Path[] = "/title1.html";
constexpr char kPage2Path[] = "/title2.html";
constexpr char kPage3Path[] = "/websql.html";
constexpr char kReportCloseEventsPath[] = "/report_close_events.html";
constexpr char kVisibilityPath[] = "/visibility.html";
constexpr char kWaitSizePath[] = "/wait-size.html";
constexpr char kPage1Title[] = "title 1";
constexpr char kPage2Title[] = "title 2";
constexpr char kPage3Title[] = "websql not available";
constexpr char kDataUrl[] =
    "data:text/html;base64,PGI+SGVsbG8sIHdvcmxkLi4uPC9iPg==";

MATCHER_P(NavigationHandleUrlEquals,
          url,
          "Checks equality with a NavigationHandle's URL.") {
  return arg->GetURL() == url;
}

class MockWebContentsObserver : public content::WebContentsObserver {
 public:
  explicit MockWebContentsObserver(content::WebContents* web_contents) {
    Observe(web_contents);
  }

  ~MockWebContentsObserver() override = default;

  MOCK_METHOD1(DidStartNavigation, void(content::NavigationHandle*));

  MOCK_METHOD1(RenderViewDeleted,
               void(content::RenderViewHost* render_view_host));
};

std::string GetDocumentVisibilityState(fuchsia::web::Frame* frame) {
  auto visibility = base::MakeRefCounted<base::RefCountedData<std::string>>();
  base::RunLoop loop;
  frame->ExecuteJavaScript(
      {"*"}, base::MemBufferFromString("document.visibilityState;", "test"),
      [visibility, quit_loop = loop.QuitClosure()](
          fuchsia::web::Frame_ExecuteJavaScript_Result result) {
        ASSERT_TRUE(result.is_response());
        visibility->data = *base::StringFromMemBuffer(result.response().result);
        quit_loop.Run();
      });
  loop.Run();
  return visibility->data;
}

::fuchsia::ui::views::ViewRef CloneViewRef(
    const ::fuchsia::ui::views::ViewRef& view_ref) {
  ::fuchsia::ui::views::ViewRef dup;
  zx_status_t status =
      view_ref.reference.duplicate(ZX_RIGHT_SAME_RIGHTS, &dup.reference);
  ZX_CHECK(status == ZX_OK, status) << "zx_object_duplicate";
  return dup;
}

}  // namespace

// Defines a suite of tests that exercise Frame-level functionality, such as
// navigation commands and page events.
class FrameImplTest : public FrameImplTestBase {
 public:
  FrameImplTest() = default;
  ~FrameImplTest() override = default;

  FrameImplTest(const FrameImplTest&) = delete;
  FrameImplTest& operator=(const FrameImplTest&) = delete;

  MOCK_METHOD1(OnServeHttpRequest,
               void(const net::test_server::HttpRequest& request));
};

// Verifies that Frames are initially "hidden", changes to "visible" once the
// View is attached to a Presenter and back to "hidden" when the View is
// detached from the Presenter.
// TODO(crbug.com/1377994): Re-enable this test on Arm64 when femu is available
// for that architecture. This test requires Vulkan and Scenic to properly
// signal the Views visibility.
#if defined(ARCH_CPU_ARM_FAMILY)
#define MAYBE_VisibilityState DISABLED_VisibilityState
#else
#define MAYBE_VisibilityState VisibilityState
#endif
IN_PROC_BROWSER_TEST_F(FrameImplTest, MAYBE_VisibilityState) {
  // This test uses the `fuchsia.ui.gfx` variant of `Frame.CreateView*()`.
  ASSERT_EQ(ui::OzonePlatform::GetInstance()->GetPlatformNameForTest(),
            "scenic");

  net::test_server::EmbeddedTestServerHandle test_server_handle;
  ASSERT_TRUE(test_server_handle =
                  embedded_test_server()->StartAndReturnHandle());
  GURL page_url(embedded_test_server()->GetURL(kVisibilityPath));

  auto frame = FrameForTest::Create(context(), {});
  frame.ptr().set_error_handler([](zx_status_t status) {
    ZX_LOG(ERROR, status);
    ADD_FAILURE() << "Frame disconnected.";
  });
  base::RunLoop().RunUntilIdle();

  // Navigate to a page and wait for it to finish loading.
  ASSERT_TRUE(LoadUrlAndExpectResponse(frame.GetNavigationController(),
                                       fuchsia::web::LoadUrlParams(),
                                       page_url.spec()));
  frame.navigation_listener().RunUntilUrlEquals(page_url);

  // Query the document.visibilityState before creating a View.
  EXPECT_EQ(GetDocumentVisibilityState(frame.ptr().get()), "\"hidden\"");

  // Query the document.visibilityState after creating the View, but without it
  // actually "attached" to the view tree.
  auto view_tokens = scenic::ViewTokenPair::New();
  auto view_ref_pair = scenic::ViewRefPair::New();
  frame->CreateViewWithViewRef(std::move(view_tokens.view_token),
                               std::move(view_ref_pair.control_ref),
                               CloneViewRef(view_ref_pair.view_ref));

  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(GetDocumentVisibilityState(frame.ptr().get()), "\"hidden\"");

  // Attach the View to a Presenter, the page should be visible.
  auto presenter = base::ComponentContextForProcess()
                       ->svc()
                       ->Connect<::fuchsia::element::GraphicalPresenter>();
  presenter.set_error_handler([](zx_status_t status) {
    ZX_LOG(ERROR, status) << "GraphicalPresenter disconnected.";
    ADD_FAILURE();
  });
  ::fuchsia::element::ViewSpec view_spec;
  view_spec.set_view_holder_token(std::move(view_tokens.view_holder_token));
  view_spec.set_view_ref(std::move(view_ref_pair.view_ref));
  ::fuchsia::element::ViewControllerPtr view_controller;
  presenter->PresentView(std::move(view_spec), nullptr,
                         view_controller.NewRequest(),
                         [](auto result) { EXPECT_FALSE(result.is_err()); });
  frame.navigation_listener().RunUntilTitleEquals("visible");

  // Detach the ViewController, causing the View to be detached.
  // This is a regression test for crbug.com/1141093, verifying that the page
  // receives a "not visible" event as a result.
  view_controller->Dismiss();
  frame.navigation_listener().RunUntilTitleEquals("hidden");
}

// Verifies that the browser will navigate and generate a navigation listener
// event when LoadUrl() is called.
IN_PROC_BROWSER_TEST_F(FrameImplTest, NavigateFrame) {
  auto frame = FrameForTest::Create(context(), {});

  EXPECT_TRUE(LoadUrlAndExpectResponse(frame.GetNavigationController(),
                                       fuchsia::web::LoadUrlParams(),
                                       url::kAboutBlankURL));
  frame.navigation_listener().RunUntilUrlAndTitleEquals(
      GURL(url::kAboutBlankURL), url::kAboutBlankURL);
}

// Verifies that the browser does not crash if the Renderer process exits while
// a navigation event listener is attached to the Frame.
IN_PROC_BROWSER_TEST_F(FrameImplTest, NavigationListenerRendererProcessGone) {
  net::test_server::EmbeddedTestServerHandle test_server_handle;
  ASSERT_TRUE(test_server_handle =
                  embedded_test_server()->StartAndReturnHandle());
  GURL url(embedded_test_server()->GetURL("/nocontent"));

  // Create a Frame and navigate it to a URL that will not "commit".
  auto frame = FrameForTest::Create(context(), {});

  EXPECT_TRUE(LoadUrlAndExpectResponse(frame.GetNavigationController(),
                                       fuchsia::web::LoadUrlParams(),
                                       url.spec()));

  // Terminate the Renderer process and run the browser until that is observed.
  content::RenderProcessHost* child_process =
      context_impl()
          ->GetFrameImplForTest(&frame.ptr())
          ->web_contents()
          ->GetPrimaryMainFrame()
          ->GetProcess();

  content::RenderProcessHostWatcher(
      child_process, content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_READY)
      .Wait();
  ASSERT_TRUE(child_process->IsReady());

  content::RenderProcessHostWatcher exit_observer(
      child_process, content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  child_process->Shutdown(0);
  exit_observer.Wait();
  EXPECT_FALSE(exit_observer.did_exit_normally());

  // Spin the browser main loop to flush any queued work, or FIDL activity.
  base::RunLoop().RunUntilIdle();
}

// Verifies that the renderer process consumes more memory for document
// rendering.
IN_PROC_BROWSER_TEST_F(FrameImplTest, NavigationIncreasesMemoryUsage) {
  net::test_server::EmbeddedTestServerHandle test_server_handle;
  ASSERT_TRUE(test_server_handle =
                  embedded_test_server()->StartAndReturnHandle());
  GURL url(embedded_test_server()->GetURL(kPage1Path));

  auto frame = FrameForTest::Create(context(), {});

  // Get the renderer size when no renderer process is active.
  base::test::TestFuture<uint64_t> before_nav_size;
  frame->GetPrivateMemorySize(
      CallbackToFitFunction(before_nav_size.GetCallback()));

  EXPECT_TRUE(LoadUrlAndExpectResponse(frame.GetNavigationController(),
                                       fuchsia::web::LoadUrlParams(),
                                       url.spec()));
  frame.navigation_listener().RunUntilUrlAndTitleEquals(url, kPage1Title);

  base::test::TestFuture<uint64_t> after_nav_size;
  frame->GetPrivateMemorySize(
      CallbackToFitFunction(after_nav_size.GetCallback()));
  ASSERT_TRUE(after_nav_size.Wait());

  EXPECT_EQ(before_nav_size.Get(), 0u);  // No render process - zero bytes.
  EXPECT_GT(after_nav_size.Get(), 0u);
}

IN_PROC_BROWSER_TEST_F(FrameImplTest, NavigateDataFrame) {
  auto frame = FrameForTest::Create(context(), {});

  EXPECT_TRUE(LoadUrlAndExpectResponse(frame.GetNavigationController(),
                                       fuchsia::web::LoadUrlParams(),
                                       kDataUrl));
  frame.navigation_listener().RunUntilUrlAndTitleEquals(GURL(kDataUrl),
                                                        kDataUrl);
}

IN_PROC_BROWSER_TEST_F(FrameImplTest, FrameDeletedBeforeContext) {
  auto frame = FrameForTest::Create(context(), {});

  // Process the frame creation message.
  base::RunLoop().RunUntilIdle();

  FrameImpl* frame_impl = context_impl()->GetFrameImplForTest(&frame.ptr());
  MockWebContentsObserver deletion_observer(frame_impl->web_contents());
  base::RunLoop run_loop;
  EXPECT_CALL(deletion_observer, RenderViewDeleted(_))
      .WillOnce(InvokeWithoutArgs([&run_loop] { run_loop.Quit(); }));

  EXPECT_TRUE(LoadUrlAndExpectResponse(frame.GetNavigationController(),
                                       fuchsia::web::LoadUrlParams(),
                                       url::kAboutBlankURL));

  frame.ptr().Unbind();
  run_loop.Run();

  // Check that |context| remains bound after the frame is closed.
  EXPECT_TRUE(context());
}

IN_PROC_BROWSER_TEST_F(FrameImplTest, ContextDeletedBeforeFrame) {
  auto frame = FrameForTest::Create(context(), {});
  EXPECT_TRUE(frame.ptr());

  base::RunLoop run_loop;
  frame.ptr().set_error_handler([&run_loop](zx_status_t status) {
    EXPECT_EQ(status, ZX_ERR_PEER_CLOSED);
    run_loop.Quit();
  });
  context().Unbind();
  run_loop.Run();
  EXPECT_FALSE(frame.ptr());
}

IN_PROC_BROWSER_TEST_F(FrameImplTest, ContextDeletedBeforeFrameWithView) {
  auto frame = FrameForTest::Create(context(), {});
  EXPECT_TRUE(frame.ptr());
  base::RunLoop().RunUntilIdle();
  FrameImpl* frame_impl = context_impl()->GetFrameImplForTest(&frame.ptr());

  auto view_tokens = scenic::ViewTokenPair::New();
  frame->CreateView(std::move(view_tokens.view_token));
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(frame_impl->has_view_for_test());

  base::RunLoop run_loop;
  frame.ptr().set_error_handler([&run_loop](zx_status_t status) {
    EXPECT_EQ(status, ZX_ERR_PEER_CLOSED);
    run_loop.Quit();
  });
  context().Unbind();
  run_loop.Run();
  EXPECT_FALSE(frame.ptr());
}

// TODO(https://crbug.com/695592): Remove this test when WebSQL is removed from
// Chrome.
IN_PROC_BROWSER_TEST_F(FrameImplTest, EnsureWebSqlDisabled) {
  auto frame = FrameForTest::Create(context(), {});

  net::test_server::EmbeddedTestServerHandle test_server_handle;
  ASSERT_TRUE(test_server_handle =
                  embedded_test_server()->StartAndReturnHandle());
  GURL title3(embedded_test_server()->GetURL(kPage3Path));

  EXPECT_TRUE(LoadUrlAndExpectResponse(frame.GetNavigationController(),
                                       fuchsia::web::LoadUrlParams(),
                                       title3.spec()));
  frame.navigation_listener().RunUntilUrlAndTitleEquals(title3, kPage3Title);
}

namespace {

void VerifyCanGoBackAndForward(FrameForTest& frame,
                               bool can_go_back_expected,
                               bool can_go_forward_expected) {
  auto* state = frame.navigation_listener().current_state();
  EXPECT_TRUE(state->has_can_go_back());
  EXPECT_EQ(state->can_go_back(), can_go_back_expected);
  EXPECT_TRUE(state->has_can_go_forward());
  EXPECT_EQ(state->can_go_forward(), can_go_forward_expected);
}

}  // namespace

IN_PROC_BROWSER_TEST_F(FrameImplTest, GoBackAndForward) {
  auto frame = FrameForTest::Create(context(), {});

  net::test_server::EmbeddedTestServerHandle test_server_handle;
  ASSERT_TRUE(test_server_handle =
                  embedded_test_server()->StartAndReturnHandle());
  GURL title1(embedded_test_server()->GetURL(kPage1Path));
  GURL title2(embedded_test_server()->GetURL(kPage2Path));

  EXPECT_TRUE(LoadUrlAndExpectResponse(frame.GetNavigationController(),
                                       fuchsia::web::LoadUrlParams(),
                                       title1.spec()));
  frame.navigation_listener().RunUntilUrlTitleBackForwardEquals(
      title1, kPage1Title, false, false);

  EXPECT_TRUE(LoadUrlAndExpectResponse(frame.GetNavigationController(),
                                       fuchsia::web::LoadUrlParams(),
                                       title2.spec()));
  frame.navigation_listener().RunUntilUrlTitleBackForwardEquals(
      title2, kPage2Title, true, false);

  frame.GetNavigationController()->GoBack();
  frame.navigation_listener().RunUntilUrlTitleBackForwardEquals(
      title1, kPage1Title, false, true);

  // At the top of the navigation entry list; this should be a no-op.
  frame.GetNavigationController()->GoBack();

  // Process the navigation request message.
  base::RunLoop().RunUntilIdle();

  // Verify that the can-go-back/forward state has not changed.
  VerifyCanGoBackAndForward(frame, false, true);

  frame.GetNavigationController()->GoForward();
  frame.navigation_listener().RunUntilUrlTitleBackForwardEquals(
      title2, kPage2Title, true, false);

  // At the end of the navigation entry list; this should be a no-op.
  frame.GetNavigationController()->GoForward();

  // Process the navigation request message.
  base::RunLoop().RunUntilIdle();

  // Back/forward state should not have changed, since the request was a
  // no-op.
  VerifyCanGoBackAndForward(frame, true, false);
}

namespace {

// An HTTP response stream whose response payload can be sent as "chunks"
// with indeterminate-length pauses in between.
class ChunkedHttpTransaction {
 public:
  explicit ChunkedHttpTransaction(
      base::WeakPtr<net::test_server::HttpResponseDelegate> delegate)
      : io_task_runner_(base::SingleThreadTaskRunner::GetCurrentDefault()),
        send_state_(SendState::IDLE),
        delegate_(delegate) {
    EXPECT_FALSE(current_instance_);

    current_instance_ = this;
  }

  ChunkedHttpTransaction(const ChunkedHttpTransaction&) = delete;
  ChunkedHttpTransaction& operator=(const ChunkedHttpTransaction&) = delete;

  static ChunkedHttpTransaction* current() {
    EXPECT_TRUE(current_instance_);
    return current_instance_;
  }

  void Close() {
    EnsureSendCompleted();
    io_task_runner_->PostTask(
        FROM_HERE,
        base::BindOnce(&net::test_server::HttpResponseDelegate::FinishResponse,
                       delegate_));
    delete this;
  }

  void EnsureSendCompleted() {
    if (send_state_ == SendState::IDLE)
      return;

    base::RunLoop run_loop;
    send_chunk_complete_callback_ = run_loop.QuitClosure();
    run_loop.Run();
    EXPECT_EQ(send_state_, SendState::IDLE);
  }

  void SendChunk(const std::string& chunk) {
    EnsureSendCompleted();

    send_state_ = SendState::BLOCKED;

    io_task_runner_->PostTask(
        FROM_HERE,
        base::BindOnce(
            &net::test_server::HttpResponseDelegate::SendContents, delegate_,
            chunk,
            base::BindOnce(&ChunkedHttpTransaction::SendChunkCompleteOnIoThread,
                           base::Unretained(this),
                           base::SingleThreadTaskRunner::GetCurrentDefault())));
  }

 private:
  static ChunkedHttpTransaction* current_instance_;

  ~ChunkedHttpTransaction() { current_instance_ = nullptr; }

  void SendChunkCompleteOnIoThread(
      scoped_refptr<base::TaskRunner> ui_thread_task_runner) {
    ui_thread_task_runner->PostTask(
        FROM_HERE,
        base::BindOnce(&ChunkedHttpTransaction::SendChunkCompleteOnUiThread,
                       base::Unretained(this)));
  }

  void SendChunkCompleteOnUiThread() {
    send_state_ = SendState::IDLE;
    if (send_chunk_complete_callback_)
      std::move(send_chunk_complete_callback_).Run();
  }

  scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;

  // Set by callers to SendChunk() waiting for the previous chunk to complete.
  base::OnceClosure send_chunk_complete_callback_;

  enum SendState { IDLE, BLOCKED };

  SendState send_state_;
  base::WeakPtr<net::test_server::HttpResponseDelegate> delegate_;
};

ChunkedHttpTransaction* ChunkedHttpTransaction::current_instance_ = nullptr;

class ChunkedHttpTransactionFactory : public net::test_server::HttpResponse {
 public:
  ChunkedHttpTransactionFactory() = default;

  ChunkedHttpTransactionFactory(const ChunkedHttpTransactionFactory&) = delete;
  ChunkedHttpTransactionFactory& operator=(
      const ChunkedHttpTransactionFactory&) = delete;

  ~ChunkedHttpTransactionFactory() override = default;

  void SetOnResponseCreatedCallback(base::OnceClosure on_response_created) {
    on_response_created_ = std::move(on_response_created);
  }

  // net::test_server::HttpResponse implementation.
  void SendResponse(
      base::WeakPtr<net::test_server::HttpResponseDelegate> delegate) override {
    // The ChunkedHttpTransaction manages its own lifetime.
    new ChunkedHttpTransaction(delegate);

    if (on_response_created_)
      std::move(on_response_created_).Run();
  }

 private:
  base::OnceClosure on_response_created_;
};

}  // namespace

IN_PROC_BROWSER_TEST_F(FrameImplTest, NavigationEventDuringPendingLoad) {
  auto frame = FrameForTest::Create(context(), {});

  ChunkedHttpTransactionFactory* factory = new ChunkedHttpTransactionFactory;
  base::RunLoop transaction_created_run_loop;
  factory->SetOnResponseCreatedCallback(
      transaction_created_run_loop.QuitClosure());
  embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
      &net::test_server::HandlePrefixedRequest, "/pausable",
      base::BindRepeating(
          [](std::unique_ptr<ChunkedHttpTransactionFactory> out_factory,
             const net::test_server::HttpRequest&)
              -> std::unique_ptr<net::test_server::HttpResponse> {
            return out_factory;
          },
          base::Passed(base::WrapUnique(factory)))));

  net::test_server::EmbeddedTestServerHandle test_server_handle;
  ASSERT_TRUE(test_server_handle =
                  embedded_test_server()->StartAndReturnHandle());
  GURL hung_url(embedded_test_server()->GetURL("/pausable"));
  EXPECT_TRUE(LoadUrlAndExpectResponse(frame.GetNavigationController(),
                                       fuchsia::web::LoadUrlParams(),
                                       hung_url.spec()));
  fuchsia::web::NavigationState state_change;
  state_change.set_url(hung_url.spec());
  state_change.set_is_main_document_loaded(false);
  transaction_created_run_loop.Run();

  ChunkedHttpTransaction* transaction = ChunkedHttpTransaction::current();
  transaction->SendChunk(
      "HTTP/1.0 200 OK\r\n"
      "Host: localhost\r\n"
      "Content-Type: text/html\r\n\r\n"
      "<html><head><title>initial load</title>");
  state_change.set_title("initial load");
  state_change.set_is_main_document_loaded(false);
  frame.navigation_listener().RunUntilNavigationStateMatches(state_change);

  transaction->SendChunk(
      "<script>document.title='final load';</script><body></body>");
  transaction->Close();
  state_change.set_title("final load");
  state_change.set_is_main_document_loaded(true);
  frame.navigation_listener().RunUntilNavigationStateMatches(state_change);
}

IN_PROC_BROWSER_TEST_F(FrameImplTest, ReloadFrame) {
  auto frame = FrameForTest::Create(context(), {});

  embedded_test_server()->RegisterRequestMonitor(base::BindRepeating(
      &FrameImplTest::OnServeHttpRequest, base::Unretained(this)));

  net::test_server::EmbeddedTestServerHandle test_server_handle;
  ASSERT_TRUE(test_server_handle =
                  embedded_test_server()->StartAndReturnHandle());
  GURL url(embedded_test_server()->GetURL(kPage1Path));

  EXPECT_CALL(*this, OnServeHttpRequest(_)).Times(AtLeast(1));
  EXPECT_TRUE(LoadUrlAndExpectResponse(frame.GetNavigationController(),
                                       fuchsia::web::LoadUrlParams(),
                                       url.spec()));
  frame.navigation_listener().RunUntilUrlAndTitleEquals(url, kPage1Title);

  // Reload with NO_CACHE.
  {
    MockWebContentsObserver web_contents_observer(
        context_impl()->GetFrameImplForTest(&frame.ptr())->web_contents_.get());
    base::RunLoop run_loop;
    EXPECT_CALL(web_contents_observer,
                DidStartNavigation(NavigationHandleUrlEquals(url)))
        .WillOnce(InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); }));
    frame.GetNavigationController()->Reload(fuchsia::web::ReloadType::NO_CACHE);
    run_loop.Run();
  }

  // Reload with PARTIAL_CACHE.
  {
    MockWebContentsObserver web_contents_observer(
        context_impl()->GetFrameImplForTest(&frame.ptr())->web_contents_.get());
    base::RunLoop run_loop;
    EXPECT_CALL(web_contents_observer,
                DidStartNavigation(NavigationHandleUrlEquals(url)))
        .WillOnce(InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); }));
    frame.GetNavigationController()->Reload(
        fuchsia::web::ReloadType::PARTIAL_CACHE);
    run_loop.Run();
  }
}

// Verifies that NavigationState correctly reports when the Renderer terminates
// or crashes.
IN_PROC_BROWSER_TEST_F(FrameImplTest, NavigationState_RendererGone) {
  auto frame = FrameForTest::Create(context(), {});

  net::test_server::EmbeddedTestServerHandle test_server_handle;
  ASSERT_TRUE(test_server_handle =
                  embedded_test_server()->StartAndReturnHandle());
  GURL url(embedded_test_server()->GetURL(kPage1Path));

  // Navigate to a page.
  ASSERT_TRUE(LoadUrlAndExpectResponse(frame.GetNavigationController(),
                                       fuchsia::web::LoadUrlParams(),
                                       url.spec()));
  frame.navigation_listener().RunUntilUrlAndTitleEquals(url, kPage1Title);

  // Kill the renderer for the tab.
  auto* frame_impl = context_impl()->GetFrameImplForTest(&frame.ptr());
  auto* web_contents = frame_impl->web_contents_for_test();
  {
    content::ScopedAllowRendererCrashes scoped_allow_renderer_crashes;

    content::RenderFrameDeletedObserver crash_observer(
        web_contents->GetPrimaryMainFrame());
    web_contents->GetPrimaryMainFrame()->GetProcess()->Shutdown(1);
    crash_observer.WaitUntilDeleted();
  }

  // Wait for the NavigationListener to also observe the transition.
  fuchsia::web::NavigationState error_state;
  error_state.set_page_type(fuchsia::web::PageType::ERROR);
  frame.navigation_listener().RunUntilNavigationStateMatches(error_state);

  const fuchsia::web::NavigationState* current_state =
      frame.navigation_listener().current_state();
  ASSERT_TRUE(current_state->has_url());
  EXPECT_EQ(current_state->url(), url.spec());
  ASSERT_TRUE(current_state->has_title());
  EXPECT_EQ(current_state->title(), kPage1Title);
  ASSERT_TRUE(current_state->has_page_type());
  EXPECT_EQ(current_state->page_type(), fuchsia::web::PageType::ERROR);
}

IN_PROC_BROWSER_TEST_F(FrameImplTest, NoNavigationObserverAttached) {
  auto frame = FrameForTest::Create(context(), {});
  base::RunLoop().RunUntilIdle();

  net::test_server::EmbeddedTestServerHandle test_server_handle;
  ASSERT_TRUE(test_server_handle =
                  embedded_test_server()->StartAndReturnHandle());
  GURL title1(embedded_test_server()->GetURL(kPage1Path));
  GURL title2(embedded_test_server()->GetURL(kPage2Path));

  MockWebContentsObserver observer(
      context_impl()->GetFrameImplForTest(&frame.ptr())->web_contents_.get());

  {
    base::RunLoop run_loop;
    EXPECT_CALL(observer, DidStartNavigation(NavigationHandleUrlEquals(title1)))
        .WillOnce(InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); }));
    EXPECT_TRUE(LoadUrlAndExpectResponse(frame.GetNavigationController(),
                                         fuchsia::web::LoadUrlParams(),
                                         title1.spec()));
    run_loop.Run();
  }

  {
    base::RunLoop run_loop;
    EXPECT_CALL(observer, DidStartNavigation(NavigationHandleUrlEquals(title2)))
        .WillOnce(InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); }));
    EXPECT_TRUE(LoadUrlAndExpectResponse(frame.GetNavigationController(),
                                         fuchsia::web::LoadUrlParams(),
                                         title2.spec()));
    run_loop.Run();
  }
}

// Verifies that a Frame will handle navigation listener disconnection events
// gracefully.
IN_PROC_BROWSER_TEST_F(FrameImplTest, NavigationObserverDisconnected) {
  auto frame = FrameForTest::Create(context(), {});
  base::RunLoop().RunUntilIdle();

  net::test_server::EmbeddedTestServerHandle test_server_handle;
  ASSERT_TRUE(test_server_handle =
                  embedded_test_server()->StartAndReturnHandle());
  GURL title1(embedded_test_server()->GetURL(kPage1Path));
  GURL title2(embedded_test_server()->GetURL(kPage2Path));

  MockWebContentsObserver web_contents_observer(
      context_impl()->GetFrameImplForTest(&frame.ptr())->web_contents_.get());
  EXPECT_CALL(web_contents_observer,
              DidStartNavigation(NavigationHandleUrlEquals(title1)));

  EXPECT_TRUE(LoadUrlAndExpectResponse(frame.GetNavigationController(),
                                       fuchsia::web::LoadUrlParams(),
                                       title1.spec()));
  frame.navigation_listener().RunUntilUrlAndTitleEquals(title1, kPage1Title);

  // Disconnect the listener & spin the runloop to propagate the disconnection
  // event over IPC.
  frame.navigation_listener_binding().Close(ZX_ERR_PEER_CLOSED);
  base::RunLoop().RunUntilIdle();

  base::RunLoop run_loop;
  EXPECT_CALL(web_contents_observer,
              DidStartNavigation(NavigationHandleUrlEquals(title2)))
      .WillOnce(InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); }));
  EXPECT_TRUE(LoadUrlAndExpectResponse(frame.GetNavigationController(),
                                       fuchsia::web::LoadUrlParams(),
                                       title2.spec()));
  run_loop.Run();
}

IN_PROC_BROWSER_TEST_F(FrameImplTest, DelayedNavigationEventAck) {
  auto frame = FrameForTest::Create(context(), {});
  base::RunLoop().RunUntilIdle();

  net::test_server::EmbeddedTestServerHandle test_server_handle;
  ASSERT_TRUE(test_server_handle =
                  embedded_test_server()->StartAndReturnHandle());
  GURL title1(embedded_test_server()->GetURL(kPage1Path));
  GURL title2(embedded_test_server()->GetURL(kPage2Path));

  // Expect an navigation event here, but deliberately postpone acknowledgement
  // until the end of the test.
  OnNavigationStateChangedCallback captured_ack_cb;
  frame.navigation_listener().SetBeforeAckHook(base::BindRepeating(
      [](OnNavigationStateChangedCallback* dest_cb,
         const fuchsia::web::NavigationState& state,
         OnNavigationStateChangedCallback cb) { *dest_cb = std::move(cb); },
      base::Unretained(&captured_ack_cb)));
  EXPECT_TRUE(LoadUrlAndExpectResponse(frame.GetNavigationController(),
                                       fuchsia::web::LoadUrlParams(),
                                       title1.spec()));
  fuchsia::web::NavigationState expected_state;
  expected_state.set_url(title1.spec());
  frame.navigation_listener().RunUntilNavigationStateMatches(expected_state);
  EXPECT_TRUE(captured_ack_cb);
  frame.navigation_listener().SetBeforeAckHook({});

  // Navigate to a second page.
  {
    // Since we have blocked NavigationEventObserver's flow, we must observe the
    // lower level browser navigation events directly from the WebContents.
    MockWebContentsObserver web_contents_observer(
        context_impl()->GetFrameImplForTest(&frame.ptr())->web_contents_.get());

    base::RunLoop run_loop;
    EXPECT_CALL(web_contents_observer,
                DidStartNavigation(NavigationHandleUrlEquals(title2)))
        .WillOnce(InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); }));
    EXPECT_TRUE(LoadUrlAndExpectResponse(frame.GetNavigationController(),
                                         fuchsia::web::LoadUrlParams(),
                                         title2.spec()));
    run_loop.Run();
  }

  // Navigate to the first page.
  {
    MockWebContentsObserver web_contents_observer(
        context_impl()->GetFrameImplForTest(&frame.ptr())->web_contents_.get());
    base::RunLoop run_loop;
    EXPECT_CALL(web_contents_observer,
                DidStartNavigation(NavigationHandleUrlEquals(title1)))
        .WillOnce(InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); }));
    EXPECT_TRUE(LoadUrlAndExpectResponse(frame.GetNavigationController(),
                                         fuchsia::web::LoadUrlParams(),
                                         title1.spec()));
    run_loop.Run();
  }

  // Since there was no observable change in navigation state since the last
  // ack, there should be no more NavigationEvents generated.
  captured_ack_cb();
  frame.navigation_listener().RunUntilUrlAndTitleEquals(title1, kPage1Title);
}

namespace {

// Observes events specific to the Stop() test case.
struct WebContentsObserverForStop : public content::WebContentsObserver {
  using content::WebContentsObserver::Observe;
  MOCK_METHOD1(DidStartNavigation, void(content::NavigationHandle*));
  MOCK_METHOD0(NavigationStopped, void());
};

}  // namespace

IN_PROC_BROWSER_TEST_F(FrameImplTest, Stop) {
  auto frame = FrameForTest::Create(context(), {});
  base::RunLoop().RunUntilIdle();

  net::test_server::EmbeddedTestServerHandle test_server_handle;
  ASSERT_TRUE(test_server_handle =
                  embedded_test_server()->StartAndReturnHandle());

  // Use a request handler that will accept the connection and stall
  // indefinitely.
  GURL hung_url(embedded_test_server()->GetURL("/hung"));

  {
    base::RunLoop run_loop;
    WebContentsObserverForStop observer;
    observer.Observe(
        context_impl()->GetFrameImplForTest(&frame.ptr())->web_contents_.get());
    EXPECT_CALL(observer, DidStartNavigation(_))
        .WillOnce(InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); }));
    frame.GetNavigationController()->LoadUrl(
        hung_url.spec(), fuchsia::web::LoadUrlParams(),
        [](fuchsia::web::NavigationController_LoadUrl_Result) {});
    run_loop.Run();
  }

  EXPECT_TRUE(context_impl()
                  ->GetFrameImplForTest(&frame.ptr())
                  ->web_contents_->IsLoading());

  {
    base::RunLoop run_loop;
    WebContentsObserverForStop observer;
    observer.Observe(
        context_impl()->GetFrameImplForTest(&frame.ptr())->web_contents_.get());
    EXPECT_CALL(observer, NavigationStopped())
        .WillOnce(InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); }));
    frame.GetNavigationController()->Stop();
    run_loop.Run();
  }

  EXPECT_FALSE(context_impl()
                   ->GetFrameImplForTest(&frame.ptr())
                   ->web_contents_->IsLoading());
}

// TODO(crbug.com/1377994): Enable on ARM64 when bots support Vulkan.
// This test requires Vulkan and Scenic to properly signal the Views visibility.
#if defined(ARCH_CPU_ARM_FAMILY)
#define MAYBE_SetPageScale DISABLED_SetPageScale
#else
// TODO(crbug.com/1239135): SetPageScale/ExecuteJavaScript is racey, causing
// the test to flake.
#define MAYBE_SetPageScale DISABLED_SetPageScale
#endif
IN_PROC_BROWSER_TEST_F(FrameImplTest, MAYBE_SetPageScale) {
  // This test uses the `fuchsia.ui.gfx` variant of `Frame.CreateView*()`.
  ASSERT_EQ(ui::OzonePlatform::GetInstance()->GetPlatformNameForTest(),
            "scenic");

  auto frame = FrameForTest::Create(context(), {});

  auto view_tokens = scenic::ViewTokenPair::New();
  auto view_ref_pair = scenic::ViewRefPair::New();
  frame->CreateViewWithViewRef(std::move(view_tokens.view_token),
                               std::move(view_ref_pair.control_ref),
                               CloneViewRef(view_ref_pair.view_ref));

  // Attach the View to a Presenter, the page should be visible.
  auto presenter = base::ComponentContextForProcess()
                       ->svc()
                       ->Connect<::fuchsia::element::GraphicalPresenter>();
  presenter.set_error_handler([](zx_status_t status) {
    ZX_LOG(ERROR, status) << "GraphicalPresenter disconnected.";
    ADD_FAILURE();
  });

  ::fuchsia::element::ViewSpec view_spec;
  view_spec.set_view_holder_token(std::move(view_tokens.view_holder_token));
  view_spec.set_view_ref(std::move(view_ref_pair.view_ref));
  ::fuchsia::element::ViewControllerPtr view_controller;
  presenter->PresentView(std::move(view_spec), nullptr,
                         view_controller.NewRequest(),
                         [](auto result) { EXPECT_FALSE(result.is_err()); });

  net::test_server::EmbeddedTestServerHandle test_server_handle;
  ASSERT_TRUE(test_server_handle =
                  embedded_test_server()->StartAndReturnHandle());
  GURL url = embedded_test_server()->GetURL(kWaitSizePath);

  EXPECT_TRUE(LoadUrlAndExpectResponse(frame.GetNavigationController(),
                                       fuchsia::web::LoadUrlParams(),
                                       url.spec()));
  frame.navigation_listener().RunUntilUrlAndTitleEquals(url, "done");

  absl::optional<base::Value> default_dpr =
      ExecuteJavaScript(frame.ptr().get(), "window.devicePixelRatio");
  ASSERT_TRUE(default_dpr);

  EXPECT_EQ(default_dpr->GetDouble(), 1.0f);

  // Update scale and verify that devicePixelRatio is updated accordingly.
  const float kZoomInScale = 1.5;
  fuchsia::web::ContentAreaSettings settings;
  settings.set_page_scale(kZoomInScale);
  frame->SetContentAreaSettings(std::move(settings));

  absl::optional<base::Value> scaled_dpr =
      ExecuteJavaScript(frame.ptr().get(), "window.devicePixelRatio");
  ASSERT_TRUE(scaled_dpr);

  EXPECT_EQ(scaled_dpr->GetDouble(), kZoomInScale);

  // Navigate to the same page on http://localhost. This is a different site,
  // so it will be loaded in a new renderer process. Page scale value should be
  // preserved.
  GURL url2 = embedded_test_server()->GetURL("localhost", kWaitSizePath);
  EXPECT_NE(url.host(), url2.host());
  EXPECT_TRUE(LoadUrlAndExpectResponse(frame.GetNavigationController(),
                                       fuchsia::web::LoadUrlParams(),
                                       url2.spec()));
  frame.navigation_listener().RunUntilUrlAndTitleEquals(url2, "done");

  absl::optional<base::Value> dpr_after_navigation =
      ExecuteJavaScript(frame.ptr().get(), "window.devicePixelRatio");
  ASSERT_TRUE(scaled_dpr);

  EXPECT_EQ(dpr_after_navigation, scaled_dpr);

  // Reset the scale to 1.0 (default) and verify that reported DPR is updated
  // to 1.0.
  const float kDefaultScale = 1.0;
  fuchsia::web::ContentAreaSettings settings2;
  settings2.set_page_scale(kDefaultScale);
  frame->SetContentAreaSettings(std::move(settings2));

  absl::optional<base::Value> dpr_after_reset =
      ExecuteJavaScript(frame.ptr().get(), "window.devicePixelRatio");
  ASSERT_TRUE(dpr_after_reset);

  EXPECT_EQ(dpr_after_reset->GetDouble(), kDefaultScale);

  // Zoom out by setting scale to 0.5.
  const float kZoomOutScale = 0.5;
  fuchsia::web::ContentAreaSettings settings3;
  settings3.set_page_scale(kZoomOutScale);
  frame->SetContentAreaSettings(std::move(settings3));

  absl::optional<base::Value> zoomed_out_dpr =
      ExecuteJavaScript(frame.ptr().get(), "window.devicePixelRatio");
  ASSERT_TRUE(zoomed_out_dpr);

  EXPECT_EQ(zoomed_out_dpr->GetDouble(), kZoomOutScale);

  // Create another frame. Verify that the scale factor is not applied to the
  // new frame.
  auto frame2 = FrameForTest::Create(context(), {});

  view_tokens = scenic::ViewTokenPair::New();
  view_ref_pair = scenic::ViewRefPair::New();
  frame2->CreateViewWithViewRef(std::move(view_tokens.view_token),
                                std::move(view_ref_pair.control_ref),
                                CloneViewRef(view_ref_pair.view_ref));

  view_spec.set_view_holder_token(std::move(view_tokens.view_holder_token));
  view_spec.set_view_ref(std::move(view_ref_pair.view_ref));
  presenter->PresentView(std::move(view_spec), nullptr,
                         view_controller.NewRequest(), [](auto) {});

  EXPECT_TRUE(LoadUrlAndExpectResponse(frame2.GetNavigationController(),
                                       fuchsia::web::LoadUrlParams(),
                                       url.spec()));
  frame2.navigation_listener().RunUntilUrlAndTitleEquals(url, "done");

  absl::optional<base::Value> frame2_dpr =
      ExecuteJavaScript(frame2.ptr().get(), "window.devicePixelRatio");
  ASSERT_TRUE(frame2_dpr);

  EXPECT_EQ(frame2_dpr->GetDouble(), 1.0);
}

IN_PROC_BROWSER_TEST_F(FrameImplTest, RecreateView) {
  auto frame = FrameForTest::Create(context(), {});

  net::test_server::EmbeddedTestServerHandle test_server_handle;
  ASSERT_TRUE(test_server_handle =
                  embedded_test_server()->StartAndReturnHandle());

  // Process the Frame creation request, and verify we can get the FrameImpl.
  base::RunLoop().RunUntilIdle();
  FrameImpl* frame_impl = context_impl()->GetFrameImplForTest(&frame.ptr());
  ASSERT_TRUE(frame_impl);
  EXPECT_FALSE(frame_impl->has_view_for_test());

  // Verify that the Frame can navigate, prior to the View being created.
  const GURL page1_url(embedded_test_server()->GetURL(kPage1Path));
  EXPECT_TRUE(LoadUrlAndExpectResponse(frame.GetNavigationController(),
                                       fuchsia::web::LoadUrlParams(),
                                       page1_url.spec()));
  frame.navigation_listener().RunUntilUrlAndTitleEquals(page1_url, kPage1Title);

  // Request a View from the Frame, and pump the loop to process the request.
  auto view_tokens = scenic::ViewTokenPair::New();
  frame->CreateView(std::move(view_tokens.view_token));
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(frame_impl->has_view_for_test());

  // Verify that the Frame still works, by navigating to Page #2.
  const GURL page2_url(embedded_test_server()->GetURL(kPage2Path));
  EXPECT_TRUE(LoadUrlAndExpectResponse(frame.GetNavigationController(),
                                       fuchsia::web::LoadUrlParams(),
                                       page2_url.spec()));
  frame.navigation_listener().RunUntilUrlAndTitleEquals(page2_url, kPage2Title);

  // Create new View tokens and request a new view.
  auto view_tokens2 = scenic::ViewTokenPair::New();
  frame->CreateView(std::move(view_tokens2.view_token));
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(frame_impl->has_view_for_test());

  // Verify that the Frame still works, by navigating back to Page #1.
  EXPECT_TRUE(LoadUrlAndExpectResponse(frame.GetNavigationController(),
                                       fuchsia::web::LoadUrlParams(),
                                       page1_url.spec()));
  frame.navigation_listener().RunUntilUrlAndTitleEquals(page1_url, kPage1Title);
}

IN_PROC_BROWSER_TEST_F(FrameImplTest, CreateViewMissingArgs) {
  auto frame = FrameForTest::Create(context(), {});

  // Close the NavigationEventListener to avoid a test failure resulting, when
  // it is disconnected as a result of the Frame closing.
  frame.navigation_listener_binding().Close(ZX_OK);

  // Create a view with GFX, without supplying a valid view token.
  base::test::TestFuture<zx_status_t> frame_status;
  frame.ptr().set_error_handler(
      CallbackToFitFunction(frame_status.GetCallback()));

  frame->CreateView({});

  EXPECT_EQ(frame_status.Get(), ZX_ERR_INVALID_ARGS);
}

IN_PROC_BROWSER_TEST_F(FrameImplTest, CreateView2MissingArgs) {
  auto frame = FrameForTest::Create(context(), {});

  // Close the NavigationEventListener to avoid a test failure resulting, when
  // it is disconnected as a result of the Frame closing.
  frame.navigation_listener_binding().Close(ZX_OK);

  // Create a view with GFX, without supplying a valid view token.
  base::test::TestFuture<zx_status_t> frame_status;
  frame.ptr().set_error_handler(
      CallbackToFitFunction(frame_status.GetCallback()));

  frame->CreateView2({});

  EXPECT_EQ(frame_status.Get(), ZX_ERR_INVALID_ARGS);
}

IN_PROC_BROWSER_TEST_F(FrameImplTest, ChildFrameNavigationIgnored) {
  net::test_server::EmbeddedTestServerHandle test_server_handle;
  ASSERT_TRUE(test_server_handle =
                  embedded_test_server()->StartAndReturnHandle());
  GURL page_url(embedded_test_server()->GetURL("/creates_child_frame.html"));

  // Navigate to a page and wait for the navigation to complete.
  auto frame = FrameForTest::Create(context(), {});
  fuchsia::web::NavigationControllerPtr controller;
  frame->GetNavigationController(controller.NewRequest());
  EXPECT_TRUE(LoadUrlAndExpectResponse(frame.GetNavigationController(),
                                       fuchsia::web::LoadUrlParams(),
                                       page_url.spec()));
  fuchsia::web::NavigationState expected_state;
  expected_state.set_url(page_url.spec());
  expected_state.set_title("main frame");
  expected_state.set_is_main_document_loaded(true);
  frame.navigation_listener().RunUntilNavigationStateMatches(
      std::move(expected_state));

  // Notify the page so that it constructs a child iframe.
  fuchsia::web::WebMessage message;
  message.set_data(base::MemBufferFromString("test", "test"));
  base::test::TestFuture<fuchsia::web::Frame_PostMessage_Result> post_result;
  frame->PostMessage(embedded_test_server()->GetOrigin().Serialize(),
                     std::move(message),
                     CallbackToFitFunction(post_result.GetCallback()));

  frame.navigation_listener().SetBeforeAckHook(
      base::BindRepeating([](const fuchsia::web::NavigationState& change,
                             OnNavigationStateChangedCallback callback) {
        // The child iframe's loading status should not affect the
        // is_main_document_loaded() bit.
        if (change.has_is_main_document_loaded())
          ADD_FAILURE();

        callback();
      }));

  frame.navigation_listener().RunUntilUrlAndTitleEquals(page_url,
                                                        "iframe loaded");
}

// Tests SetNavigationEventListener() immediately returns a NavigationEvent,
// even in the absence of a new navigation.
IN_PROC_BROWSER_TEST_F(FrameImplTest, ImmediateNavigationEvent) {
  net::test_server::EmbeddedTestServerHandle test_server_handle;
  ASSERT_TRUE(test_server_handle =
                  embedded_test_server()->StartAndReturnHandle());
  GURL page_url(embedded_test_server()->GetURL(kPage1Path));

  // The first NavigationState received should be empty.
  base::RunLoop run_loop;
  auto frame = FrameForTest::Create(context(), {});
  frame.navigation_listener().SetBeforeAckHook(base::BindRepeating(
      [](base::OnceClosure quit_loop,
         const fuchsia::web::NavigationState& change,
         OnNavigationStateChangedCallback callback) {
        std::move(quit_loop).Run();
        EXPECT_TRUE(change.IsEmpty());
        callback();
      },
      run_loop.QuitClosure()));
  run_loop.Run();
  frame.navigation_listener().SetBeforeAckHook({});

  // Navigate to a page and wait for the navigation to complete.
  EXPECT_TRUE(LoadUrlAndExpectResponse(frame.GetNavigationController(),
                                       fuchsia::web::LoadUrlParams(),
                                       page_url.spec()));
  frame.navigation_listener().RunUntilUrlEquals(page_url);

  // Attach a new navigation listener, we should get the new page state, even if
  // no new navigation occurred.
  frame.CreateAndAttachNavigationListener(/*flags=*/{});
  frame.navigation_listener().RunUntilUrlAndTitleEquals(page_url, kPage1Title);
}

// Check loading an invalid URL in NavigationController.LoadUrl() sets the right
// error.
IN_PROC_BROWSER_TEST_F(FrameImplTest, InvalidUrl) {
  auto frame = FrameForTest::Create(context(), {});

  base::test::TestFuture<fuchsia::web::NavigationController_LoadUrl_Result>
      result;
  auto controller = frame.GetNavigationController();
  controller->LoadUrl("http:google.com:foo", fuchsia::web::LoadUrlParams(),
                      CallbackToFitFunction(result.GetCallback()));
  ASSERT_TRUE(result.Wait());

  ASSERT_TRUE(result.Get().is_err());
  EXPECT_EQ(result.Get().err(),
            fuchsia::web::NavigationControllerError::INVALID_URL);
}

// Check setting invalid headers in NavigationController.LoadUrl() sets the
// right error.
IN_PROC_BROWSER_TEST_F(FrameImplTest, InvalidHeader) {
  auto frame = FrameForTest::Create(context(), {});

  {
    // Set an invalid header name.
    fuchsia::web::LoadUrlParams load_url_params;
    fuchsia::net::http::Header header;
    header.name = StringToBytes("Invalid:Header");
    header.value = StringToBytes("1");
    load_url_params.set_headers({header});

    base::test::TestFuture<fuchsia::web::NavigationController_LoadUrl_Result>
        result;
    auto controller = frame.GetNavigationController();
    controller->LoadUrl("http://site.ext/", std::move(load_url_params),
                        CallbackToFitFunction(result.GetCallback()));
    ASSERT_TRUE(result.Wait());

    ASSERT_TRUE(result.Get().is_err());
    EXPECT_EQ(result.Get().err(),
              fuchsia::web::NavigationControllerError::INVALID_HEADER);
  }

  {
    // Set an invalid header value.
    fuchsia::web::LoadUrlParams load_url_params;
    fuchsia::net::http::Header header;
    header.name = StringToBytes("Header");
    header.value = StringToBytes("Invalid\rValue");
    load_url_params.set_headers({header});

    base::test::TestFuture<fuchsia::web::NavigationController_LoadUrl_Result>
        result;
    auto controller = frame.GetNavigationController();
    controller->LoadUrl("http://site.ext/", std::move(load_url_params),
                        CallbackToFitFunction(result.GetCallback()));
    ASSERT_TRUE(result.Wait());

    ASSERT_TRUE(result.Get().is_err());
    EXPECT_EQ(result.Get().err(),
              fuchsia::web::NavigationControllerError::INVALID_HEADER);
  }
}

IN_PROC_BROWSER_TEST_F(FrameImplTest, ContentAreaSettings) {
  auto frame = FrameForTest::Create(context(), {});
  base::RunLoop().RunUntilIdle();
  auto* frame_impl = context_impl()->GetFrameImplForTest(&frame.ptr());
  auto* web_contents = frame_impl->web_contents_for_test();

  // Frame should start with default values in web_contents.
  {
    blink::web_pref::WebPreferences web_prefs =
        web_contents->GetOrCreateWebPreferences();
    EXPECT_FALSE(web_prefs.hide_scrollbars);
    EXPECT_EQ(web_prefs.autoplay_policy,
              blink::mojom::AutoplayPolicy::kDocumentUserActivationRequired);
    EXPECT_EQ(web_prefs.preferred_color_scheme,
              blink::mojom::PreferredColorScheme::kLight);
  }

  // SetContentAreaSettings with empty settings object should not change any
  // existing settings.
  {
    fuchsia::web::ContentAreaSettings settings;
    frame->SetContentAreaSettings(std::move(settings));
    base::RunLoop().RunUntilIdle();

    blink::web_pref::WebPreferences web_prefs =
        web_contents->GetOrCreateWebPreferences();
    EXPECT_FALSE(web_prefs.hide_scrollbars);
    EXPECT_EQ(web_prefs.autoplay_policy,
              blink::mojom::AutoplayPolicy::kDocumentUserActivationRequired);
    EXPECT_EQ(web_prefs.preferred_color_scheme,
              blink::mojom::PreferredColorScheme::kLight);
  }

  // Set hide_scrollbars field and expect that it's reflected in web_contents.
  // Expect other fields to be unchanged.
  {
    fuchsia::web::ContentAreaSettings settings;
    settings.set_hide_scrollbars(true);
    frame->SetContentAreaSettings(std::move(settings));
    base::RunLoop().RunUntilIdle();

    blink::web_pref::WebPreferences web_prefs =
        web_contents->GetOrCreateWebPreferences();
    EXPECT_TRUE(web_prefs.hide_scrollbars);
    EXPECT_EQ(web_prefs.autoplay_policy,
              blink::mojom::AutoplayPolicy::kDocumentUserActivationRequired);
    EXPECT_EQ(web_prefs.preferred_color_scheme,
              blink::mojom::PreferredColorScheme::kLight);
  }

  // ResetContentAreaSettings should revert preferences to their default values
  // in web_contents.
  {
    frame->ResetContentAreaSettings();
    base::RunLoop().RunUntilIdle();

    blink::web_pref::WebPreferences web_prefs =
        web_contents->GetOrCreateWebPreferences();
    EXPECT_FALSE(web_prefs.hide_scrollbars);
    EXPECT_EQ(web_prefs.autoplay_policy,
              blink::mojom::AutoplayPolicy::kDocumentUserActivationRequired);
    EXPECT_EQ(web_prefs.preferred_color_scheme,
              blink::mojom::PreferredColorScheme::kLight);
  }
}

// Verifies that a `Frame` closes correctly if `Close()` is called before any
// page is loaded.
IN_PROC_BROWSER_TEST_F(FrameImplTest, Close_BeforeNavigation) {
  auto frame = FrameForTest::Create(context(), {});

  base::RunLoop loop;
  frame.ptr().set_error_handler(
      [quit = loop.QuitClosure()](zx_status_t status) {
        EXPECT_EQ(status, ZX_OK);
        std::move(quit).Run();
      });

  // Request to gracefully close the Frame, which should be immediate since
  // nothing has been loaded into it yet.
  frame->Close({});

  loop.Run();
}

namespace {

// Helper class for `Frame.Close()` tests, that navigates the `Frame` to an
// event-recording page, and connects to accumulate the list of events it
// receives.
// If `hang_on_event` is true then the web page will be configured to busy-loop
// as soon as any event is received, to allow timeouts to be simulated.
class FrameForTestWithMessageLog : public FrameForTest {
 public:
  FrameForTestWithMessageLog(FrameForTest frame,
                             net::EmbeddedTestServer& test_server,
                             bool hang_on_event = false)
      : FrameForTest(std::move(frame)) {
    // Navigate to a page that will record the relevant events.
    const GURL page_url(test_server.GetURL(kReportCloseEventsPath));
    if (!LoadUrlAndExpectResponse(GetNavigationController(),
                                  fuchsia::web::LoadUrlParams(),
                                  page_url.spec())) {
      ADD_FAILURE();
      loop_.Quit();
      return;
    }
    navigation_listener().RunUntilUrlEquals(page_url);

    // Connect a message port over which to receive notifications of events.
    fuchsia::web::WebMessage message;
    message.set_data(base::MemBufferFromString(
        hang_on_event ? "hang_on_event" : "init", "test"));
    message.mutable_outgoing_transfer()->push_back(
        std::move(fuchsia::web::OutgoingTransferable().set_message_port(
            message_port_.NewRequest())));

    base::test::TestFuture<fuchsia::web::Frame_PostMessage_Result> post_result;
    get()->PostMessage(test_server.GetOrigin().Serialize(), std::move(message),
                       CallbackToFitFunction(post_result.GetCallback()));
    if (!post_result.Wait()) {
      ADD_FAILURE();
      loop_.Quit();
      return;
    }

    // If the FrameForTest becomes disconnected then store the epitaph, for
    // tests to verify.
    ptr().set_error_handler(CallbackToFitFunction(epitaph_.GetCallback()));

    // Don't error-out if the Frame disconnects.
    navigation_listener_binding().set_error_handler([](zx_status_t) {});

    // Start reading messages from the port into a queue, until the port closes.
    message_port_.set_error_handler(
        [quit = loop_.QuitClosure()](zx_status_t) { std::move(quit).Run(); });
    message_port_->ReceiveMessage(
        fit::bind_member(this, &FrameForTestWithMessageLog::OnMessage));
  }

  void RunUntilMessagePortClosed() { loop_.Run(); }

  base::test::TestFuture<zx_status_t>& epitaph() { return epitaph_; }

  const std::vector<std::string>& events() const { return events_; }

  std::string EventsString() const {
    return "[" + base::JoinString(events_, ", ") + "]";
  }

 private:
  void OnMessage(fuchsia::web::WebMessage message) {
    events_.push_back(std::move(*base::StringFromMemBuffer(message.data())));
    message_port_->ReceiveMessage(
        fit::bind_member(this, &FrameForTestWithMessageLog::OnMessage));
  }

  base::RunLoop loop_;
  fuchsia::web::MessagePortPtr message_port_;
  std::vector<std::string> events_;
  base::test::TestFuture<zx_status_t> epitaph_;
};

constexpr char kBeforeUnloadEventName[] = "window.beforeunload";
constexpr char kUnloadEventName[] = "window.unload";
constexpr char kPageHideEventName[] = "window.pagehide";

}  // namespace

// Verifies that `Close()`ing a `Frame` without an explicit timeout allows
// graceful teardown, including firing the expected set of events
// ("beforeunload", "pagehide" and "onunload").
IN_PROC_BROWSER_TEST_F(FrameImplTest, Close_EventsWithDefaultTimeout) {
  net::test_server::EmbeddedTestServerHandle test_server_handle;
  ASSERT_TRUE(test_server_handle =
                  embedded_test_server()->StartAndReturnHandle());

  FrameForTestWithMessageLog frame(FrameForTest::Create(context(), {}),
                                   *embedded_test_server());

  // Request to gracefully close the Frame, which should trigger the
  // relevant event handlers, and then quickly tear-down.
  frame->Close({});

  frame.RunUntilMessagePortClosed();

  // Verify that the expected events were delivered!
  ASSERT_EQ(frame.events().size(), 3u) << frame.EventsString();
  EXPECT_EQ(frame.events()[0], kBeforeUnloadEventName);
  EXPECT_EQ(frame.events()[1], kPageHideEventName);
  EXPECT_EQ(frame.events()[2], kUnloadEventName);

  EXPECT_EQ(frame.epitaph().Get(), ZX_OK);
}

// Verifies that `Close()`ing a `Frame` with an explicit timeout allows
// graceful teardown, dispatching the expected events.
IN_PROC_BROWSER_TEST_F(FrameImplTest, Close_EventsWithNonZeroTimeout) {
  net::test_server::EmbeddedTestServerHandle test_server_handle;
  ASSERT_TRUE(test_server_handle =
                  embedded_test_server()->StartAndReturnHandle());

  FrameForTestWithMessageLog frame(FrameForTest::Create(context(), {}),
                                   *embedded_test_server());

  // Request to gracefully close the Frame, which should trigger the
  // relevant event handlers, and then quickly tear-down.
  // Use a timeout long enough that the test would have timed-out if
  // teardown had taken so long.
  frame->Close(std::move(fuchsia::web::FrameCloseRequest().set_timeout(
      TestTimeouts::action_max_timeout().ToZxDuration())));

  frame.RunUntilMessagePortClosed();

  // Verify that the expected events were delivered!
  ASSERT_EQ(frame.events().size(), 3u) << frame.EventsString();
  EXPECT_EQ(frame.events()[0], kBeforeUnloadEventName);
  EXPECT_EQ(frame.events()[1], kPageHideEventName);
  EXPECT_EQ(frame.events()[2], kUnloadEventName);

  EXPECT_EQ(frame.epitaph().Get(), ZX_OK);
}

// Verifies that if a `Frame` is `Close()`d with a timeout and takes too long
// to close then `ZX_ERR_TIMED_OUT` is reported.
IN_PROC_BROWSER_TEST_F(FrameImplTest, Close_WithInsufficientTimeout) {
  net::test_server::EmbeddedTestServerHandle test_server_handle;
  ASSERT_TRUE(test_server_handle =
                  embedded_test_server()->StartAndReturnHandle());

  FrameForTestWithMessageLog frame(FrameForTest::Create(context(), {}),
                                   *embedded_test_server(),
                                   /* hang_on_event= */ true);

  // Request to gracefully close the Frame, by specifying a non-zero timeout.
  // This can be arbitrarily short, since we are deliberately provoking timeout.
  frame->Close(std::move(fuchsia::web::FrameCloseRequest().set_timeout(
      base::Microseconds(1u).ToZxDuration())));

  // Don't wait for the MessagePort to close, since that doesn't happen in
  // ASAN builds, for some reason (crbug.com/1400304).

  // Regardless of how many events may have been delivered, teardown should
  // have timed-out.
  EXPECT_EQ(frame.epitaph().Get(), ZX_ERR_TIMED_OUT);
}

// Verifies that `Close()`ing a `Frame` with a zero timeout takes immediate
// effect.
IN_PROC_BROWSER_TEST_F(FrameImplTest, Close_NoEventsWithZeroTimeout) {
  net::test_server::EmbeddedTestServerHandle test_server_handle;
  ASSERT_TRUE(test_server_handle =
                  embedded_test_server()->StartAndReturnHandle());

  FrameForTestWithMessageLog frame(FrameForTest::Create(context(), {}),
                                   *embedded_test_server());

  // Request to close the frame immediately.
  frame->Close(std::move(fuchsia::web::FrameCloseRequest().set_timeout(0u)));

  frame.RunUntilMessagePortClosed();

  // In practice it is possible for content to have time to receive & process
  // visibility and unload events, so just check for "beforeunload".
  EXPECT_THAT(frame.events(), Not(Contains(kBeforeUnloadEventName)))
      << frame.EventsString();

  EXPECT_EQ(frame.epitaph().Get(), ZX_OK);
}

// Verifies that disconnecting a `Frame` takes immediate effect.
IN_PROC_BROWSER_TEST_F(FrameImplTest, Disconnect_NoEvents) {
  net::test_server::EmbeddedTestServerHandle test_server_handle;
  ASSERT_TRUE(test_server_handle =
                  embedded_test_server()->StartAndReturnHandle());

  FrameForTestWithMessageLog frame(FrameForTest::Create(context(), {}),
                                   *embedded_test_server());

  // Request to close the frame immediately.
  frame.ptr() = nullptr;

  frame.RunUntilMessagePortClosed();

  // In practice it is possible for content to have time to receive & process
  // visibility and unload events, so just check for "beforeunload".
  EXPECT_THAT(frame.events(), Not(Contains(kBeforeUnloadEventName)))
      << frame.EventsString();
}
