// Copyright (c) 2014 The Chromium Embedded Framework 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 "include/base/cef_bind.h"
#include "include/base/cef_scoped_ptr.h"
#include "include/wrapper/cef_closure_task.h"
#include "include/wrapper/cef_stream_resource_handler.h"
#include "tests/ceftests/test_handler.h"
#include "tests/ceftests/test_util.h"
#include "tests/gtest/include/gtest/gtest.h"
#include "tests/shared/browser/client_app_browser.h"
#include "tests/shared/renderer/client_app_renderer.h"

using client::ClientAppBrowser;
using client::ClientAppRenderer;

namespace {

// The frame navigation test harness work as follows:
//
// In the browser process:
// 1. TEST() function creates a new FrameNavTestHandler instance with a unique
//    FrameNavFactoryId.
// 2. FrameNavTestHandler calls FrameNavExpectationsFactoryBrowser::FromID to
//    create a new factory instance.
// 3. FrameNavTestHandler calls FrameNavExpectationsFactoryBrowser::Create to
//    create a new FrameNavExpectationsBrowser instance for the current
//    navigation.
// 4. FrameNavTestHandler retrieves the URL to load via
//    FrameNavExpectationsBrowser::GetMainURL and calls either CreateBrowser
//    (for the first navigation) or LoadURL (for the following navigations).
// 5. If the renderer process does not already exist CEF creates it with
//    command-line arguments that specify the FrameNavFactoryId via
//    FrameNavBrowserTest::OnBeforeChildProcessLaunch.
//
// In the renderer process:
// 6. If the renderer process is newly created FrameNavRendererTest calls
//    FrameNavExpectationsFactoryRenderer::FromID to create a new factory
//    instance.
// 7. FrameNavRendererTest calls FrameNavExpectationsFactoryRenderer::Create to
//    create a new FrameNavExpectationsRenderer instance for the current
//    navigation.
//
// In both processes:
// 8. Callback notifications are sent to the FrameNavExpectations* instances.
//
// In the renderer process:
// 9. When the FrameNavExpectationsRenderer instance determines that the
//    renderer side of the test is complete it calls SignalComplete which
//    finalizes and deletes the FrameNavExpectationsRenderer instance and
//    sends an IPC message to the browser process.
//
// In the browser process:
// 11.FrameNavExpectationsBrowser::OnRendererComplete is called in response to
//    renderer-side test completion message.
// 12.When the FrameNavExpectationsBrowser instance determines that the browser
//    side of the test is complete it calls SignalComplete which finalizes and
//    deletes the FrameNavExpectationsBrowser instance.
// 13.If FrameNavExpectationsFactoryBrowser::HasMoreNavigations returns false
//    then DestroyTest is called and the test ends. Otherwise, the navigation
//    count is incremented and the process repeats starting with step #3.
//
//
// To add a new test case:
// 1. Add a new value to the FrameNavFactoryId enumeration.
// 2. Provide implementations of FrameNavExpectations*.
// 3. Add a case for the new factory ID to FrameNavExpectationsFactory*::FromID.
// 4. Implement a TEST() function that creates a FrameNavTestHandler instance
//    and passes the new factory ID.
//
//
// Run with the `--single-process` command-line flag to see expectation failures
// from the renderer process.
//

// All known factory IDs.
enum FrameNavFactoryId {
  FNF_ID_INVALID = 0,
  FNF_ID_SINGLE_NAV_HARNESS,
  FNF_ID_SINGLE_NAV,
  FNF_ID_MULTI_NAV_HARNESS,
  FNF_ID_MULTI_NAV,
  FNF_ID_NESTED_IFRAMES_SAME_ORIGIN,
  FNF_ID_NESTED_IFRAMES_DIFF_ORIGIN,
};

// IPC message name.
const char kFrameNavMsg[] = "FrameTest.Navigation";

// Extra info parameter keys.
const char kFrameNavTestCmdKey[] = "frame-nav-test";

// Origins used in tests.
const char kFrameNavOrigin0[] = "http://tests-framenav0.com/";
const char kFrameNavOrigin1[] = "http://tests-framenav1.com/";
const char kFrameNavOrigin2[] = "http://tests-framenav2.com/";
const char kFrameNavOrigin3[] = "http://tests-framenav3.com/";

// Maximum number of navigations. Should be kept synchronized with the number
// of kFrameNavOrigin* values. Don't modify this value without checking the
// below use cases.
const int kMaxMultiNavNavigations = 4;

// Abstract base class representing expectations that result from a navigation.
class FrameNavExpectations {
 public:
  typedef base::Callback<void(CefRefPtr<CefBrowser>, CefRefPtr<CefFrame>)>
      CompletionCallback;

  FrameNavExpectations(int nav, bool renderer)
      : nav_(nav), renderer_(renderer) {}
  virtual ~FrameNavExpectations() {}

  // Browser and renderer notifications.
  virtual bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
                                    bool isLoading) {
    return true;
  }
  virtual bool OnLoadStart(CefRefPtr<CefBrowser> browser,
                           CefRefPtr<CefFrame> frame) {
    return true;
  }
  virtual bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
                         CefRefPtr<CefFrame> frame) {
    return true;
  }

  // Final expectations check before this object is deleted.
  virtual bool Finalize() = 0;

  // Signal that all expectations are completed. Should be called as a result of
  // notifications.
  void SignalComplete(CefRefPtr<CefBrowser> browser,
                      CefRefPtr<CefFrame> frame) {
    if (!completion_callback_.is_null()) {
      // Execute the callback asynchronously to avoid any issues with what's
      // currently on the stack.
      CefPostTask((renderer_ ? TID_RENDERER : TID_UI),
                  base::Bind(completion_callback_, browser, frame));
      completion_callback_.Reset();
    }
  }

  // Returns the current navigation count. In the browser process this value
  // increments over the life span of the FrameNavTestHandler instance. In the
  // renderer process this value increments over the life span of a single
  // renderer instance (i.e. cross-origin navigations will cause this value to
  // reset).
  int nav() const { return nav_; }

  // Returns true if this is a renderer-side expectation object.
  bool renderer() const { return renderer_; }

  void set_completion_callback(const CompletionCallback& completion_callback) {
    completion_callback_ = completion_callback;
  }

 private:
  int nav_;
  bool renderer_;
  CompletionCallback completion_callback_;
};

// Browser process expectations abstract base class.
class FrameNavExpectationsBrowser : public FrameNavExpectations {
 public:
  explicit FrameNavExpectationsBrowser(int nav)
      : FrameNavExpectations(nav, false) {}

  // Loading information.
  virtual std::string GetMainURL() = 0;
  virtual std::string GetContentForURL(const std::string& url) = 0;

  // Browser-only notifications.
  virtual bool OnAfterCreated(CefRefPtr<CefBrowser> browser) {
    EXPECT_TRUE(browser.get());
    return true;
  }
  virtual bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
                              CefRefPtr<CefFrame> frame,
                              const std::string& url) {
    EXPECT_TRUE(browser.get());
    EXPECT_TRUE(frame.get());
    EXPECT_FALSE(url.empty());
    return true;
  }
  virtual bool GetResourceHandler(CefRefPtr<CefBrowser> browser,
                                  CefRefPtr<CefFrame> frame) {
    EXPECT_TRUE(browser.get());
    EXPECT_TRUE(frame.get());
    return true;
  }

  // Called when the renderer signals completion.
  virtual bool OnRendererComplete(CefRefPtr<CefBrowser> browser,
                                  CefRefPtr<CefFrame> frame,
                                  int renderer_nav,
                                  bool renderer_result) = 0;
};

// Renderer process expectations abstract base class.
class FrameNavExpectationsRenderer : public FrameNavExpectations {
 public:
  explicit FrameNavExpectationsRenderer(int nav)
      : FrameNavExpectations(nav, true) {}
};

// Abstract base class for the factory that creates expectations objects.
class FrameNavExpectationsFactory {
 public:
  FrameNavExpectationsFactory() {}
  virtual ~FrameNavExpectationsFactory() {}

  // Returns the unique ID for this factory type.
  virtual FrameNavFactoryId GetID() const = 0;
};

// Browser process expectations factory abstact base class.
class FrameNavExpectationsFactoryBrowser : public FrameNavExpectationsFactory {
 public:
  FrameNavExpectationsFactoryBrowser() {}

  // Create a new factory instance of the specified type.
  static scoped_ptr<FrameNavExpectationsFactoryBrowser> FromID(
      FrameNavFactoryId id);

  // Returns true if there will be more navigations in the browser process
  // handler.
  virtual bool HasMoreNavigations() const = 0;

  // Verify final expectations results.
  virtual bool Finalize() = 0;

  scoped_ptr<FrameNavExpectationsBrowser> Create(
      int nav,
      const FrameNavExpectations::CompletionCallback& completion_callback) {
    scoped_ptr<FrameNavExpectationsBrowser> expectations;
    expectations = Create(nav);
    expectations->set_completion_callback(completion_callback);
    return expectations.Pass();
  }

 protected:
  // Implement in the test-specific factory instance.
  virtual scoped_ptr<FrameNavExpectationsBrowser> Create(int nav) = 0;
};

// Renderer process expectations factory abstact base class.
class FrameNavExpectationsFactoryRenderer : public FrameNavExpectationsFactory {
 public:
  FrameNavExpectationsFactoryRenderer() {}

  // Create a new factory instance of the specified type.
  static scoped_ptr<FrameNavExpectationsFactoryRenderer> FromID(
      FrameNavFactoryId id);

  scoped_ptr<FrameNavExpectationsRenderer> Create(
      int nav,
      const FrameNavExpectations::CompletionCallback& completion_callback) {
    scoped_ptr<FrameNavExpectationsRenderer> expectations;
    expectations = Create(nav);
    expectations->set_completion_callback(completion_callback);
    return expectations.Pass();
  }

 protected:
  // Implement in the test-specific factory instance.
  virtual scoped_ptr<FrameNavExpectationsRenderer> Create(int nav) = 0;
};

// Renderer side handler.
class FrameNavRendererTest : public ClientAppRenderer::Delegate,
                             public CefLoadHandler {
 public:
  FrameNavRendererTest() : run_test_(false), nav_(0) {}

  void OnBrowserCreated(CefRefPtr<ClientAppRenderer> app,
                        CefRefPtr<CefBrowser> browser,
                        CefRefPtr<CefDictionaryValue> extra_info) override {
    if (!extra_info->HasKey(kFrameNavTestCmdKey))
      return;

    FrameNavFactoryId factory_id =
        static_cast<FrameNavFactoryId>(extra_info->GetInt(kFrameNavTestCmdKey));
    run_test_ = factory_id != FNF_ID_INVALID;
    if (!run_test_)
      return;

    factory_ = FrameNavExpectationsFactoryRenderer::FromID(factory_id);
  }

  CefRefPtr<CefLoadHandler> GetLoadHandler(
      CefRefPtr<ClientAppRenderer> app) override {
    if (!run_test_)
      return nullptr;

    return this;
  }

  void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
                            bool isLoading,
                            bool canGoBack,
                            bool canGoForward) override {
    CreateExpectationsIfNecessary();
    EXPECT_TRUE(expectations_->OnLoadingStateChange(browser, isLoading))
        << "isLoading = " << isLoading << ", nav = " << nav_;
  }

  void OnLoadStart(CefRefPtr<CefBrowser> browser,
                   CefRefPtr<CefFrame> frame,
                   TransitionType transition_type) override {
    CreateExpectationsIfNecessary();
    EXPECT_TRUE(expectations_->OnLoadStart(browser, frame)) << "nav = " << nav_;
  }

  void OnLoadEnd(CefRefPtr<CefBrowser> browser,
                 CefRefPtr<CefFrame> frame,
                 int httpStatusCode) override {
    CreateExpectationsIfNecessary();
    EXPECT_TRUE(expectations_->OnLoadEnd(browser, frame)) << "nav = " << nav_;
  }

 protected:
  // Create a new expectations object if one does not already exist for the
  // current navigation.
  void CreateExpectationsIfNecessary() {
    if (expectations_)
      return;
    expectations_ = factory_->Create(
        nav_, base::Bind(&FrameNavRendererTest::SendTestResults, this));
  }

  // Send the test results.
  // Will be called via FrameNavExpectations::SignalComplete.
  void SendTestResults(CefRefPtr<CefBrowser> browser,
                       CefRefPtr<CefFrame> frame) {
    // End of the current expectations object.
    EXPECT_TRUE(expectations_->Finalize()) << "nav = " << nav_;
    expectations_.reset(nullptr);

    // Check if the test has failed.
    bool result = !TestFailed();

    // Return the result to the browser process.
    CefRefPtr<CefProcessMessage> return_msg =
        CefProcessMessage::Create(kFrameNavMsg);
    CefRefPtr<CefListValue> args = return_msg->GetArgumentList();
    EXPECT_TRUE(args.get());
    EXPECT_TRUE(args->SetInt(0, nav_));
    EXPECT_TRUE(args->SetBool(1, result));

    const int64 frame_id = frame->GetIdentifier();
    EXPECT_TRUE(args->SetInt(2, CefInt64GetLow(frame_id)));
    EXPECT_TRUE(args->SetInt(3, CefInt64GetHigh(frame_id)));

    frame->SendProcessMessage(PID_BROWSER, return_msg);

    nav_++;
  }

  bool run_test_;
  int nav_;
  scoped_ptr<FrameNavExpectationsFactoryRenderer> factory_;
  scoped_ptr<FrameNavExpectationsRenderer> expectations_;

  IMPLEMENT_REFCOUNTING(FrameNavRendererTest);
};

// Browser side handler.
class FrameNavTestHandler : public TestHandler {
 public:
  explicit FrameNavTestHandler(FrameNavFactoryId factory_id)
      : nav_(0),
        factory_(FrameNavExpectationsFactoryBrowser::FromID(factory_id)) {}

  ~FrameNavTestHandler() override { EXPECT_TRUE(got_destroyed_); }

  void RunTest() override {
    // Create the first expectations object.
    expectations_ = factory_->Create(
        nav_, base::Bind(&FrameNavTestHandler::RunNextNav, this));

    CefRefPtr<CefDictionaryValue> extra_info = CefDictionaryValue::Create();
    extra_info->SetInt(kFrameNavTestCmdKey, factory_->GetID());

    // Create the browser with the initial URL.
    CreateBrowser(expectations_->GetMainURL(), nullptr, extra_info);

    // Time out the test after a reasonable period of time.
    SetTestTimeout(15000);
  }

  // Transition to the next navigation.
  // Will be called via FrameNavExpectations::SignalComplete.
  void RunNextNav(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame) {
    // End of the current expectations object.
    EXPECT_TRUE(expectations_->Finalize());
    expectations_.reset(nullptr);

    if (!factory_->HasMoreNavigations()) {
      // End of the test.
      DestroyTest();
      return;
    }

    nav_++;

    // Create the next expectations object.
    expectations_ = factory_->Create(
        nav_, base::Bind(&FrameNavTestHandler::RunNextNav, this));

    // Load the main URL.
    browser->GetMainFrame()->LoadURL(expectations_->GetMainURL());
  }

  void OnAfterCreated(CefRefPtr<CefBrowser> browser) override {
    TestHandler::OnAfterCreated(browser);

    EXPECT_TRUE(expectations_->OnAfterCreated(browser)) << "nav = " << nav_;
  }

  CefRefPtr<CefResourceHandler> GetResourceHandler(
      CefRefPtr<CefBrowser> browser,
      CefRefPtr<CefFrame> frame,
      CefRefPtr<CefRequest> request) override {
    EXPECT_TRUE(expectations_->GetResourceHandler(browser, frame))
        << "nav = " << nav_;

    const std::string& url = request->GetURL();
    const std::string& content = expectations_->GetContentForURL(url);
    EXPECT_TRUE(!content.empty()) << "nav = " << nav_;

    CefRefPtr<CefStreamReader> stream = CefStreamReader::CreateForData(
        static_cast<void*>(const_cast<char*>(content.c_str())),
        content.length());
    return new CefStreamResourceHandler("text/html", stream);
  }

  bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
                      CefRefPtr<CefFrame> frame,
                      CefRefPtr<CefRequest> request,
                      bool user_gesture,
                      bool is_redirect) override {
    EXPECT_TRUE(
        expectations_->OnBeforeBrowse(browser, frame, request->GetURL()))
        << "nav = " << nav_;

    return false;
  }

  void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
                            bool isLoading,
                            bool canGoBack,
                            bool canGoForward) override {
    EXPECT_TRUE(expectations_->OnLoadingStateChange(browser, isLoading))
        << "isLoading = " << isLoading << ", nav = " << nav_;
    ;
  }

  void OnLoadStart(CefRefPtr<CefBrowser> browser,
                   CefRefPtr<CefFrame> frame,
                   TransitionType transition_type) override {
    EXPECT_TRUE(expectations_->OnLoadStart(browser, frame)) << "nav = " << nav_;
  }

  void OnLoadEnd(CefRefPtr<CefBrowser> browser,
                 CefRefPtr<CefFrame> frame,
                 int httpStatusCode) override {
    EXPECT_TRUE(expectations_->OnLoadEnd(browser, frame)) << "nav = " << nav_;
  }

  bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
                                CefRefPtr<CefFrame> frame,
                                CefProcessId source_process,
                                CefRefPtr<CefProcessMessage> message) override {
    if (message->GetName().ToString() == kFrameNavMsg) {
      // Test that the renderer side succeeded.
      CefRefPtr<CefListValue> args = message->GetArgumentList();
      EXPECT_TRUE(args.get());

      EXPECT_TRUE(expectations_->OnRendererComplete(
          browser, frame, args->GetInt(0), args->GetBool(1)))
          << "nav = " << nav_;

      // Test that browser and render process frame IDs match.
      const int64 frame_id = CefInt64Set(args->GetInt(2), args->GetInt(3));
      EXPECT_EQ(frame->GetIdentifier(), frame_id);

      return true;
    }

    // Message not handled.
    return false;
  }

  void DestroyTest() override {
    if (got_destroyed_)
      return;

    got_destroyed_.yes();

    // The expectations should have been tested already.
    EXPECT_FALSE(expectations_.get());

    // Test that factory conditions we met.
    EXPECT_TRUE(factory_->Finalize()) << "nav = " << nav_;

    TestHandler::DestroyTest();
  }

  int nav_;
  TrackCallback got_destroyed_;
  scoped_ptr<FrameNavExpectationsFactoryBrowser> factory_;
  scoped_ptr<FrameNavExpectationsBrowser> expectations_;

  IMPLEMENT_REFCOUNTING(FrameNavTestHandler);
};

// Helper for defining frame tests.
#define FRAME_TEST(name, factory_id)         \
  TEST(FrameTest, name) {                    \
    CefRefPtr<FrameNavTestHandler> handler = \
        new FrameNavTestHandler(factory_id); \
    handler->ExecuteTest();                  \
    ReleaseAndWaitForDestructor(handler);    \
  }

// Browser process expectations for a single navigation.
class FrameNavExpectationsBrowserSingleNav
    : public FrameNavExpectationsBrowser {
 public:
  explicit FrameNavExpectationsBrowserSingleNav(int nav)
      : FrameNavExpectationsBrowser(nav) {}

  ~FrameNavExpectationsBrowserSingleNav() override {
    EXPECT_TRUE(got_finalize_);
  }

  bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
                            bool isLoading) override {
    if (isLoading) {
      EXPECT_FALSE(got_loading_state_change_start_);
      got_loading_state_change_start_.yes();
    } else {
      EXPECT_FALSE(got_loading_state_change_end_);
      got_loading_state_change_end_.yes();
      SignalCompleteIfDone(browser, browser->GetMainFrame());
    }
    return true;
  }

  bool OnLoadStart(CefRefPtr<CefBrowser> browser,
                   CefRefPtr<CefFrame> frame) override {
    EXPECT_FALSE(got_load_start_);
    got_load_start_.yes();
    return true;
  }

  bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
                 CefRefPtr<CefFrame> frame) override {
    EXPECT_FALSE(got_load_end_);
    got_load_end_.yes();
    SignalCompleteIfDone(browser, frame);
    return true;
  }

  bool OnAfterCreated(CefRefPtr<CefBrowser> browser) override {
    EXPECT_FALSE(got_after_created_);
    got_after_created_.yes();
    return true;
  }

  bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
                      CefRefPtr<CefFrame> frame,
                      const std::string& url) override {
    EXPECT_FALSE(got_before_browse_);
    got_before_browse_.yes();
    return true;
  }

  bool GetResourceHandler(CefRefPtr<CefBrowser> browser,
                          CefRefPtr<CefFrame> frame) override {
    EXPECT_FALSE(got_get_resource_handler_);
    got_get_resource_handler_.yes();
    return true;
  }

  bool OnRendererComplete(CefRefPtr<CefBrowser> browser,
                          CefRefPtr<CefFrame> frame,
                          int renderer_nav,
                          bool renderer_result) override {
    EXPECT_EQ(nav(), renderer_nav);
    EXPECT_TRUE(renderer_result);
    EXPECT_FALSE(got_renderer_done_);
    got_renderer_done_.yes();
    SignalCompleteIfDone(browser, frame);
    return true;
  }

  bool Finalize() override {
    V_DECLARE();
    V_EXPECT_TRUE(got_load_start_);
    V_EXPECT_TRUE(got_load_end_);
    V_EXPECT_TRUE(got_loading_state_change_start_);
    V_EXPECT_TRUE(got_loading_state_change_end_);
    V_EXPECT_TRUE(got_renderer_done_);
    V_EXPECT_TRUE(got_after_created_);
    V_EXPECT_TRUE(got_before_browse_);
    V_EXPECT_TRUE(got_get_resource_handler_);
    V_EXPECT_FALSE(got_finalize_);

    got_finalize_.yes();

    V_RETURN();
  }

 private:
  void SignalCompleteIfDone(CefRefPtr<CefBrowser> browser,
                            CefRefPtr<CefFrame> frame) {
    if (got_renderer_done_ && got_load_end_ && got_loading_state_change_end_)
      SignalComplete(browser, frame);
  }

  TrackCallback got_load_start_;
  TrackCallback got_load_end_;
  TrackCallback got_loading_state_change_start_;
  TrackCallback got_loading_state_change_end_;
  TrackCallback got_renderer_done_;
  TrackCallback got_after_created_;
  TrackCallback got_before_browse_;
  TrackCallback got_get_resource_handler_;
  TrackCallback got_finalize_;
};

// Renderer process expectations for a single navigation.
class FrameNavExpectationsRendererSingleNav
    : public FrameNavExpectationsRenderer {
 public:
  explicit FrameNavExpectationsRendererSingleNav(int nav)
      : FrameNavExpectationsRenderer(nav) {}

  ~FrameNavExpectationsRendererSingleNav() override {
    EXPECT_TRUE(got_finalize_);
  }

  bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
                            bool isLoading) override {
    if (isLoading) {
      EXPECT_FALSE(got_loading_state_change_start_);
      got_loading_state_change_start_.yes();
    } else {
      EXPECT_FALSE(got_loading_state_change_end_);
      got_loading_state_change_end_.yes();
      SignalCompleteIfDone(browser, browser->GetMainFrame());
    }
    return true;
  }

  bool OnLoadStart(CefRefPtr<CefBrowser> browser,
                   CefRefPtr<CefFrame> frame) override {
    EXPECT_FALSE(got_load_start_);
    got_load_start_.yes();
    return true;
  }

  bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
                 CefRefPtr<CefFrame> frame) override {
    EXPECT_FALSE(got_load_end_);
    got_load_end_.yes();
    SignalCompleteIfDone(browser, frame);
    return true;
  }

  bool Finalize() override {
    V_DECLARE();
    V_EXPECT_TRUE(got_load_start_);
    V_EXPECT_TRUE(got_load_end_);
    V_EXPECT_TRUE(got_loading_state_change_start_);
    V_EXPECT_TRUE(got_loading_state_change_end_);
    V_EXPECT_FALSE(got_finalize_);

    got_finalize_.yes();

    V_RETURN();
  }

 private:
  void SignalCompleteIfDone(CefRefPtr<CefBrowser> browser,
                            CefRefPtr<CefFrame> frame) {
    if (got_load_end_ && got_loading_state_change_end_)
      SignalComplete(browser, frame);
  }

  TrackCallback got_load_start_;
  TrackCallback got_load_end_;
  TrackCallback got_loading_state_change_start_;
  TrackCallback got_loading_state_change_end_;
  TrackCallback got_finalize_;
};

// Test that the single nav harness works.
class FrameNavExpectationsBrowserTestSingleNavHarness
    : public FrameNavExpectationsBrowserSingleNav {
 public:
  typedef FrameNavExpectationsBrowserSingleNav parent;

  explicit FrameNavExpectationsBrowserTestSingleNavHarness(int nav)
      : parent(nav) {}

  ~FrameNavExpectationsBrowserTestSingleNavHarness() override {
    EXPECT_TRUE(got_finalize_);
  }

  std::string GetMainURL() override {
    EXPECT_FALSE(got_get_main_url_);
    got_get_main_url_.yes();
    return kFrameNavOrigin0;
  }

  std::string GetContentForURL(const std::string& url) override {
    EXPECT_FALSE(got_get_content_for_url_);
    got_get_content_for_url_.yes();
    EXPECT_STREQ(kFrameNavOrigin0, url.c_str());
    return "<html><body>Nav</body></html>";
  }

  bool Finalize() override {
    EXPECT_FALSE(got_finalize_);
    got_finalize_.yes();

    V_DECLARE();
    V_EXPECT_TRUE(got_get_main_url_);
    V_EXPECT_TRUE(got_get_content_for_url_);
    V_EXPECT_TRUE(parent::Finalize());
    V_RETURN();
  }

 private:
  TrackCallback got_get_main_url_;
  TrackCallback got_get_content_for_url_;
  TrackCallback got_finalize_;
};

class FrameNavExpectationsRendererTestSingleNavHarness
    : public FrameNavExpectationsRendererSingleNav {
 public:
  typedef FrameNavExpectationsRendererSingleNav parent;

  explicit FrameNavExpectationsRendererTestSingleNavHarness(int nav)
      : parent(nav) {}

  ~FrameNavExpectationsRendererTestSingleNavHarness() override {
    EXPECT_TRUE(got_finalize_);
  }

  bool Finalize() override {
    EXPECT_FALSE(got_finalize_);
    got_finalize_.yes();
    return parent::Finalize();
  }

 private:
  TrackCallback got_finalize_;
};

class FrameNavExpectationsFactoryBrowserTestSingleNavHarness
    : public FrameNavExpectationsFactoryBrowser {
 public:
  FrameNavExpectationsFactoryBrowserTestSingleNavHarness() {}

  ~FrameNavExpectationsFactoryBrowserTestSingleNavHarness() override {
    EXPECT_TRUE(got_finalize_);
  }

  FrameNavFactoryId GetID() const override { return FNF_ID_SINGLE_NAV_HARNESS; }

  bool HasMoreNavigations() const override {
    EXPECT_FALSE(got_get_browser_navigation_count_);
    got_get_browser_navigation_count_.yes();
    return false;
  }

  bool Finalize() override {
    EXPECT_FALSE(got_finalize_);
    got_finalize_.yes();

    V_DECLARE();
    V_EXPECT_TRUE(got_get_browser_navigation_count_);
    V_EXPECT_TRUE(got_create_);
    V_RETURN();
  }

 protected:
  scoped_ptr<FrameNavExpectationsBrowser> Create(int nav) override {
    EXPECT_FALSE(got_create_);
    got_create_.yes();
    return scoped_ptr<FrameNavExpectationsBrowser>(
        new FrameNavExpectationsBrowserTestSingleNavHarness(nav));
  }

 private:
  mutable TrackCallback got_get_browser_navigation_count_;
  TrackCallback got_create_;
  TrackCallback got_finalize_;
};

class FrameNavExpectationsFactoryRendererTestSingleNavHarness
    : public FrameNavExpectationsFactoryRenderer {
 public:
  FrameNavExpectationsFactoryRendererTestSingleNavHarness() {}

  FrameNavFactoryId GetID() const override { return FNF_ID_SINGLE_NAV_HARNESS; }

 protected:
  scoped_ptr<FrameNavExpectationsRenderer> Create(int nav) override {
    return scoped_ptr<FrameNavExpectationsRenderer>(
        new FrameNavExpectationsRendererTestSingleNavHarness(nav));
  }
};

}  // namespace

// Test that the single nav harness works.
FRAME_TEST(SingleNavHarness, FNF_ID_SINGLE_NAV_HARNESS)

namespace {

bool VerifySingleBrowserFrame(CefRefPtr<CefBrowser> browser,
                              CefRefPtr<CefFrame> frame,
                              const std::string& expected_url) {
  V_DECLARE();
  V_EXPECT_TRUE(frame.get());
  V_EXPECT_TRUE(frame->IsValid());
  const int64 frame_id = frame->GetIdentifier();
  V_EXPECT_TRUE(frame_id > 0) << frame_id;
  V_EXPECT_TRUE(frame->IsValid());
  V_EXPECT_TRUE(frame->IsMain());
  V_EXPECT_TRUE(frame->IsFocused());
  V_EXPECT_FALSE(frame->GetParent().get());
  V_EXPECT_TRUE(frame->GetName().empty());
  V_EXPECT_TRUE(browser->GetIdentifier() ==
                frame->GetBrowser()->GetIdentifier());

  const std::string& frame_url = frame->GetURL();
  V_EXPECT_TRUE(frame_url == expected_url)
      << "frame_url = " << frame_url << ", expected_url = " << expected_url;

  V_RETURN();
}

bool VerifySingleBrowserFrames(CefRefPtr<CefBrowser> browser,
                               CefRefPtr<CefFrame> frame,
                               const std::string& expected_url) {
  V_DECLARE();
  V_EXPECT_TRUE(browser.get());

  // |frame| may be nullptr for callbacks that don't specify one.
  if (frame.get()) {
    V_EXPECT_TRUE(VerifySingleBrowserFrame(browser, frame, expected_url));
  }

  CefRefPtr<CefFrame> main_frame = browser->GetMainFrame();
  V_EXPECT_TRUE(VerifySingleBrowserFrame(browser, main_frame, expected_url));

  CefRefPtr<CefFrame> focused_frame = browser->GetFocusedFrame();
  V_EXPECT_TRUE(VerifySingleBrowserFrame(browser, focused_frame, expected_url));

  size_t frame_count = browser->GetFrameCount();
  V_EXPECT_TRUE(frame_count == 1U);

  std::vector<int64> identifiers;
  browser->GetFrameIdentifiers(identifiers);
  V_EXPECT_TRUE(identifiers.size() == 1U);
  if (identifiers.size() == 1U) {
    V_EXPECT_TRUE(identifiers[0] == main_frame->GetIdentifier());
    V_EXPECT_TRUE(identifiers[0] == focused_frame->GetIdentifier());
  }

  // Names may be empty for callbacks that execute while the frame is loading.
  std::vector<CefString> names;
  browser->GetFrameNames(names);
  V_EXPECT_TRUE(names.size() <= 1U);
  if (names.size() == 1U) {
    V_EXPECT_TRUE(names[0].ToString() == main_frame->GetName().ToString());
    V_EXPECT_TRUE(names[0].ToString() == focused_frame->GetName().ToString());
  }

  V_RETURN();
}

// Test that single navigation works.
class FrameNavExpectationsBrowserTestSingleNav
    : public FrameNavExpectationsBrowserSingleNav {
 public:
  typedef FrameNavExpectationsBrowserSingleNav parent;

  explicit FrameNavExpectationsBrowserTestSingleNav(int nav) : parent(nav) {}

  std::string GetMainURL() override { return kFrameNavOrigin0; }

  std::string GetContentForURL(const std::string& url) override {
    return "<html><body>Nav</body></html>";
  }

  bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
                            bool isLoading) override {
    V_DECLARE();
    V_EXPECT_TRUE(VerifySingleBrowserFrames(
        browser, nullptr, isLoading ? std::string() : kFrameNavOrigin0));
    V_EXPECT_TRUE(parent::OnLoadingStateChange(browser, isLoading));
    V_RETURN();
  }

  bool OnLoadStart(CefRefPtr<CefBrowser> browser,
                   CefRefPtr<CefFrame> frame) override {
    V_DECLARE();
    V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, kFrameNavOrigin0));
    V_EXPECT_TRUE(parent::OnLoadStart(browser, frame));
    V_RETURN();
  }

  bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
                 CefRefPtr<CefFrame> frame) override {
    V_DECLARE();
    V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, kFrameNavOrigin0));
    V_EXPECT_TRUE(parent::OnLoadEnd(browser, frame));
    V_RETURN();
  }

  bool OnAfterCreated(CefRefPtr<CefBrowser> browser) override {
    V_DECLARE();
    V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, nullptr, std::string()));
    V_EXPECT_TRUE(parent::OnAfterCreated(browser));
    V_RETURN();
  }

  bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
                      CefRefPtr<CefFrame> frame,
                      const std::string& url) override {
    V_DECLARE();
    V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, std::string()));
    V_EXPECT_TRUE(parent::OnBeforeBrowse(browser, frame, url));
    V_RETURN();
  }

  bool GetResourceHandler(CefRefPtr<CefBrowser> browser,
                          CefRefPtr<CefFrame> frame) override {
    V_DECLARE();
    V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, std::string()));
    V_EXPECT_TRUE(parent::GetResourceHandler(browser, frame));
    V_RETURN();
  }

  bool OnRendererComplete(CefRefPtr<CefBrowser> browser,
                          CefRefPtr<CefFrame> frame,
                          int renderer_nav,
                          bool renderer_result) override {
    return parent::OnRendererComplete(browser, frame, renderer_nav,
                                      renderer_result);
  }

  bool Finalize() override { return parent::Finalize(); }
};

class FrameNavExpectationsRendererTestSingleNav
    : public FrameNavExpectationsRendererSingleNav {
 public:
  typedef FrameNavExpectationsRendererSingleNav parent;

  explicit FrameNavExpectationsRendererTestSingleNav(int nav) : parent(nav) {}

  bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
                            bool isLoading) override {
    V_DECLARE();
    // A frame should always exist in the renderer process.
    V_EXPECT_TRUE(
        VerifySingleBrowserFrames(browser, nullptr, kFrameNavOrigin0));
    V_EXPECT_TRUE(parent::OnLoadingStateChange(browser, isLoading));
    V_RETURN();
  }

  bool OnLoadStart(CefRefPtr<CefBrowser> browser,
                   CefRefPtr<CefFrame> frame) override {
    V_DECLARE();
    V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, kFrameNavOrigin0));
    V_EXPECT_TRUE(parent::OnLoadStart(browser, frame));
    V_RETURN();
  }

  bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
                 CefRefPtr<CefFrame> frame) override {
    V_DECLARE();
    V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, kFrameNavOrigin0));
    V_EXPECT_TRUE(parent::OnLoadEnd(browser, frame));
    V_RETURN();
  }

  bool Finalize() override { return parent::Finalize(); }
};

class FrameNavExpectationsFactoryBrowserTestSingleNav
    : public FrameNavExpectationsFactoryBrowser {
 public:
  FrameNavExpectationsFactoryBrowserTestSingleNav() {}

  FrameNavFactoryId GetID() const override { return FNF_ID_SINGLE_NAV; }

  bool HasMoreNavigations() const override { return false; }

  bool Finalize() override { return true; }

 protected:
  scoped_ptr<FrameNavExpectationsBrowser> Create(int nav) override {
    return scoped_ptr<FrameNavExpectationsBrowser>(
        new FrameNavExpectationsBrowserTestSingleNav(nav));
  }
};

class FrameNavExpectationsFactoryRendererTestSingleNav
    : public FrameNavExpectationsFactoryRenderer {
 public:
  FrameNavExpectationsFactoryRendererTestSingleNav() {}

  FrameNavFactoryId GetID() const override { return FNF_ID_SINGLE_NAV; }

 protected:
  scoped_ptr<FrameNavExpectationsRenderer> Create(int nav) override {
    return scoped_ptr<FrameNavExpectationsRenderer>(
        new FrameNavExpectationsRendererTestSingleNav(nav));
  }
};

}  // namespace

// Test that single navigation works.
FRAME_TEST(SingleNav, FNF_ID_SINGLE_NAV)

namespace {

// Browser process expectations for a multiple navigations.
class FrameNavExpectationsBrowserMultiNav : public FrameNavExpectationsBrowser {
 public:
  explicit FrameNavExpectationsBrowserMultiNav(int nav)
      : FrameNavExpectationsBrowser(nav) {}

  ~FrameNavExpectationsBrowserMultiNav() override {
    EXPECT_TRUE(got_finalize_);
  }

  // Returns true if all navigation is done.
  virtual bool IsNavigationDone() const = 0;

  bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
                            bool isLoading) override {
    if (!isLoading)
      SignalCompleteIfDone(browser, browser->GetMainFrame());
    return true;
  }

  bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
                 CefRefPtr<CefFrame> frame) override {
    SignalCompleteIfDone(browser, frame);
    return true;
  }

  bool OnRendererComplete(CefRefPtr<CefBrowser> browser,
                          CefRefPtr<CefFrame> frame,
                          int renderer_nav,
                          bool renderer_result) override {
    EXPECT_TRUE(renderer_result);
    SignalCompleteIfDone(browser, frame);
    return true;
  }

  bool Finalize() override {
    V_DECLARE();
    V_EXPECT_FALSE(got_finalize_);

    got_finalize_.yes();

    V_RETURN();
  }

 private:
  void SignalCompleteIfDone(CefRefPtr<CefBrowser> browser,
                            CefRefPtr<CefFrame> frame) {
    if (IsNavigationDone())
      SignalComplete(browser, frame);
  }

  TrackCallback got_finalize_;
};

// Renderer process expectations for a multiple navigations.
class FrameNavExpectationsRendererMultiNav
    : public FrameNavExpectationsRenderer {
 public:
  explicit FrameNavExpectationsRendererMultiNav(int nav)
      : FrameNavExpectationsRenderer(nav) {}

  ~FrameNavExpectationsRendererMultiNav() override {
    EXPECT_TRUE(got_finalize_);
  }

  // Returns true if all navigation is done.
  virtual bool IsNavigationDone() const = 0;

  bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
                            bool isLoading) override {
    if (!isLoading)
      SignalCompleteIfDone(browser, browser->GetMainFrame());
    return true;
  }

  bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
                 CefRefPtr<CefFrame> frame) override {
    SignalCompleteIfDone(browser, frame);
    return true;
  }

  bool Finalize() override {
    V_DECLARE();
    V_EXPECT_FALSE(got_finalize_);

    got_finalize_.yes();

    V_RETURN();
  }

 private:
  void SignalCompleteIfDone(CefRefPtr<CefBrowser> browser,
                            CefRefPtr<CefFrame> frame) {
    if (IsNavigationDone())
      SignalComplete(browser, frame);
  }

  TrackCallback got_finalize_;
};

// Create a URL containing the nav number.
std::string GetMultiNavURL(const std::string& origin, int nav) {
  std::stringstream ss;
  ss << origin << "nav" << nav << ".html";
  return ss.str();
}

// Extract the nav number from the URL.
int GetNavFromMultiNavURL(const std::string& url) {
  const size_t start = url.find("/nav");
  const size_t end = url.find(".html", start);
  EXPECT_TRUE(start < end && start > 0U);
  const std::string& nav = url.substr(start + 4, end - start - 4);
  return atoi(nav.c_str());
}

// Extract the origin from the URL.
std::string GetOriginFromMultiNavURL(const std::string& url) {
  const size_t pos = url.rfind("/");
  EXPECT_TRUE(pos > 0U);
  return url.substr(0, pos + 1);
}

// Test that the multi nav harness works.
class FrameNavExpectationsBrowserTestMultiNavHarness
    : public FrameNavExpectationsBrowserMultiNav {
 public:
  typedef FrameNavExpectationsBrowserMultiNav parent;

  explicit FrameNavExpectationsBrowserTestMultiNavHarness(int nav)
      : parent(nav), navigation_done_count_(0) {}

  ~FrameNavExpectationsBrowserTestMultiNavHarness() override {
    EXPECT_TRUE(got_finalize_);
  }

  std::string GetMainURL() override {
    EXPECT_FALSE(got_get_main_url_);
    got_get_main_url_.yes();
    return GetMultiNavURL(kFrameNavOrigin0, nav());
  }

  std::string GetContentForURL(const std::string& url) override {
    EXPECT_FALSE(got_get_content_for_url_);
    got_get_content_for_url_.yes();
    EXPECT_STREQ(GetMultiNavURL(kFrameNavOrigin0, nav()).c_str(), url.c_str());
    return "<html><body>Nav</body></html>";
  }

  bool IsNavigationDone() const override {
    navigation_done_count_++;
    return got_load_state_change_done_ && got_load_end_ &&
           got_renderer_complete_;
  }

  bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
                            bool isLoading) override {
    if (!isLoading) {
      EXPECT_FALSE(got_load_state_change_done_);
      got_load_state_change_done_.yes();
    }
    return parent::OnLoadingStateChange(browser, isLoading);
  }

  bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
                 CefRefPtr<CefFrame> frame) override {
    EXPECT_FALSE(got_load_end_);
    got_load_end_.yes();
    return parent::OnLoadEnd(browser, frame);
  }

  bool OnAfterCreated(CefRefPtr<CefBrowser> browser) override {
    EXPECT_FALSE(got_on_after_created_);
    got_on_after_created_.yes();
    return parent::OnAfterCreated(browser);
  }

  bool OnRendererComplete(CefRefPtr<CefBrowser> browser,
                          CefRefPtr<CefFrame> frame,
                          int renderer_nav,
                          bool renderer_result) override {
    EXPECT_FALSE(got_renderer_complete_);
    got_renderer_complete_.yes();
    EXPECT_EQ(nav(), renderer_nav);
    return parent::OnRendererComplete(browser, frame, renderer_nav,
                                      renderer_result);
  }

  bool Finalize() override {
    EXPECT_FALSE(got_finalize_);
    got_finalize_.yes();

    V_DECLARE();
    V_EXPECT_TRUE(got_get_main_url_);
    V_EXPECT_TRUE(got_get_content_for_url_);
    V_EXPECT_TRUE(got_load_state_change_done_);
    V_EXPECT_TRUE(got_load_end_);
    if (nav() == 0) {
      V_EXPECT_TRUE(got_on_after_created_);
    } else {
      V_EXPECT_FALSE(got_on_after_created_);
    }
    V_EXPECT_TRUE(got_renderer_complete_);
    V_EXPECT_TRUE(navigation_done_count_ == 3);
    V_EXPECT_TRUE(parent::Finalize());
    V_RETURN();
  }

 private:
  TrackCallback got_get_main_url_;
  TrackCallback got_get_content_for_url_;
  TrackCallback got_load_state_change_done_;
  TrackCallback got_load_end_;
  TrackCallback got_on_after_created_;
  TrackCallback got_renderer_complete_;
  mutable int navigation_done_count_;
  TrackCallback got_finalize_;
};

class FrameNavExpectationsRendererTestMultiNavHarness
    : public FrameNavExpectationsRendererMultiNav {
 public:
  typedef FrameNavExpectationsRendererMultiNav parent;

  explicit FrameNavExpectationsRendererTestMultiNavHarness(int nav)
      : parent(nav), navigation_done_count_(0) {}

  ~FrameNavExpectationsRendererTestMultiNavHarness() override {
    EXPECT_TRUE(got_finalize_);
  }

  bool IsNavigationDone() const override {
    navigation_done_count_++;
    return got_load_state_change_done_ && got_load_end_;
  }

  bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
                            bool isLoading) override {
    if (!isLoading) {
      EXPECT_FALSE(got_load_state_change_done_);
      got_load_state_change_done_.yes();
    }
    return parent::OnLoadingStateChange(browser, isLoading);
  }

  bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
                 CefRefPtr<CefFrame> frame) override {
    EXPECT_FALSE(got_load_end_);
    got_load_end_.yes();
    return parent::OnLoadEnd(browser, frame);
  }

  bool Finalize() override {
    EXPECT_FALSE(got_finalize_);
    got_finalize_.yes();

    V_DECLARE();
    V_EXPECT_TRUE(got_load_state_change_done_);
    V_EXPECT_TRUE(got_load_end_);
    V_EXPECT_TRUE(navigation_done_count_ == 2);
    V_EXPECT_TRUE(parent::Finalize());
    V_RETURN();
  }

 private:
  TrackCallback got_load_state_change_done_;
  TrackCallback got_load_end_;
  mutable int navigation_done_count_;
  TrackCallback got_finalize_;
};

class FrameNavExpectationsFactoryBrowserTestMultiNavHarness
    : public FrameNavExpectationsFactoryBrowser {
 public:
  FrameNavExpectationsFactoryBrowserTestMultiNavHarness()
      : get_browser_navigation_count_(0), create_count_(0) {}

  ~FrameNavExpectationsFactoryBrowserTestMultiNavHarness() override {
    EXPECT_TRUE(got_finalize_);
  }

  FrameNavFactoryId GetID() const override { return FNF_ID_MULTI_NAV_HARNESS; }

  bool HasMoreNavigations() const override {
    get_browser_navigation_count_++;
    return (get_browser_navigation_count_ < kMaxMultiNavNavigations);
  }

  bool Finalize() override {
    EXPECT_FALSE(got_finalize_);
    got_finalize_.yes();

    V_DECLARE();
    V_EXPECT_TRUE(get_browser_navigation_count_ == kMaxMultiNavNavigations);
    V_EXPECT_TRUE(create_count_ == kMaxMultiNavNavigations);
    V_RETURN();
  }

 protected:
  scoped_ptr<FrameNavExpectationsBrowser> Create(int nav) override {
    create_count_++;
    return scoped_ptr<FrameNavExpectationsBrowser>(
        new FrameNavExpectationsBrowserTestMultiNavHarness(nav));
  }

 private:
  mutable int get_browser_navigation_count_;
  int create_count_;
  TrackCallback got_finalize_;
};

class FrameNavExpectationsFactoryRendererTestMultiNavHarness
    : public FrameNavExpectationsFactoryRenderer {
 public:
  FrameNavExpectationsFactoryRendererTestMultiNavHarness() {}

  FrameNavFactoryId GetID() const override { return FNF_ID_MULTI_NAV_HARNESS; }

 protected:
  scoped_ptr<FrameNavExpectationsRenderer> Create(int nav) override {
    return scoped_ptr<FrameNavExpectationsRenderer>(
        new FrameNavExpectationsRendererTestMultiNavHarness(nav));
  }
};

}  // namespace

// Test that the multiple nav harness works.
FRAME_TEST(MultiNavHarness, FNF_ID_MULTI_NAV_HARNESS)

namespace {

// Test that multiple navigation works.
class FrameNavExpectationsBrowserTestMultiNav
    : public FrameNavExpectationsBrowserMultiNav {
 public:
  typedef FrameNavExpectationsBrowserMultiNav parent;

  explicit FrameNavExpectationsBrowserTestMultiNav(int nav) : parent(nav) {}

  std::string GetMainURL() override {
    return GetMultiNavURL(kFrameNavOrigin0, nav());
  }

  std::string GetContentForURL(const std::string& url) override {
    return "<html><body>Nav</body></html>";
  }

  bool IsNavigationDone() const override {
    return got_load_state_change_done_ && got_load_end_ &&
           got_renderer_complete_;
  }

  bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
                            bool isLoading) override {
    if (!isLoading)
      got_load_state_change_done_.yes();
    V_DECLARE();
    if (isLoading && nav() == 0) {
      V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, nullptr, std::string()));
    } else if (isLoading) {
      // Expect the URL from the previous load.
      V_EXPECT_TRUE(
          VerifySingleBrowserFrames(browser, nullptr, GetPreviousMainURL()));
    } else {
      V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, nullptr, GetMainURL()));
    }
    V_EXPECT_TRUE(parent::OnLoadingStateChange(browser, isLoading));
    V_RETURN();
  }

  bool OnLoadStart(CefRefPtr<CefBrowser> browser,
                   CefRefPtr<CefFrame> frame) override {
    V_DECLARE();
    V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, GetMainURL()));
    V_EXPECT_TRUE(parent::OnLoadStart(browser, frame));
    V_RETURN();
  }

  bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
                 CefRefPtr<CefFrame> frame) override {
    got_load_end_.yes();
    V_DECLARE();
    V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, GetMainURL()));
    V_EXPECT_TRUE(parent::OnLoadEnd(browser, frame));
    V_RETURN();
  }

  bool OnAfterCreated(CefRefPtr<CefBrowser> browser) override {
    V_DECLARE();
    V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, nullptr, std::string()));
    V_EXPECT_TRUE(parent::OnAfterCreated(browser));
    V_RETURN();
  }

  bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
                      CefRefPtr<CefFrame> frame,
                      const std::string& url) override {
    V_DECLARE();
    std::string expected_url;
    if (nav() > 0)
      expected_url = GetPreviousMainURL();
    V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, expected_url));
    V_EXPECT_TRUE(parent::OnBeforeBrowse(browser, frame, url));
    V_RETURN();
  }

  bool GetResourceHandler(CefRefPtr<CefBrowser> browser,
                          CefRefPtr<CefFrame> frame) override {
    V_DECLARE();
    std::string expected_url;
    if (nav() > 0)
      expected_url = GetPreviousMainURL();
    V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, expected_url));
    V_EXPECT_TRUE(parent::GetResourceHandler(browser, frame));
    V_RETURN();
  }

  bool OnRendererComplete(CefRefPtr<CefBrowser> browser,
                          CefRefPtr<CefFrame> frame,
                          int renderer_nav,
                          bool renderer_result) override {
    got_renderer_complete_.yes();
    V_DECLARE();
    V_EXPECT_TRUE(nav() == renderer_nav);
    V_EXPECT_TRUE(parent::OnRendererComplete(browser, frame, renderer_nav,
                                             renderer_result));
    V_RETURN();
  }

  bool Finalize() override {
    V_DECLARE();
    V_EXPECT_TRUE(got_load_state_change_done_);
    V_EXPECT_TRUE(got_load_end_);
    V_EXPECT_TRUE(got_renderer_complete_);
    V_EXPECT_TRUE(parent::Finalize());
    V_RETURN();
  }

 private:
  // Helper for VerifySingleBrowserFrames.
  std::string GetPreviousMainURL() {
    EXPECT_GT(nav(), 0);
    return GetMultiNavURL(kFrameNavOrigin0, nav() - 1);
  }

  TrackCallback got_load_state_change_done_;
  TrackCallback got_load_end_;
  TrackCallback got_renderer_complete_;
};

class FrameNavExpectationsRendererTestMultiNav
    : public FrameNavExpectationsRendererMultiNav {
 public:
  typedef FrameNavExpectationsRendererMultiNav parent;

  explicit FrameNavExpectationsRendererTestMultiNav(int nav) : parent(nav) {}

  bool IsNavigationDone() const override {
    return got_load_state_change_done_ && got_load_end_;
  }

  bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
                            bool isLoading) override {
    if (!isLoading)
      got_load_state_change_done_.yes();
    V_DECLARE();
    V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, nullptr, GetMainURL()));
    V_EXPECT_TRUE(parent::OnLoadingStateChange(browser, isLoading));
    V_RETURN();
  }

  bool OnLoadStart(CefRefPtr<CefBrowser> browser,
                   CefRefPtr<CefFrame> frame) override {
    V_DECLARE();
    V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, GetMainURL()));
    V_EXPECT_TRUE(parent::OnLoadStart(browser, frame));
    V_RETURN();
  }

  bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
                 CefRefPtr<CefFrame> frame) override {
    got_load_end_.yes();
    V_DECLARE();
    V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, GetMainURL()));
    V_EXPECT_TRUE(parent::OnLoadEnd(browser, frame));
    V_RETURN();
  }

  bool Finalize() override {
    V_DECLARE();
    V_EXPECT_TRUE(got_load_state_change_done_);
    V_EXPECT_TRUE(got_load_end_);
    V_EXPECT_TRUE(parent::Finalize());
    V_RETURN();
  }

 private:
  // Helpers for calling VerifySingleBrowserFrames.
  std::string GetMainURL() const {
    return GetMultiNavURL(kFrameNavOrigin0, nav());
  }
  std::string GetPreviousMainURL() {
    EXPECT_GT(nav(), 0);
    return GetMultiNavURL(kFrameNavOrigin0, nav() - 1);
  }

  TrackCallback got_load_state_change_done_;
  TrackCallback got_load_end_;
};

class FrameNavExpectationsFactoryBrowserTestMultiNav
    : public FrameNavExpectationsFactoryBrowser {
 public:
  FrameNavExpectationsFactoryBrowserTestMultiNav() : nav_count_(0) {}

  FrameNavFactoryId GetID() const override { return FNF_ID_MULTI_NAV; }

  bool HasMoreNavigations() const override {
    return (nav_count_ < kMaxMultiNavNavigations);
  }

  bool Finalize() override {
    V_DECLARE();
    V_EXPECT_TRUE(nav_count_ == kMaxMultiNavNavigations);
    V_RETURN();
  }

 protected:
  scoped_ptr<FrameNavExpectationsBrowser> Create(int nav) override {
    nav_count_++;
    return scoped_ptr<FrameNavExpectationsBrowser>(
        new FrameNavExpectationsBrowserTestMultiNav(nav));
  }

 private:
  int nav_count_;
};

class FrameNavExpectationsFactoryRendererTestMultiNav
    : public FrameNavExpectationsFactoryRenderer {
 public:
  FrameNavExpectationsFactoryRendererTestMultiNav() {}

  FrameNavFactoryId GetID() const override { return FNF_ID_MULTI_NAV; }

 protected:
  scoped_ptr<FrameNavExpectationsRenderer> Create(int nav) override {
    return scoped_ptr<FrameNavExpectationsRenderer>(
        new FrameNavExpectationsRendererTestMultiNav(nav));
  }
};

}  // namespace

// Test that multiple navigation works.
FRAME_TEST(MultiNav, FNF_ID_MULTI_NAV)

namespace {

const char kFrame0Name[] = "";
const char kFrame1Name[] = "nav2";
const char kFrame2Name[] = "<!--framePath //nav2/<!--frame0-->-->";
const char kFrame3Name[] = "nav3";

bool VerifyBrowserIframe(CefRefPtr<CefBrowser> browser,
                         CefRefPtr<CefFrame> frame,
                         const std::string& origin,
                         int frame_number) {
  V_DECLARE();

  // frame0 contains frame1 contains frame2, contains frame3.
  CefRefPtr<CefFrame> frame0, frame1, frame2, frame3;
  CefRefPtr<CefFrame> frame0b, frame1b, frame2b, frame3b;
  int64 frame0id, frame1id, frame2id, frame3id;
  std::string frame0url, frame1url, frame2url, frame3url;

  // Verify the GetFrameNames result.
  std::set<std::string> expected_names = {kFrame0Name, kFrame1Name, kFrame2Name,
                                          kFrame3Name};

  std::vector<CefString> names;
  browser->GetFrameNames(names);
  V_EXPECT_TRUE(names.size() == expected_names.size())
      << "expected: " << expected_names.size() << " actual: " << names.size();

  for (const auto& name : names) {
    const std::string& nameStr = name;
    auto it = expected_names.find(nameStr);
    V_EXPECT_FALSE(it == expected_names.end())
        << "Unexpected name: \"" << nameStr << "\"";
    if (it != expected_names.end())
      expected_names.erase(it);
  }

  for (const auto& name : expected_names) {
    V_EXPECT_FALSE(true) << "Missing name: \"" << name << "\"";
  }

  // Find frames by name.
  frame0 = browser->GetFrame(kFrame0Name);
  V_EXPECT_TRUE(frame0.get());
  frame1 = browser->GetFrame(kFrame1Name);
  V_EXPECT_TRUE(frame1.get());
  frame2 = browser->GetFrame(kFrame2Name);
  V_EXPECT_TRUE(frame2.get());
  frame3 = browser->GetFrame(kFrame3Name);
  V_EXPECT_TRUE(frame3.get());

  if (!frame0 || !frame1 || !frame2 || !frame3) {
    V_RETURN();
  }

  // Verify that the name matches.
  V_EXPECT_TRUE(frame0->GetName().ToString() == kFrame0Name)
      << "expected: " << kFrame0Name
      << " actual: " << frame0->GetName().ToString();
  V_EXPECT_TRUE(frame1->GetName().ToString() == kFrame1Name)
      << "expected: " << kFrame1Name
      << " actual: " << frame1->GetName().ToString();
  V_EXPECT_TRUE(frame2->GetName().ToString() == kFrame2Name)
      << "expected: " << kFrame2Name
      << " actual: " << frame2->GetName().ToString();
  V_EXPECT_TRUE(frame3->GetName().ToString() == kFrame3Name)
      << "expected: " << kFrame3Name
      << " actual: " << frame3->GetName().ToString();

  // Verify that the URL matches.
  frame0url = GetMultiNavURL(origin, 0);
  V_EXPECT_TRUE(frame0->GetURL() == frame0url)
      << "expected: " << frame0url
      << " actual: " << frame0->GetURL().ToString();
  frame1url = GetMultiNavURL(origin, 1);
  V_EXPECT_TRUE(frame1->GetURL() == frame1url)
      << "expected: " << frame1url
      << " actual: " << frame1->GetURL().ToString();
  frame2url = GetMultiNavURL(origin, 2);
  V_EXPECT_TRUE(frame2->GetURL() == frame2url)
      << "expected: " << frame2url
      << " actual: " << frame2->GetURL().ToString();
  frame3url = GetMultiNavURL(origin, 3);
  V_EXPECT_TRUE(frame3->GetURL() == frame3url)
      << "expected: " << frame3url
      << " actual: " << frame3->GetURL().ToString();

  // Verify that the frame id is valid.
  frame0id = frame0->GetIdentifier();
  V_EXPECT_TRUE(frame0id > 0) << "actual: " << frame0id;
  frame1id = frame1->GetIdentifier();
  V_EXPECT_TRUE(frame1id > 0) << "actual: " << frame1id;
  frame2id = frame2->GetIdentifier();
  V_EXPECT_TRUE(frame2id > 0) << "actual: " << frame2id;
  frame3id = frame3->GetIdentifier();
  V_EXPECT_TRUE(frame3id > 0) << "actual: " << frame3id;

  // Verify that the current frame has the correct id.
  if (frame_number == 0) {
    V_EXPECT_TRUE(frame->GetIdentifier() == frame0id)
        << "expected: " << frame0id << " actual: " << frame->GetIdentifier();
  } else if (frame_number == 1) {
    V_EXPECT_TRUE(frame->GetIdentifier() == frame1id)
        << "expected: " << frame1id << " actual: " << frame->GetIdentifier();
  } else if (frame_number == 2) {
    V_EXPECT_TRUE(frame->GetIdentifier() == frame2id)
        << "expected: " << frame2id << " actual: " << frame->GetIdentifier();
  } else if (frame_number == 3) {
    V_EXPECT_TRUE(frame->GetIdentifier() == frame3id)
        << "expected: " << frame3id << " actual: " << frame->GetIdentifier();
  }

  // Find frames by id.
  frame0b = browser->GetFrame(frame0->GetIdentifier());
  V_EXPECT_TRUE(frame0b.get());
  frame1b = browser->GetFrame(frame1->GetIdentifier());
  V_EXPECT_TRUE(frame1b.get());
  frame2b = browser->GetFrame(frame2->GetIdentifier());
  V_EXPECT_TRUE(frame2b.get());
  frame3b = browser->GetFrame(frame3->GetIdentifier());
  V_EXPECT_TRUE(frame3b.get());

  if (!frame0b || !frame1b || !frame2b || !frame3b) {
    V_RETURN();
  }

  // Verify that the id matches.
  V_EXPECT_TRUE(frame0b->GetIdentifier() == frame0id)
      << "expected: " << frame0id << " actual: " << frame0b->GetIdentifier();
  V_EXPECT_TRUE(frame1b->GetIdentifier() == frame1id)
      << "expected: " << frame1id << " actual: " << frame1b->GetIdentifier();
  V_EXPECT_TRUE(frame2b->GetIdentifier() == frame2id)
      << "expected: " << frame2id << " actual: " << frame2b->GetIdentifier();
  V_EXPECT_TRUE(frame3b->GetIdentifier() == frame3id)
      << "expected: " << frame3id << " actual: " << frame3b->GetIdentifier();

  size_t frame_count = browser->GetFrameCount();
  V_EXPECT_TRUE(frame_count == 4U) << " actual: " << frame_count;

  // Verify the GetFrameIdentifiers result.
  std::set<int64> expected_idents = {frame0id, frame1id, frame2id, frame3id};

  std::vector<int64> idents;
  browser->GetFrameIdentifiers(idents);
  V_EXPECT_TRUE(idents.size() == expected_idents.size())
      << "expected: " << expected_idents.size() << " actual: " << idents.size();

  for (const auto& ident : idents) {
    auto it = expected_idents.find(ident);
    V_EXPECT_FALSE(it == expected_idents.end()) << "Unexpected id: " << ident;
    if (it != expected_idents.end())
      expected_idents.erase(it);
  }

  for (const auto& ident : expected_idents) {
    V_EXPECT_FALSE(true) << "Missing id: " << ident;
  }

  // Verify parent hierarchy.
  V_EXPECT_FALSE(frame0->GetParent().get());
  V_EXPECT_TRUE(frame1->GetParent()->GetIdentifier() == frame0id)
      << "expected: " << frame0id
      << " actual: " << frame1->GetParent()->GetIdentifier();
  V_EXPECT_TRUE(frame2->GetParent()->GetIdentifier() == frame1id)
      << "expected: " << frame1id
      << " actual: " << frame2->GetParent()->GetIdentifier();
  V_EXPECT_TRUE(frame3->GetParent()->GetIdentifier() == frame2id)
      << "expected: " << frame2id
      << " actual: " << frame3->GetParent()->GetIdentifier();

  V_RETURN();
}

// Test that nested iframes work.
class FrameNavExpectationsBrowserTestNestedIframes
    : public FrameNavExpectationsBrowserMultiNav {
 public:
  typedef FrameNavExpectationsBrowserMultiNav parent;

  FrameNavExpectationsBrowserTestNestedIframes(int nav, bool same_origin)
      : parent(nav), same_origin_(same_origin) {
    // In the browser process we can rely on the |nav| value to determine the
    // origin.
    if (same_origin) {
      origin_ = kFrameNavOrigin0;
    } else {
      switch (nav) {
        case 0:
          origin_ = kFrameNavOrigin0;
          break;
        case 1:
          origin_ = kFrameNavOrigin1;
          break;
        case 2:
          origin_ = kFrameNavOrigin2;
          break;
        case 3:
          origin_ = kFrameNavOrigin3;
          break;
        default:
          EXPECT_TRUE(false);  // Not reached.
          break;
      }
    }
  }

  std::string GetMainURL() override {
    // Load the first (main) frame.
    return GetMultiNavURL(origin_, 0);
  }

  std::string GetContentForURL(const std::string& url) override {
    const int frame_number = GetNavFromMultiNavURL(url);
    switch (frame_number) {
      case 0:
        // Frame 0. Contains a named iframe.
        return "<html><body>Nav1<iframe src=\"" + GetMultiNavURL(origin_, 1) +
               "\" name=\"nav2\"></body></html>";
      case 1:
        // Frame 1. Contains an unnamed iframe.
        return "<html><body>Nav2<iframe src=\"" + GetMultiNavURL(origin_, 2) +
               "\"></body></html>";
      case 2: {
        // Frame 2. Contains an named iframe created via javascript.
        std::stringstream ss;
        ss << "<html><script>"
           << "  function createFrame() {"
           << "    var f = document.createElement('iframe');"
           << "    f.name = 'nav3';"
           << "    f.src = '" << GetMultiNavURL(origin_, 3) << "';"
           << "    document.body.appendChild(f);"
           << "  }</script><body onload=\"createFrame()\">Nav3</body></html>";
        return ss.str();
      }
      case 3:
        // Frame 3.
        return "<html><body>Nav4</body></html>";
      default:
        EXPECT_TRUE(false);  // Not reached.
        return "";
    }
  }

  bool IsNavigationDone() const override {
    return got_load_state_change_done_ && got_renderer_complete_ &&
           got_load_end_[0] && got_load_end_[1] && got_load_end_[2] &&
           got_load_end_[3];
  }

  bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
                      CefRefPtr<CefFrame> frame,
                      const std::string& url) override {
    V_DECLARE();
    V_EXPECT_TRUE(frame.get());
    const int frame_number = GetNavFromMultiNavURL(url);
    if (frame_number == 0) {
      // Main frame.
      V_EXPECT_TRUE(frame->IsMain());
    } else {
      // Sub frame.
      V_EXPECT_FALSE(frame->IsMain());
    }
    V_EXPECT_TRUE(parent::OnBeforeBrowse(browser, frame, url));
    V_RETURN();
  }

  bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
                            bool isLoading) override {
    V_DECLARE();
    V_EXPECT_FALSE(got_load_state_change_done_);

    if (!isLoading) {
      got_load_state_change_done_.yes();
    }

    V_EXPECT_TRUE(parent::OnLoadingStateChange(browser, isLoading));
    V_RETURN();
  }

  bool OnLoadStart(CefRefPtr<CefBrowser> browser,
                   CefRefPtr<CefFrame> frame) override {
    const int frame_number = GetNavFromMultiNavURL(frame->GetURL());

    V_DECLARE();
    V_EXPECT_FALSE(got_load_start_[frame_number]);
    V_EXPECT_FALSE(got_load_end_[frame_number]);

    // Notification should be received for parent frame before child frame.
    if (frame_number == 0) {
      V_EXPECT_FALSE(got_load_start_[1]);
      V_EXPECT_FALSE(got_load_start_[2]);
      V_EXPECT_FALSE(got_load_start_[3]);
    } else if (frame_number == 1) {
      V_EXPECT_TRUE(got_load_start_[0]);
      V_EXPECT_FALSE(got_load_start_[2]);
      V_EXPECT_FALSE(got_load_start_[3]);
    } else if (frame_number == 2) {
      V_EXPECT_TRUE(got_load_start_[0]);
      V_EXPECT_TRUE(got_load_start_[1]);
      V_EXPECT_FALSE(got_load_start_[3]);
    } else if (frame_number == 3) {
      V_EXPECT_TRUE(got_load_start_[0]);
      V_EXPECT_TRUE(got_load_start_[1]);
      V_EXPECT_TRUE(got_load_start_[2]);
    } else {
      V_EXPECT_TRUE(false);  // Not reached.
    }

    got_load_start_[frame_number].yes();

    V_EXPECT_TRUE(parent::OnLoadStart(browser, frame));
    V_RETURN();
  }

  bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
                 CefRefPtr<CefFrame> frame) override {
    const int frame_number = GetNavFromMultiNavURL(frame->GetURL());

    V_DECLARE();
    V_EXPECT_TRUE(got_load_start_[frame_number]);
    V_EXPECT_FALSE(got_load_end_[frame_number]);

    // Notification should be received for child frame before parent frame.
    if (frame_number == 0) {
      V_EXPECT_TRUE(got_load_end_[1]);
      V_EXPECT_TRUE(got_load_end_[2]);
      V_EXPECT_TRUE(got_load_end_[3]);
    } else if (frame_number == 1) {
      V_EXPECT_FALSE(got_load_end_[0]);
      V_EXPECT_TRUE(got_load_end_[2]);
      V_EXPECT_TRUE(got_load_end_[3]);
    } else if (frame_number == 2) {
      V_EXPECT_FALSE(got_load_end_[0]);
      V_EXPECT_FALSE(got_load_end_[1]);
      V_EXPECT_TRUE(got_load_end_[3]);
    } else if (frame_number == 3) {
      V_EXPECT_FALSE(got_load_end_[0]);
      V_EXPECT_FALSE(got_load_end_[1]);
      V_EXPECT_FALSE(got_load_end_[2]);
    } else {
      V_EXPECT_TRUE(false);  // Not reached.
    }

    V_EXPECT_TRUE(VerifyBrowserIframe(browser, frame, origin_, frame_number))
        << "frame_number = " << frame_number;

    got_load_end_[frame_number].yes();

    V_EXPECT_TRUE(parent::OnLoadEnd(browser, frame));
    V_RETURN();
  }

  bool OnRendererComplete(CefRefPtr<CefBrowser> browser,
                          CefRefPtr<CefFrame> frame,
                          int renderer_nav,
                          bool renderer_result) override {
    V_DECLARE();
    V_EXPECT_FALSE(got_renderer_complete_);
    if (same_origin_) {
      V_EXPECT_TRUE(renderer_nav == nav());
    } else {
      // Because each navigation is in a new renderer process.
      V_EXPECT_TRUE(renderer_nav == 0);
    }

    got_renderer_complete_.yes();

    V_EXPECT_TRUE(parent::OnRendererComplete(browser, frame, renderer_nav,
                                             renderer_result));
    V_RETURN();
  }

  bool Finalize() override {
    V_DECLARE();
    V_EXPECT_TRUE(got_load_state_change_done_);
    V_EXPECT_TRUE(got_load_start_[0]);
    V_EXPECT_TRUE(got_load_start_[1]);
    V_EXPECT_TRUE(got_load_start_[2]);
    V_EXPECT_TRUE(got_load_start_[3]);
    V_EXPECT_TRUE(got_load_end_[0]);
    V_EXPECT_TRUE(got_load_end_[1]);
    V_EXPECT_TRUE(got_load_end_[2]);
    V_EXPECT_TRUE(got_load_end_[3]);
    V_EXPECT_TRUE(got_renderer_complete_);
    V_EXPECT_TRUE(parent::Finalize());
    V_RETURN();
  }

 private:
  bool same_origin_;
  std::string origin_;

  TrackCallback got_load_state_change_done_;
  TrackCallback got_load_start_[4];
  TrackCallback got_load_end_[4];
  TrackCallback got_renderer_complete_;
};

class FrameNavExpectationsRendererTestNestedIframes
    : public FrameNavExpectationsRendererMultiNav {
 public:
  typedef FrameNavExpectationsRendererMultiNav parent;

  FrameNavExpectationsRendererTestNestedIframes(int nav, bool same_origin)
      : parent(nav) {
    if (same_origin)
      origin_ = kFrameNavOrigin0;
  }

  bool IsNavigationDone() const override {
    return got_load_state_change_done_ && got_load_end_[0] &&
           got_load_end_[1] && got_load_end_[2] && got_load_end_[3];
  }

  bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
                            bool isLoading) override {
    V_DECLARE();
    V_EXPECT_FALSE(got_load_state_change_done_);

    if (!isLoading) {
      got_load_state_change_done_.yes();
    }

    V_EXPECT_TRUE(parent::OnLoadingStateChange(browser, isLoading));
    V_RETURN();
  }

  bool OnLoadStart(CefRefPtr<CefBrowser> browser,
                   CefRefPtr<CefFrame> frame) override {
    if (origin_.empty()) {
      // When navigating different origins we can't rely on the nav() value
      // because each navigation creates a new renderer process. Get the origin
      // by parsing the URL instead.
      origin_ = GetOriginFromMultiNavURL(browser->GetMainFrame()->GetURL());
    }

    const int frame_number = GetNavFromMultiNavURL(frame->GetURL());

    V_DECLARE();
    V_EXPECT_FALSE(got_load_start_[frame_number]);
    V_EXPECT_FALSE(got_load_end_[frame_number]);

    // Notification should be received for parent frame before child frame.
    if (frame_number == 0) {
      V_EXPECT_FALSE(got_load_start_[1]);
      V_EXPECT_FALSE(got_load_start_[2]);
      V_EXPECT_FALSE(got_load_start_[3]);
    } else if (frame_number == 1) {
      V_EXPECT_TRUE(got_load_start_[0]);
      V_EXPECT_FALSE(got_load_start_[2]);
      V_EXPECT_FALSE(got_load_start_[3]);
    } else if (frame_number == 2) {
      V_EXPECT_TRUE(got_load_start_[0]);
      V_EXPECT_TRUE(got_load_start_[1]);
      V_EXPECT_FALSE(got_load_start_[3]);
    } else if (frame_number == 3) {
      V_EXPECT_TRUE(got_load_start_[0]);
      V_EXPECT_TRUE(got_load_start_[1]);
      V_EXPECT_TRUE(got_load_start_[2]);
    }

    got_load_start_[frame_number].yes();

    V_EXPECT_TRUE(parent::OnLoadStart(browser, frame));
    V_RETURN();
  }

  bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
                 CefRefPtr<CefFrame> frame) override {
    const int frame_number = GetNavFromMultiNavURL(frame->GetURL());

    V_DECLARE();
    V_EXPECT_TRUE(got_load_start_[frame_number]);
    V_EXPECT_FALSE(got_load_end_[frame_number]);

    // Notification should be received for child frame before parent frame.
    if (frame_number == 0) {
      V_EXPECT_TRUE(got_load_end_[1]);
      V_EXPECT_TRUE(got_load_end_[2]);
      V_EXPECT_TRUE(got_load_end_[3]);
    } else if (frame_number == 1) {
      V_EXPECT_FALSE(got_load_end_[0]);
      V_EXPECT_TRUE(got_load_end_[2]);
      V_EXPECT_TRUE(got_load_end_[3]);
    } else if (frame_number == 2) {
      V_EXPECT_FALSE(got_load_end_[0]);
      V_EXPECT_FALSE(got_load_end_[1]);
      V_EXPECT_TRUE(got_load_end_[3]);
    } else if (frame_number == 3) {
      V_EXPECT_FALSE(got_load_end_[0]);
      V_EXPECT_FALSE(got_load_end_[1]);
      V_EXPECT_FALSE(got_load_end_[2]);
    }

    V_EXPECT_TRUE(VerifyBrowserIframe(browser, frame, origin_, frame_number))
        << "frame_number = " << frame_number;

    got_load_end_[frame_number].yes();

    V_EXPECT_TRUE(parent::OnLoadEnd(browser, frame));
    V_RETURN();
  }

  bool Finalize() override {
    V_DECLARE();
    V_EXPECT_TRUE(got_load_state_change_done_);
    V_EXPECT_TRUE(got_load_start_[0]);
    V_EXPECT_TRUE(got_load_start_[1]);
    V_EXPECT_TRUE(got_load_start_[2]);
    V_EXPECT_TRUE(got_load_start_[3]);
    V_EXPECT_TRUE(got_load_end_[0]);
    V_EXPECT_TRUE(got_load_end_[1]);
    V_EXPECT_TRUE(got_load_end_[2]);
    V_EXPECT_TRUE(got_load_end_[3]);
    V_EXPECT_TRUE(parent::Finalize());
    V_RETURN();
  }

 private:
  std::string origin_;

  TrackCallback got_load_state_change_done_;
  TrackCallback got_load_start_[4];
  TrackCallback got_load_end_[4];
};

class FrameNavExpectationsFactoryBrowserTestNestedIframesSameOrigin
    : public FrameNavExpectationsFactoryBrowser {
 public:
  FrameNavExpectationsFactoryBrowserTestNestedIframesSameOrigin()
      : create_count_(0) {}

  FrameNavFactoryId GetID() const override {
    return FNF_ID_NESTED_IFRAMES_SAME_ORIGIN;
  }

  bool HasMoreNavigations() const override {
    return (create_count_ < kMaxMultiNavNavigations);
  }

  bool Finalize() override {
    V_DECLARE();
    V_EXPECT_TRUE(create_count_ == kMaxMultiNavNavigations);
    V_RETURN();
  }

 protected:
  scoped_ptr<FrameNavExpectationsBrowser> Create(int nav) override {
    create_count_++;
    return scoped_ptr<FrameNavExpectationsBrowser>(
        new FrameNavExpectationsBrowserTestNestedIframes(nav, true));
  }

 private:
  int create_count_;
};

class FrameNavExpectationsFactoryRendererTestNestedIframesSameOrigin
    : public FrameNavExpectationsFactoryRenderer {
 public:
  FrameNavExpectationsFactoryRendererTestNestedIframesSameOrigin() {}

  FrameNavFactoryId GetID() const override {
    return FNF_ID_NESTED_IFRAMES_SAME_ORIGIN;
  }

 protected:
  scoped_ptr<FrameNavExpectationsRenderer> Create(int nav) override {
    return scoped_ptr<FrameNavExpectationsRenderer>(
        new FrameNavExpectationsRendererTestNestedIframes(nav, true));
  }
};

}  // namespace

// Test that nested iframes work.
FRAME_TEST(NestedIframesSameOrigin, FNF_ID_NESTED_IFRAMES_SAME_ORIGIN)

namespace {

class FrameNavExpectationsFactoryBrowserTestNestedIframesDiffOrigin
    : public FrameNavExpectationsFactoryBrowser {
 public:
  FrameNavExpectationsFactoryBrowserTestNestedIframesDiffOrigin()
      : create_count_(0) {}

  FrameNavFactoryId GetID() const override {
    return FNF_ID_NESTED_IFRAMES_DIFF_ORIGIN;
  }

  bool HasMoreNavigations() const override {
    return (create_count_ < kMaxMultiNavNavigations);
  }

  bool Finalize() override {
    V_DECLARE();
    V_EXPECT_TRUE(create_count_ == kMaxMultiNavNavigations);
    V_RETURN();
  }

 protected:
  scoped_ptr<FrameNavExpectationsBrowser> Create(int nav) override {
    create_count_++;
    return scoped_ptr<FrameNavExpectationsBrowser>(
        new FrameNavExpectationsBrowserTestNestedIframes(nav, false));
  }

 private:
  int create_count_;
};

class FrameNavExpectationsFactoryRendererTestNestedIframesDiffOrigin
    : public FrameNavExpectationsFactoryRenderer {
 public:
  FrameNavExpectationsFactoryRendererTestNestedIframesDiffOrigin() {}

  FrameNavFactoryId GetID() const override {
    return FNF_ID_NESTED_IFRAMES_DIFF_ORIGIN;
  }

 protected:
  scoped_ptr<FrameNavExpectationsRenderer> Create(int nav) override {
    return scoped_ptr<FrameNavExpectationsRenderer>(
        new FrameNavExpectationsRendererTestNestedIframes(nav, false));
  }
};

}  // namespace

// Test that nested iframes work.
FRAME_TEST(NestedIframesDiffOrigin, FNF_ID_NESTED_IFRAMES_DIFF_ORIGIN)

namespace {

// Returns a new factory in the browser or renderer process. All factory types
// must be listed here.

// static
scoped_ptr<FrameNavExpectationsFactoryBrowser>
FrameNavExpectationsFactoryBrowser::FromID(FrameNavFactoryId id) {
  scoped_ptr<FrameNavExpectationsFactoryBrowser> factory;
  switch (id) {
    case FNF_ID_SINGLE_NAV_HARNESS:
      factory.reset(new FrameNavExpectationsFactoryBrowserTestSingleNavHarness);
      break;
    case FNF_ID_SINGLE_NAV:
      factory.reset(new FrameNavExpectationsFactoryBrowserTestSingleNav);
      break;
    case FNF_ID_MULTI_NAV_HARNESS:
      factory.reset(new FrameNavExpectationsFactoryBrowserTestMultiNavHarness);
      break;
    case FNF_ID_MULTI_NAV:
      factory.reset(new FrameNavExpectationsFactoryBrowserTestMultiNav);
      break;
    case FNF_ID_NESTED_IFRAMES_SAME_ORIGIN:
      factory.reset(
          new FrameNavExpectationsFactoryBrowserTestNestedIframesSameOrigin);
      break;
    case FNF_ID_NESTED_IFRAMES_DIFF_ORIGIN:
      factory.reset(
          new FrameNavExpectationsFactoryBrowserTestNestedIframesDiffOrigin);
      break;
    default:
      break;
  }
  EXPECT_TRUE(factory);
  EXPECT_EQ(id, factory->GetID());
  return factory.Pass();
}

// static
scoped_ptr<FrameNavExpectationsFactoryRenderer>
FrameNavExpectationsFactoryRenderer::FromID(FrameNavFactoryId id) {
  scoped_ptr<FrameNavExpectationsFactoryRenderer> factory;
  switch (id) {
    case FNF_ID_SINGLE_NAV_HARNESS:
      factory.reset(
          new FrameNavExpectationsFactoryRendererTestSingleNavHarness);
      break;
    case FNF_ID_SINGLE_NAV:
      factory.reset(new FrameNavExpectationsFactoryRendererTestSingleNav);
      break;
    case FNF_ID_MULTI_NAV_HARNESS:
      factory.reset(new FrameNavExpectationsFactoryRendererTestMultiNavHarness);
      break;
    case FNF_ID_MULTI_NAV:
      factory.reset(new FrameNavExpectationsFactoryRendererTestMultiNav);
      break;
    case FNF_ID_NESTED_IFRAMES_SAME_ORIGIN:
      factory.reset(
          new FrameNavExpectationsFactoryRendererTestNestedIframesSameOrigin);
      break;
    case FNF_ID_NESTED_IFRAMES_DIFF_ORIGIN:
      factory.reset(
          new FrameNavExpectationsFactoryRendererTestNestedIframesDiffOrigin);
      break;
    default:
      break;
  }
  EXPECT_TRUE(factory);
  EXPECT_EQ(id, factory->GetID());
  return factory.Pass();
}

}  // namespace

// Entry point for creating frame renderer test objects.
// Called from client_app_delegates.cc.
void CreateFrameRendererTests(ClientAppRenderer::DelegateSet& delegates) {
  delegates.insert(new FrameNavRendererTest);
}
