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

#include <stddef.h>
#include <utility>

#include "base/base64.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/sys_info.h"
#include "base/values.h"
#include "build/build_config.h"
#include "content/browser/frame_host/interstitial_page_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/interstitial_page_delegate.h"
#include "content/public/browser/javascript_dialog_manager.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/ssl_status.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/shell/browser/shell.h"
#include "content/test/content_browser_test_utils_internal.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/cert_test_util.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/test_data_directory.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/base/layout.h"
#include "ui/compositor/compositor_switches.h"
#include "ui/gfx/codec/jpeg_codec.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/skia_util.h"
#include "ui/snapshot/snapshot.h"

#define EXPECT_SIZE_EQ(expected, actual)               \
  do {                                                 \
    EXPECT_EQ((expected).width(), (actual).width());   \
    EXPECT_EQ((expected).height(), (actual).height()); \
  } while (false)

using testing::ElementsAre;

namespace content {

namespace {

const char kIdParam[] = "id";
const char kMethodParam[] = "method";
const char kParamsParam[] = "params";

class TestJavaScriptDialogManager : public JavaScriptDialogManager,
                                    public WebContentsDelegate {
 public:
  TestJavaScriptDialogManager() : handle_(false) {}
  ~TestJavaScriptDialogManager() override {}

  void Handle()
  {
    if (!callback_.is_null()) {
      callback_.Run(true, base::string16());
      callback_.Reset();
    } else {
      handle_ = true;
    }
  }

  // WebContentsDelegate
  JavaScriptDialogManager* GetJavaScriptDialogManager(
      WebContents* source) override {
    return this;
  }

  // JavaScriptDialogManager
  void RunJavaScriptDialog(WebContents* web_contents,
                           const GURL& origin_url,
                           JavaScriptDialogType dialog_type,
                           const base::string16& message_text,
                           const base::string16& default_prompt_text,
                           const DialogClosedCallback& callback,
                           bool* did_suppress_message) override {
    if (handle_) {
      handle_ = false;
      callback.Run(true, base::string16());
    } else {
      callback_ = callback;
    }
  };

  void RunBeforeUnloadDialog(WebContents* web_contents,
                             bool is_reload,
                             const DialogClosedCallback& callback) override {}

  bool HandleJavaScriptDialog(WebContents* web_contents,
                              bool accept,
                              const base::string16* prompt_override) override {
    return true;
  }

  void CancelDialogs(WebContents* web_contents,
                     bool reset_state) override {}

 private:
  DialogClosedCallback callback_;
  bool handle_;
  DISALLOW_COPY_AND_ASSIGN(TestJavaScriptDialogManager);
};

}

class DevToolsProtocolTest : public ContentBrowserTest,
                             public DevToolsAgentHostClient,
                             public WebContentsDelegate {
 public:
  DevToolsProtocolTest()
      : last_sent_id_(0),
        waiting_for_command_result_id_(0),
        in_dispatch_(false),
        agent_host_can_close_(false) {}

  void SetUpOnMainThread() override {
    ok_cert_ =
        net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem");
    expired_cert_ = net::ImportCertFromFile(net::GetTestCertsDirectory(),
                                            "expired_cert.pem");
  }

 protected:
  // WebContentsDelegate method:
  bool DidAddMessageToConsole(WebContents* source,
                              int32_t level,
                              const base::string16& message,
                              int32_t line_no,
                              const base::string16& source_id) override {
    console_messages_.push_back(base::UTF16ToUTF8(message));
    return true;
  }

  void ShowCertificateViewerInDevTools(
      WebContents* web_contents,
      scoped_refptr<net::X509Certificate> certificate) override {
    last_shown_certificate_ = certificate;
  }

  void SendCommand(const std::string& method,
                   std::unique_ptr<base::DictionaryValue> params) {
    SendCommand(method, std::move(params), true);
  }

  void SendCommand(const std::string& method,
                   std::unique_ptr<base::DictionaryValue> params,
                   bool wait) {
    in_dispatch_ = true;
    base::DictionaryValue command;
    command.SetInteger(kIdParam, ++last_sent_id_);
    command.SetString(kMethodParam, method);
    if (params)
      command.Set(kParamsParam, params.release());

    std::string json_command;
    base::JSONWriter::Write(command, &json_command);
    agent_host_->DispatchProtocolMessage(this, json_command);
    // Some messages are dispatched synchronously.
    // Only run loop if we are not finished yet.
    if (in_dispatch_ && wait)
      WaitForResponse();
    in_dispatch_ = false;
  }

  void WaitForResponse() {
    waiting_for_command_result_id_ = last_sent_id_;
    base::RunLoop().Run();
  }

  bool HasValue(const std::string& path) {
    base::Value* value = 0;
    return result_->Get(path, &value);
  }

  bool HasListItem(const std::string& path_to_list,
                   const std::string& name,
                   const std::string& value) {
    base::ListValue* list;
    if (!result_->GetList(path_to_list, &list))
      return false;

    for (size_t i = 0; i != list->GetSize(); i++) {
      base::DictionaryValue* item;
      if (!list->GetDictionary(i, &item))
        return false;
      std::string id;
      if (!item->GetString(name, &id))
        return false;
      if (id == value)
        return true;
    }
    return false;
  }

  void Attach() {
    agent_host_ = DevToolsAgentHost::GetOrCreateFor(shell()->web_contents());
    agent_host_->AttachClient(this);
    shell()->web_contents()->SetDelegate(this);
  }

  void TearDownOnMainThread() override {
    if (agent_host_) {
      agent_host_->DetachClient(this);
      agent_host_ = nullptr;
    }
  }

  std::unique_ptr<base::DictionaryValue> WaitForNotification(
      const std::string& notification) {
    return WaitForNotification(notification, false);
  }

  std::unique_ptr<base::DictionaryValue> WaitForNotification(
      const std::string& notification,
      bool allow_existing) {
    if (allow_existing) {
      for (size_t i = 0; i < notifications_.size(); i++) {
        if (notifications_[i] == notification) {
          std::unique_ptr<base::DictionaryValue> result =
              std::move(notification_params_[i]);
          notifications_.erase(notifications_.begin() + i);
          notification_params_.erase(notification_params_.begin() + i);
          return result;
        }
      }
    }

    waiting_for_notification_ = notification;
    RunMessageLoop();
    return std::move(waiting_for_notification_params_);
  }

  void ClearNotifications() {
    notifications_.clear();
    notification_params_.clear();
  }

  struct ExpectedNavigation {
    std::string url;
    bool is_in_main_frame;
    bool is_redirect;
    std::string navigation_response;
  };

  std::string RemovePort(const GURL& url) {
    GURL::Replacements remove_port;
    remove_port.ClearPort();
    return url.ReplaceComponents(remove_port).spec();
  }

  // Waits for the expected navigations to occur in any order. If an expected
  // navigation occurs, Page.processNavigation is called with the specified
  // navigation_response to either allow it to proceed or to cancel it.
  void ProcessNavigationsAnyOrder(
      std::vector<ExpectedNavigation> expected_navigations) {
    while (!expected_navigations.empty()) {
      std::unique_ptr<base::DictionaryValue> params =
          WaitForNotification("Page.navigationRequested");

      std::string url;
      ASSERT_TRUE(params->GetString("url", &url));

      // The url will typically have a random port which we want to remove.
      url = RemovePort(GURL(url));

      int navigation_id;
      ASSERT_TRUE(params->GetInteger("navigationId", &navigation_id));
      bool is_in_main_frame;
      ASSERT_TRUE(params->GetBoolean( "isInMainFrame", &is_in_main_frame));
      bool is_redirect;
      ASSERT_TRUE(params->GetBoolean("isRedirect", &is_redirect));

      bool navigation_was_expected;
      for (auto it = expected_navigations.begin();
           it != expected_navigations.end(); it++) {
        if (url != it->url || is_in_main_frame != it->is_in_main_frame ||
            is_redirect != it->is_redirect) {
          continue;
        }

        std::unique_ptr<base::DictionaryValue> process_params(
            new base::DictionaryValue());
        process_params->SetString("response", it->navigation_response);
        process_params->SetInteger("navigationId", navigation_id);
        SendCommand("Page.processNavigation", std::move(process_params), false);

        navigation_was_expected = true;
        expected_navigations.erase(it);
        break;
      }
      EXPECT_TRUE(navigation_was_expected)
          << "url = " << url << "is_in_main_frame = " << is_in_main_frame
          << "is_redirect = " << is_redirect;
    }
  }

  std::vector<std::string> GetAllFrameUrls() {
    std::vector<std::string> urls;
    for (RenderFrameHost* render_frame_host :
         shell()->web_contents()->GetAllFrames()) {
      urls.push_back(RemovePort(render_frame_host->GetLastCommittedURL()));
    }
    return urls;
  }

  const scoped_refptr<net::X509Certificate>& last_shown_certificate() {
    return last_shown_certificate_;
  }

  const scoped_refptr<net::X509Certificate>& ok_cert() { return ok_cert_; }

  const scoped_refptr<net::X509Certificate>& expired_cert() {
    return expired_cert_;
  }

  void set_agent_host_can_close() { agent_host_can_close_ = true; }

  std::unique_ptr<base::DictionaryValue> result_;
  scoped_refptr<DevToolsAgentHost> agent_host_;
  int last_sent_id_;
  std::vector<int> result_ids_;
  std::vector<std::string> notifications_;
  std::vector<std::string> console_messages_;
  std::vector<std::unique_ptr<base::DictionaryValue>> notification_params_;

 private:
  void DispatchProtocolMessage(DevToolsAgentHost* agent_host,
                               const std::string& message) override {
    std::unique_ptr<base::DictionaryValue> root(
        static_cast<base::DictionaryValue*>(
            base::JSONReader::Read(message).release()));
    int id;
    if (root->GetInteger("id", &id)) {
      result_ids_.push_back(id);
      base::DictionaryValue* result;
      ASSERT_TRUE(root->GetDictionary("result", &result));
      result_.reset(result->DeepCopy());
      in_dispatch_ = false;
      if (id && id == waiting_for_command_result_id_) {
        waiting_for_command_result_id_ = 0;
        base::MessageLoop::current()->QuitNow();
      }
    } else {
      std::string notification;
      EXPECT_TRUE(root->GetString("method", &notification));
      notifications_.push_back(notification);
      base::DictionaryValue* params;
      if (root->GetDictionary("params", &params)) {
        notification_params_.push_back(params->CreateDeepCopy());
      } else {
        notification_params_.push_back(
            base::WrapUnique(new base::DictionaryValue()));
      }
      if (waiting_for_notification_ == notification) {
        waiting_for_notification_ = std::string();
        waiting_for_notification_params_ = base::WrapUnique(
            notification_params_[notification_params_.size() - 1]->DeepCopy());
        base::MessageLoop::current()->QuitNow();
      }
    }
  }

  void AgentHostClosed(DevToolsAgentHost* agent_host, bool replaced) override {
    if (!agent_host_can_close_)
      NOTREACHED();
  }

  std::string waiting_for_notification_;
  std::unique_ptr<base::DictionaryValue> waiting_for_notification_params_;
  int waiting_for_command_result_id_;
  bool in_dispatch_;
  scoped_refptr<net::X509Certificate> last_shown_certificate_;
  scoped_refptr<net::X509Certificate> ok_cert_;
  scoped_refptr<net::X509Certificate> expired_cert_;
  bool agent_host_can_close_;
};

class TestInterstitialDelegate : public InterstitialPageDelegate {
 private:
  // InterstitialPageDelegate:
  std::string GetHTMLContents() override { return "<p>Interstitial</p>"; }
};

class SyntheticKeyEventTest : public DevToolsProtocolTest {
 protected:
  void SendKeyEvent(const std::string& type,
                    int modifier,
                    int windowsKeyCode,
                    int nativeKeyCode,
                    const std::string& key,
                    bool wait) {
    std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
    params->SetString("type", type);
    params->SetInteger("modifiers", modifier);
    params->SetInteger("windowsVirtualKeyCode", windowsKeyCode);
    params->SetInteger("nativeVirtualKeyCode", nativeKeyCode);
    params->SetString("key", key);
    SendCommand("Input.dispatchKeyEvent", std::move(params), wait);
  }
};

class SyntheticMouseEventTest : public DevToolsProtocolTest {
 protected:
  void SendMouseEvent(const std::string& type, int x, int y, bool wait) {
    std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
    params->SetString("type", type);
    params->SetInteger("x", x);
    params->SetInteger("y", y);
    SendCommand("Input.dispatchMouseEvent", std::move(params), wait);
  }
};

IN_PROC_BROWSER_TEST_F(SyntheticKeyEventTest, KeyEventSynthesizeKey) {
  NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
  Attach();
  ASSERT_TRUE(content::ExecuteScript(
      shell()->web_contents()->GetRenderViewHost(),
      "function handleKeyEvent(event) {"
        "domAutomationController.setAutomationId(0);"
        "domAutomationController.send(event.key);"
      "}"
      "document.body.addEventListener('keydown', handleKeyEvent);"
      "document.body.addEventListener('keyup', handleKeyEvent);"));

  DOMMessageQueue dom_message_queue;

  // Send enter (keycode 13).
  SendKeyEvent("rawKeyDown", 0, 13, 13, "Enter", true);
  SendKeyEvent("keyUp", 0, 13, 13, "Enter", true);

  std::string key;
  ASSERT_TRUE(dom_message_queue.WaitForMessage(&key));
  EXPECT_EQ("\"Enter\"", key);
  ASSERT_TRUE(dom_message_queue.WaitForMessage(&key));
  EXPECT_EQ("\"Enter\"", key);

  // Send escape (keycode 27).
  SendKeyEvent("rawKeyDown", 0, 27, 27, "Escape", true);
  SendKeyEvent("keyUp", 0, 27, 27, "Escape", true);

  ASSERT_TRUE(dom_message_queue.WaitForMessage(&key));
  EXPECT_EQ("\"Escape\"", key);
  ASSERT_TRUE(dom_message_queue.WaitForMessage(&key));
  EXPECT_EQ("\"Escape\"", key);
}

IN_PROC_BROWSER_TEST_F(SyntheticKeyEventTest, KeyboardEventAck) {
  NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
  Attach();
  ASSERT_TRUE(content::ExecuteScript(
      shell()->web_contents()->GetRenderViewHost(),
      "document.body.addEventListener('keydown', () => console.log('x'));"));

  scoped_refptr<InputMsgWatcher> filter = new InputMsgWatcher(
      RenderWidgetHostImpl::From(
          shell()->web_contents()->GetRenderViewHost()->GetWidget()),
      blink::WebInputEvent::MouseMove);

  SendCommand("Runtime.enable", nullptr);
  SendKeyEvent("rawKeyDown", 0, 13, 13, "Enter", false);

  // We expect that the console log message event arrives *before* the input
  // event ack, and the subsequent command response for Input.dispatchKeyEvent.
  WaitForNotification("Runtime.consoleAPICalled");
  EXPECT_THAT(console_messages_, ElementsAre("x"));
  EXPECT_FALSE(filter->HasReceivedAck());
  EXPECT_EQ(1u, result_ids_.size());

  WaitForResponse();
  EXPECT_EQ(2u, result_ids_.size());
}

IN_PROC_BROWSER_TEST_F(SyntheticMouseEventTest, MouseEventAck) {
  NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
  Attach();
  ASSERT_TRUE(content::ExecuteScript(
      shell()->web_contents()->GetRenderViewHost(),
      "document.body.addEventListener('mousemove', () => console.log('x'));"));

  scoped_refptr<InputMsgWatcher> filter = new InputMsgWatcher(
      RenderWidgetHostImpl::From(
          shell()->web_contents()->GetRenderViewHost()->GetWidget()),
      blink::WebInputEvent::MouseMove);

  SendCommand("Runtime.enable", nullptr);
  SendMouseEvent("mouseMoved", 15, 15, false);

  // We expect that the console log message event arrives *before* the input
  // event ack, and the subsequent command response for
  // Input.dispatchMouseEvent.
  WaitForNotification("Runtime.consoleAPICalled");
  EXPECT_THAT(console_messages_, ElementsAre("x"));
  EXPECT_FALSE(filter->HasReceivedAck());
  EXPECT_EQ(1u, result_ids_.size());

  WaitForResponse();
  EXPECT_EQ(2u, result_ids_.size());
}

namespace {
bool DecodePNG(std::string base64_data, SkBitmap* bitmap) {
  std::string png_data;
  if (!base::Base64Decode(base64_data, &png_data))
    return false;
  return gfx::PNGCodec::Decode(
      reinterpret_cast<unsigned const char*>(png_data.data()), png_data.size(),
      bitmap);
}

std::unique_ptr<SkBitmap> DecodeJPEG(std::string base64_data) {
  std::string jpeg_data;
  if (!base::Base64Decode(base64_data, &jpeg_data))
    return nullptr;
  return gfx::JPEGCodec::Decode(
      reinterpret_cast<unsigned const char*>(jpeg_data.data()),
      jpeg_data.size());
}

bool ColorsMatchWithinLimit(SkColor color1,
                            SkColor color2,
                            int32_t error_limit) {
  auto a_distance = std::abs(static_cast<int32_t>(SkColorGetA(color1)) -
                             static_cast<int32_t>(SkColorGetA(color2)));
  auto r_distance = std::abs(static_cast<int32_t>(SkColorGetR(color1)) -
                             static_cast<int32_t>(SkColorGetR(color2)));
  auto g_distance = std::abs(static_cast<int32_t>(SkColorGetG(color1)) -
                             static_cast<int32_t>(SkColorGetG(color2)));
  auto b_distance = std::abs(static_cast<int32_t>(SkColorGetB(color1)) -
                             static_cast<int32_t>(SkColorGetB(color2)));

  return a_distance * a_distance + r_distance * r_distance +
             g_distance * g_distance + b_distance * b_distance <=
         error_limit * error_limit;
}

// Adapted from cc::ExactPixelComparator.
bool MatchesBitmap(const SkBitmap& expected_bmp,
                   const SkBitmap& actual_bmp,
                   const gfx::Rect& matching_mask,
                   int error_limit) {
  // Number of pixels with an error
  int error_pixels_count = 0;

  gfx::Rect error_bounding_rect = gfx::Rect();

  // Check that bitmaps have identical dimensions.
  EXPECT_EQ(expected_bmp.width(), actual_bmp.width());
  EXPECT_EQ(expected_bmp.height(), actual_bmp.height());
  if (expected_bmp.width() != actual_bmp.width() ||
      expected_bmp.height() != actual_bmp.height()) {
    return false;
  }

  SkAutoLockPixels lock_actual_bmp(actual_bmp);
  SkAutoLockPixels lock_expected_bmp(expected_bmp);

  DCHECK(gfx::SkIRectToRect(actual_bmp.bounds()).Contains(matching_mask));

  for (int x = matching_mask.x(); x < matching_mask.width(); ++x) {
    for (int y = matching_mask.y(); y < matching_mask.height(); ++y) {
      SkColor actual_color = actual_bmp.getColor(x, y);
      SkColor expected_color = expected_bmp.getColor(x, y);
      if (!ColorsMatchWithinLimit(actual_color, expected_color, error_limit)) {
        if (error_pixels_count < 10) {
          LOG(ERROR) << "Pixel (" << x << "," << y << "): expected "
                     << expected_color << " actual " << actual_color;
        }
        error_pixels_count++;
        error_bounding_rect.Union(gfx::Rect(x, y, 1, 1));
      }
    }
  }

  if (error_pixels_count != 0) {
    LOG(ERROR) << "Number of pixel with an error: " << error_pixels_count;
    LOG(ERROR) << "Error Bounding Box : " << error_bounding_rect.ToString();
    return false;
  }

  return true;
}
}  // namespace

class CaptureScreenshotTest : public DevToolsProtocolTest {
 protected:
  enum ScreenshotEncoding { ENCODING_PNG, ENCODING_JPEG };
  void CaptureScreenshotAndCompareTo(const SkBitmap& expected_bitmap,
                                     ScreenshotEncoding encoding) {
    std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
    params->SetString("format", encoding == ENCODING_PNG ? "png" : "jpeg");
    params->SetInteger("quality", 100);
    SendCommand("Page.captureScreenshot", std::move(params));

    std::string base64;
    EXPECT_TRUE(result_->GetString("data", &base64));
    std::unique_ptr<SkBitmap> result_bitmap;
    int error_limit = 0;
    if (encoding == ENCODING_PNG) {
      result_bitmap.reset(new SkBitmap());
      EXPECT_TRUE(DecodePNG(base64, result_bitmap.get()));
    } else {
      result_bitmap = DecodeJPEG(base64);
      // Even with quality 100, jpeg isn't lossless. So, we allow some skew in
      // pixel values. Not that this assumes that there is no skew in pixel
      // positions, so will only work reliably if all pixels have equal values.
      error_limit = 3;
    }
    EXPECT_TRUE(result_bitmap);

    gfx::Rect matching_mask(gfx::SkIRectToRect(expected_bitmap.bounds()));
#if defined(OS_MACOSX)
    // Mask out the corners, which may be drawn differently on Mac because of
    // rounded corners.
    matching_mask.Inset(4, 4, 4, 4);
#endif
    EXPECT_TRUE(MatchesBitmap(expected_bitmap, *result_bitmap, matching_mask,
                              error_limit));
  }

  // Takes a screenshot of a colored box that is positioned inside the frame.
  void PlaceAndCaptureBox(const gfx::Size& frame_size,
                          const gfx::Size& box_size,
                          float screenshot_scale) {
    static const int kBoxOffsetHeight = 100;
    const gfx::Size scaled_box_size =
        ScaleToFlooredSize(box_size, screenshot_scale);
    std::unique_ptr<base::DictionaryValue> params;

    VLOG(1) << "Testing screenshot of box with size " << box_size.width() << "x"
            << box_size.height() << "px at scale " << screenshot_scale
            << " ...";

    // Draw a blue box of provided size in the horizontal center of the page.
    EXPECT_TRUE(content::ExecuteScript(
        shell()->web_contents()->GetRenderViewHost(),
        base::StringPrintf(
            "var style = document.body.style;                             "
            "style.overflow = 'hidden';                                   "
            "style.minHeight = '%dpx';                                    "
            "style.backgroundImage = 'linear-gradient(#0000ff, #0000ff)'; "
            "style.backgroundSize = '%dpx %dpx';                          "
            "style.backgroundPosition = '50%% %dpx';                      "
            "style.backgroundRepeat = 'no-repeat';                        ",
            box_size.height() + kBoxOffsetHeight, box_size.width(),
            box_size.height(), kBoxOffsetHeight)));

    // Force frame size: The offset of the blue box within the frame shouldn't
    // change during screenshotting. This verifies that the page doesn't observe
    // a change in frame size as a side effect of screenshotting.
    params.reset(new base::DictionaryValue());
    params->SetInteger("width", frame_size.width());
    params->SetInteger("height", frame_size.height());
    params->SetDouble("deviceScaleFactor", 0);
    params->SetBoolean("mobile", false);
    params->SetBoolean("fitWindow", false);
    SendCommand("Emulation.setDeviceMetricsOverride", std::move(params));

    // Resize frame to scaled blue box size.
    params.reset(new base::DictionaryValue());
    params->SetInteger("width", scaled_box_size.width());
    params->SetInteger("height", scaled_box_size.height());
    SendCommand("Emulation.setVisibleSize", std::move(params));

    // Force viewport to match scaled blue box.
    params.reset(new base::DictionaryValue());
    params->SetDouble("x", (frame_size.width() - box_size.width()) / 2.);
    params->SetDouble("y", kBoxOffsetHeight);
    params->SetDouble("scale", screenshot_scale);
    SendCommand("Emulation.forceViewport", std::move(params));

    // Capture screenshot and verify that it is indeed blue.
    SkBitmap expected_bitmap;
    expected_bitmap.allocN32Pixels(scaled_box_size.width(),
                                   scaled_box_size.height());
    expected_bitmap.eraseColor(SkColorSetRGB(0x00, 0x00, 0xff));
    CaptureScreenshotAndCompareTo(expected_bitmap, ENCODING_PNG);

    // Reset for next screenshot.
    SendCommand("Emulation.resetViewport", nullptr);
    SendCommand("Emulation.clearDeviceMetricsOverride", nullptr);
  }

 private:
#if !defined(OS_ANDROID)
  void SetUpCommandLine(base::CommandLine* command_line) override {
    command_line->AppendSwitch(switches::kEnablePixelOutputInTests);
  }
#endif
};

IN_PROC_BROWSER_TEST_F(CaptureScreenshotTest, CaptureScreenshot) {
  // This test fails consistently on low-end Android devices.
  // See crbug.com/653637.
  // TODO(eseckler): Reenable with error limit if necessary.
  if (base::SysInfo::IsLowEndDevice()) return;

  shell()->LoadURL(
      GURL("data:text/html,<body style='background:#123456'></body>"));
  WaitForLoadStop(shell()->web_contents());
  Attach();
  SkBitmap expected_bitmap;
  // We compare against the actual physical backing size rather than the
  // view size, because the view size is stored adjusted for DPI and only in
  // integer precision.
  gfx::Size view_size = static_cast<RenderWidgetHostViewBase*>(
                            shell()->web_contents()->GetRenderWidgetHostView())
                            ->GetPhysicalBackingSize();
  expected_bitmap.allocN32Pixels(view_size.width(), view_size.height());
  expected_bitmap.eraseColor(SkColorSetRGB(0x12, 0x34, 0x56));
  CaptureScreenshotAndCompareTo(expected_bitmap, ENCODING_PNG);
}

IN_PROC_BROWSER_TEST_F(CaptureScreenshotTest, CaptureScreenshotJpeg) {
  // This test fails consistently on low-end Android devices.
  // See crbug.com/653637.
  // TODO(eseckler): Reenable with error limit if necessary.
  if (base::SysInfo::IsLowEndDevice())
    return;

  shell()->LoadURL(
      GURL("data:text/html,<body style='background:#123456'></body>"));
  WaitForLoadStop(shell()->web_contents());
  Attach();
  SkBitmap expected_bitmap;
  // We compare against the actual physical backing size rather than the
  // view size, because the view size is stored adjusted for DPI and only in
  // integer precision.
  gfx::Size view_size = static_cast<RenderWidgetHostViewBase*>(
                            shell()->web_contents()->GetRenderWidgetHostView())
                            ->GetPhysicalBackingSize();
  expected_bitmap.allocN32Pixels(view_size.width(), view_size.height());
  expected_bitmap.eraseColor(SkColorSetRGB(0x12, 0x34, 0x56));
  CaptureScreenshotAndCompareTo(expected_bitmap, ENCODING_JPEG);
}

// Setting frame size (through RWHV) is not supported on Android.
#if defined(OS_ANDROID)
#define MAYBE_CaptureScreenshotArea DISABLED_CaptureScreenshotArea
#else
#define MAYBE_CaptureScreenshotArea CaptureScreenshotArea
#endif
IN_PROC_BROWSER_TEST_F(CaptureScreenshotTest,
                       MAYBE_CaptureScreenshotArea) {
  static const gfx::Size kFrameSize(800, 600);

  shell()->LoadURL(GURL("about:blank"));
  Attach();

  // Test capturing a subarea inside the emulated frame at different scales.
  PlaceAndCaptureBox(kFrameSize, gfx::Size(100, 200), 1.0);
  PlaceAndCaptureBox(kFrameSize, gfx::Size(100, 200), 2.0);
  PlaceAndCaptureBox(kFrameSize, gfx::Size(100, 200), 0.5);

  // Ensure that content outside the emulated frame is painted, too.
  PlaceAndCaptureBox(kFrameSize, gfx::Size(10, 10000), 1.0);
}

#if defined(OS_ANDROID)
// Disabled, see http://crbug.com/469947.
IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, DISABLED_SynthesizePinchGesture) {
  GURL test_url = GetTestUrl("devtools", "synthetic_gesture_tests.html");
  NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1);
  Attach();

  int old_width;
  ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
      shell(), "domAutomationController.send(window.innerWidth)", &old_width));

  int old_height;
  ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
      shell(), "domAutomationController.send(window.innerHeight)",
      &old_height));

  std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
  params->SetInteger("x", old_width / 2);
  params->SetInteger("y", old_height / 2);
  params->SetDouble("scaleFactor", 2.0);
  SendCommand("Input.synthesizePinchGesture", std::move(params));

  int new_width;
  ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
      shell(), "domAutomationController.send(window.innerWidth)", &new_width));
  ASSERT_DOUBLE_EQ(2.0, static_cast<double>(old_width) / new_width);

  int new_height;
  ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
      shell(), "domAutomationController.send(window.innerHeight)",
      &new_height));
  ASSERT_DOUBLE_EQ(2.0, static_cast<double>(old_height) / new_height);
}

IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, DISABLED_SynthesizeScrollGesture) {
  GURL test_url = GetTestUrl("devtools", "synthetic_gesture_tests.html");
  NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1);
  Attach();

  int scroll_top;
  ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
      shell(), "domAutomationController.send(document.body.scrollTop)",
      &scroll_top));
  ASSERT_EQ(0, scroll_top);

  std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
  params->SetInteger("x", 0);
  params->SetInteger("y", 0);
  params->SetInteger("xDistance", 0);
  params->SetInteger("yDistance", -100);
  SendCommand("Input.synthesizeScrollGesture", std::move(params));

  ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
      shell(), "domAutomationController.send(document.body.scrollTop)",
      &scroll_top));
  ASSERT_EQ(100, scroll_top);
}

IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, DISABLED_SynthesizeTapGesture) {
  GURL test_url = GetTestUrl("devtools", "synthetic_gesture_tests.html");
  NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1);
  Attach();

  int scroll_top;
  ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
      shell(), "domAutomationController.send(document.body.scrollTop)",
      &scroll_top));
  ASSERT_EQ(0, scroll_top);

  std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
  params->SetInteger("x", 16);
  params->SetInteger("y", 16);
  params->SetString("gestureSourceType", "touch");
  SendCommand("Input.synthesizeTapGesture", std::move(params));

  // The link that we just tapped should take us to the bottom of the page. The
  // new value of |document.body.scrollTop| will depend on the screen dimensions
  // of the device that we're testing on, but in any case it should be greater
  // than 0.
  ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
      shell(), "domAutomationController.send(document.body.scrollTop)",
      &scroll_top));
  ASSERT_GT(scroll_top, 0);
}
#endif  // defined(OS_ANDROID)

IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, NavigationPreservesMessages) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL test_url = embedded_test_server()->GetURL("/devtools/navigation.html");
  NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1);
  Attach();
  SendCommand("Page.enable", nullptr, false);

  std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
  test_url = GetTestUrl("devtools", "navigation.html");
  params->SetString("url", test_url.spec());
  TestNavigationObserver navigation_observer(shell()->web_contents());
  SendCommand("Page.navigate", std::move(params), true);
  navigation_observer.Wait();

  bool enough_results = result_ids_.size() >= 2u;
  EXPECT_TRUE(enough_results);
  if (enough_results) {
    EXPECT_EQ(1, result_ids_[0]);  // Page.enable
    EXPECT_EQ(2, result_ids_[1]);  // Page.navigate
  }

  enough_results = notifications_.size() >= 1u;
  EXPECT_TRUE(enough_results);
  bool found_frame_notification = false;
  for (const std::string& notification : notifications_) {
    if (notification == "Page.frameStartedLoading")
      found_frame_notification = true;
  }
  EXPECT_TRUE(found_frame_notification);
}

IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, CrossSiteNoDetach) {
  host_resolver()->AddRule("*", "127.0.0.1");
  content::SetupCrossSiteRedirector(embedded_test_server());
  ASSERT_TRUE(embedded_test_server()->Start());

  GURL test_url1 = embedded_test_server()->GetURL(
      "A.com", "/devtools/navigation.html");
  NavigateToURLBlockUntilNavigationsComplete(shell(), test_url1, 1);
  Attach();

  GURL test_url2 = embedded_test_server()->GetURL(
      "B.com", "/devtools/navigation.html");
  NavigateToURLBlockUntilNavigationsComplete(shell(), test_url2, 1);

  EXPECT_EQ(0u, notifications_.size());
}

IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, ReconnectPreservesState) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL test_url = embedded_test_server()->GetURL("/devtools/navigation.html");
  NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1);

  Shell* second = CreateBrowser();
  NavigateToURLBlockUntilNavigationsComplete(second, test_url, 1);

  Attach();
  SendCommand("Runtime.enable", nullptr);

  agent_host_->DisconnectWebContents();
  agent_host_->ConnectWebContents(second->web_contents());
  WaitForNotification("Runtime.executionContextsCleared");
}

IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, CrossSitePauseInBeforeUnload) {
  host_resolver()->AddRule("*", "127.0.0.1");
  content::SetupCrossSiteRedirector(embedded_test_server());
  ASSERT_TRUE(embedded_test_server()->Start());

  NavigateToURLBlockUntilNavigationsComplete(shell(),
      embedded_test_server()->GetURL("A.com", "/devtools/navigation.html"), 1);
  Attach();
  SendCommand("Debugger.enable", nullptr);

  ASSERT_TRUE(content::ExecuteScript(
      shell(),
      "window.onbeforeunload = function() { debugger; return null; }"));

  shell()->LoadURL(
      embedded_test_server()->GetURL("B.com", "/devtools/navigation.html"));
  WaitForNotification("Debugger.paused");
  TestNavigationObserver observer(shell()->web_contents(), 1);
  SendCommand("Debugger.resume", nullptr);
  observer.Wait();
}

IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, InspectDuringFrameSwap) {
  host_resolver()->AddRule("*", "127.0.0.1");
  content::SetupCrossSiteRedirector(embedded_test_server());
  ASSERT_TRUE(embedded_test_server()->Start());

  GURL test_url1 =
      embedded_test_server()->GetURL("A.com", "/devtools/navigation.html");
  NavigateToURLBlockUntilNavigationsComplete(shell(), test_url1, 1);

  ShellAddedObserver new_shell_observer;
  EXPECT_TRUE(ExecuteScript(shell(), "window.open('about:blank','foo');"));
  Shell* new_shell = new_shell_observer.GetShell();
  EXPECT_TRUE(new_shell->web_contents()->HasOpener());

  agent_host_ = DevToolsAgentHost::GetOrCreateFor(new_shell->web_contents());
  agent_host_->AttachClient(this);

  GURL test_url2 =
      embedded_test_server()->GetURL("B.com", "/devtools/navigation.html");

  // After this navigation, if the bug exists, the process will crash.
  NavigateToURLBlockUntilNavigationsComplete(new_shell, test_url2, 1);

  // Ensure that the A.com process is still alive by executing a script in the
  // original tab.
  //
  // TODO(alexmos, nasko):  A better way to do this is to navigate the original
  // tab to another site, watch for process exit, and check whether there was a
  // crash. However, currently there's no way to wait for process exit
  // regardless of whether it's a crash or not.  RenderProcessHostWatcher
  // should be fixed to support waiting on both WATCH_FOR_PROCESS_EXIT and
  // WATCH_FOR_HOST_DESTRUCTION, and then used here.
  bool success = false;
  EXPECT_TRUE(ExecuteScriptAndExtractBool(shell(),
                                          "window.domAutomationController.send("
                                          "    !!window.open('', 'foo'));",
                                          &success));
  EXPECT_TRUE(success);

  GURL test_url3 =
      embedded_test_server()->GetURL("A.com", "/devtools/navigation.html");

  // After this navigation, if the bug exists, the process will crash.
  NavigateToURLBlockUntilNavigationsComplete(new_shell, test_url3, 1);

  // Ensure that the A.com process is still alive by executing a script in the
  // original tab.
  success = false;
  EXPECT_TRUE(ExecuteScriptAndExtractBool(shell(),
                                          "window.domAutomationController.send("
                                          "    !!window.open('', 'foo'));",
                                          &success));
  EXPECT_TRUE(success);
}

IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, DoubleCrash) {
  set_agent_host_can_close();
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL test_url = embedded_test_server()->GetURL("/devtools/navigation.html");
  NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
  Attach();
  SendCommand("ServiceWorker.enable", nullptr);
  NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1);
  CrashTab(shell()->web_contents());
  NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1);
  CrashTab(shell()->web_contents());
  NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
  // Should not crash at this point.
}

IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, ReloadBlankPage) {
  Shell* window =  Shell::CreateNewWindow(
      shell()->web_contents()->GetBrowserContext(),
      GURL("javascript:x=1"),
      nullptr,
      gfx::Size());
  WaitForLoadStop(window->web_contents());
  Attach();
  SendCommand("Page.reload", nullptr, false);
  // Should not crash at this point.
}

IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, EvaluateInBlankPage) {
  NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
  Attach();
  std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
  params->SetString("expression", "window");
  SendCommand("Runtime.evaluate", std::move(params), true);
  EXPECT_FALSE(result_->HasKey("exceptionDetails"));
}

IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest,
    EvaluateInBlankPageAfterNavigation) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL test_url = embedded_test_server()->GetURL("/devtools/navigation.html");
  NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1);
  Attach();
  NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
  std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
  params->SetString("expression", "window");
  SendCommand("Runtime.evaluate", std::move(params), true);
  EXPECT_FALSE(result_->HasKey("exceptionDetails"));
}

IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, JavaScriptDialogNotifications) {
  NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
  Attach();
  TestJavaScriptDialogManager dialog_manager;
  shell()->web_contents()->SetDelegate(&dialog_manager);
  SendCommand("Page.enable", nullptr, true);
  std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
  params->SetString("expression", "alert('alert')");
  SendCommand("Runtime.evaluate", std::move(params), false);
  WaitForNotification("Page.javascriptDialogOpening");
  dialog_manager.Handle();
}

IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, BrowserCreateAndCloseTarget) {
  NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
  Attach();
  EXPECT_EQ(1u, shell()->windows().size());
  std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
  params->SetString("url", "about:blank");
  SendCommand("Target.createTarget", std::move(params), true);
  std::string target_id;
  EXPECT_TRUE(result_->GetString("targetId", &target_id));
  EXPECT_EQ(2u, shell()->windows().size());

  // TODO(eseckler): Since the RenderView is closed asynchronously, we currently
  // don't verify that the command actually closes the shell.
  bool success;
  params.reset(new base::DictionaryValue());
  params->SetString("targetId", target_id);
  SendCommand("Target.closeTarget", std::move(params), true);
  EXPECT_TRUE(result_->GetBoolean("success", &success));
  EXPECT_TRUE(success);
}

IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, BrowserGetTargets) {
  NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
  Attach();
  SendCommand("Target.getTargets", nullptr, true);
  base::ListValue* target_infos;
  EXPECT_TRUE(result_->GetList("targetInfos", &target_infos));
  EXPECT_EQ(1u, target_infos->GetSize());
  base::DictionaryValue* target_info;
  EXPECT_TRUE(target_infos->GetDictionary(0u, &target_info));
  std::string target_id, type, title, url;
  EXPECT_TRUE(target_info->GetString("targetId", &target_id));
  EXPECT_TRUE(target_info->GetString("type", &type));
  EXPECT_TRUE(target_info->GetString("title", &title));
  EXPECT_TRUE(target_info->GetString("url", &url));
  EXPECT_EQ("page", type);
  EXPECT_EQ("about:blank", title);
  EXPECT_EQ("about:blank", url);
}

namespace {
class NavigationFinishedObserver : public content::WebContentsObserver {
 public:
  explicit NavigationFinishedObserver(WebContents* web_contents)
      : WebContentsObserver(web_contents),
        num_finished_(0),
        num_to_wait_for_(0) {}

  ~NavigationFinishedObserver() override {}

  void DidFinishNavigation(
      content::NavigationHandle* navigation_handle) override {
    if (navigation_handle->WasServerRedirect())
      return;

    num_finished_++;
    if (num_finished_ >= num_to_wait_for_ && num_to_wait_for_ != 0) {
      base::MessageLoop::current()->QuitNow();
    }
  }

  void WaitForNavigationsToFinish(int num_to_wait_for) {
    if (num_finished_ < num_to_wait_for) {
      num_to_wait_for_ = num_to_wait_for;
      RunMessageLoop();
    }
    num_to_wait_for_ = 0;
  }

 private:
  int num_finished_;
  int num_to_wait_for_;
};
}  // namespace

IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, PageStopLoading) {
  ASSERT_TRUE(embedded_test_server()->Start());

  // Navigate to about:blank first so we can make sure there is a target page we
  // can attach to, and have Page.setControlNavigations complete before we start
  // the navigations we're interested in.
  NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
  Attach();

  std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
  params->SetBoolean("enabled", true);
  SendCommand("Page.setControlNavigations", std::move(params), true);

  NavigationFinishedObserver navigation_finished_observer(
      shell()->web_contents());

  // The page will try to navigate twice, however since
  // Page.setControlNavigations is true, it'll wait for confirmation before
  // committing to the navigation.
  GURL test_url = embedded_test_server()->GetURL(
      "/devtools/control_navigations/meta_tag.html");
  shell()->LoadURL(test_url);

  // Stop all navigations.
  SendCommand("Page.stopLoading", nullptr);

  // Wait for the initial navigation to finish.
  navigation_finished_observer.WaitForNavigationsToFinish(1);
}

IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, ControlNavigationsMainFrame) {
  ASSERT_TRUE(embedded_test_server()->Start());

  // Navigate to about:blank first so we can make sure there is a target page we
  // can attach to, and have Page.setControlNavigations complete before we start
  // the navigations we're interested in.
  NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
  Attach();

  std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
  params->SetBoolean("enabled", true);
  SendCommand("Page.setControlNavigations", std::move(params), true);

  NavigationFinishedObserver navigation_finished_observer(
      shell()->web_contents());

  GURL test_url = embedded_test_server()->GetURL(
      "/devtools/control_navigations/meta_tag.html");
  shell()->LoadURL(test_url);

  std::vector<ExpectedNavigation> expected_navigations = {
      {"http://127.0.0.1/devtools/control_navigations/meta_tag.html",
       true /* expected_is_in_main_frame */, false /* expected_is_redirect */,
       "Proceed"},
      {"http://127.0.0.1/devtools/navigation.html",
       true /* expected_is_in_main_frame */, false /* expected_is_redirect */,
       "Cancel"}};

  ProcessNavigationsAnyOrder(std::move(expected_navigations));

  // Wait for the initial navigation and the cancelled meta refresh navigation
  // to finish.
  navigation_finished_observer.WaitForNavigationsToFinish(2);

  // Check main frame has the expected url.
  EXPECT_EQ(
      "http://127.0.0.1/devtools/control_navigations/meta_tag.html",
      RemovePort(
          shell()->web_contents()->GetMainFrame()->GetLastCommittedURL()));
}

class IsolatedDevToolsProtocolTest : public DevToolsProtocolTest {
 public:
  ~IsolatedDevToolsProtocolTest() override {}

  void SetUpCommandLine(base::CommandLine* command_line) override {
    IsolateAllSitesForTesting(command_line);
  }
};

IN_PROC_BROWSER_TEST_F(IsolatedDevToolsProtocolTest,
                       ControlNavigationsChildFrames) {
  host_resolver()->AddRule("*", "127.0.0.1");
  content::SetupCrossSiteRedirector(embedded_test_server());
  ASSERT_TRUE(embedded_test_server()->Start());

  // Navigate to about:blank first so we can make sure there is a target page we
  // can attach to, and have Page.setControlNavigations complete before we start
  // the navigations we're interested in.
  NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
  Attach();

  std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
  params->SetBoolean("enabled", true);
  SendCommand("Page.setControlNavigations", std::move(params), true);

  NavigationFinishedObserver navigation_finished_observer(
      shell()->web_contents());

  GURL test_url = embedded_test_server()->GetURL(
      "/devtools/control_navigations/iframe_navigation.html");
  shell()->LoadURL(test_url);

  // Allow main frame navigation, and all iframe navigations to http://a.com
  // Allow initial iframe navigation to http://b.com but dissallow it to
  // navigate to /devtools/navigation.html.
  std::vector<ExpectedNavigation> expected_navigations = {
      {"http://127.0.0.1/devtools/control_navigations/"
       "iframe_navigation.html",
       /* expected_is_in_main_frame */ true,
       /* expected_is_redirect */ false, "Proceed"},
      {"http://127.0.0.1/cross-site/a.com/devtools/control_navigations/"
       "meta_tag.html",
       /* expected_is_in_main_frame */ false,
       /* expected_is_redirect */ false, "Proceed"},
      {"http://127.0.0.1/cross-site/b.com/devtools/control_navigations/"
       "meta_tag.html",
       /* expected_is_in_main_frame */ false,
       /* expected_is_redirect */ false, "Proceed"},
      {"http://a.com/devtools/control_navigations/meta_tag.html",
       /* expected_is_in_main_frame */ false,
       /* expected_is_redirect */ true, "Proceed"},
      {"http://b.com/devtools/control_navigations/meta_tag.html",
       /* expected_is_in_main_frame */ false,
       /* expected_is_redirect */ true, "Proceed"},
      {"http://a.com/devtools/navigation.html",
       /* expected_is_in_main_frame */ false,
       /* expected_is_redirect */ false, "Proceed"},
      {"http://b.com/devtools/navigation.html",
       /* expected_is_in_main_frame */ false,
       /* expected_is_redirect */ false, "Cancel"}};

  ProcessNavigationsAnyOrder(std::move(expected_navigations));

  // Wait for each frame's navigation to finish, ignoring redirects.
  navigation_finished_observer.WaitForNavigationsToFinish(3);

  // Make sure each frame has the expected url.
  EXPECT_THAT(
      GetAllFrameUrls(),
      ElementsAre("http://127.0.0.1/devtools/control_navigations/"
                  "iframe_navigation.html",
                  "http://a.com/devtools/navigation.html",
                  "http://b.com/devtools/control_navigations/meta_tag.html"));
}

// Setting RWHV size is not supported on Android.
#if defined(OS_ANDROID)
#define MAYBE_EmulationSetVisibleSize DISABLED_EmulationSetVisibleSize
#else
#define MAYBE_EmulationSetVisibleSize EmulationSetVisibleSize
#endif
IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest,
                       MAYBE_EmulationSetVisibleSize) {
  NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
  Attach();
  gfx::Size new_size(200, 400);
  std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
  params->SetInteger("width", new_size.width());
  params->SetInteger("height", new_size.height());
  SendCommand("Emulation.setVisibleSize", std::move(params), true);
  EXPECT_SIZE_EQ(new_size, (shell()->web_contents())
                               ->GetRenderWidgetHostView()
                               ->GetViewBounds()
                               .size());
}

// TODO(701223): Enable this on android.
#if defined(OS_ANDROID)
#define MAYBE_VirtualTimeTest DISABLED_VirtualTimeTest
#else
#define MAYBE_VirtualTimeTest VirtualTimeTest
#endif
IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, MAYBE_VirtualTimeTest) {
  NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
  Attach();

  std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
  params->SetString("policy", "pause");
  SendCommand("Emulation.setVirtualTimePolicy", std::move(params), true);

  params.reset(new base::DictionaryValue());
  params->SetString("expression",
                    "setTimeout(function(){console.log('before')}, 1000);"
                    "setTimeout(function(){console.log('after')}, 1001);");
  SendCommand("Runtime.evaluate", std::move(params), true);

  // Let virtual time advance for one second.
  params.reset(new base::DictionaryValue());
  params->SetString("policy", "advance");
  params->SetInteger("budget", 1000);
  SendCommand("Emulation.setVirtualTimePolicy", std::move(params), true);

  WaitForNotification("Emulation.virtualTimeBudgetExpired");

  params.reset(new base::DictionaryValue());
  params->SetString("expression", "console.log('done')");
  SendCommand("Runtime.evaluate", std::move(params), true);

  // The second timer shold not fire.
  EXPECT_THAT(console_messages_, ElementsAre("before", "done"));

  // Let virtual time advance for another second, which should make the second
  // timer fire.
  params.reset(new base::DictionaryValue());
  params->SetString("policy", "advance");
  params->SetInteger("budget", 1000);
  SendCommand("Emulation.setVirtualTimePolicy", std::move(params), true);

  WaitForNotification("Emulation.virtualTimeBudgetExpired");

  EXPECT_THAT(console_messages_, ElementsAre("before", "done", "after"));
}

// Tests that the Security.showCertificateViewer command shows the
// certificate corresponding to the visible navigation entry, even when
// an interstitial is showing. Regression test for
// https://crbug.com/647759.
IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, ShowCertificateViewer) {
  // First test that the correct certificate is shown for a normal
  // (non-interstitial) page.
  NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
  Attach();

  // Set a dummy certificate on the NavigationEntry.
  shell()
      ->web_contents()
      ->GetController()
      .GetVisibleEntry()
      ->GetSSL()
      .certificate = ok_cert();

  std::unique_ptr<base::DictionaryValue> params1(new base::DictionaryValue());
  SendCommand("Security.showCertificateViewer", std::move(params1), true);

  scoped_refptr<net::X509Certificate> normal_page_cert = shell()
                                                             ->web_contents()
                                                             ->GetController()
                                                             .GetVisibleEntry()
                                                             ->GetSSL()
                                                             .certificate;
  ASSERT_TRUE(normal_page_cert);
  EXPECT_EQ(normal_page_cert, last_shown_certificate());

  // Now test that the correct certificate is shown on an interstitial.
  TestInterstitialDelegate* delegate = new TestInterstitialDelegate;
  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(shell()->web_contents());
  GURL interstitial_url("https://example.test");
  InterstitialPageImpl* interstitial = new InterstitialPageImpl(
      web_contents, static_cast<RenderWidgetHostDelegate*>(web_contents), true,
      interstitial_url, delegate);
  interstitial->Show();
  WaitForInterstitialAttach(web_contents);

  // Set the transient navigation entry certificate.
  NavigationEntry* transient_entry =
      web_contents->GetController().GetTransientEntry();
  ASSERT_TRUE(transient_entry);
  transient_entry->GetSSL().certificate = expired_cert();
  ASSERT_TRUE(transient_entry->GetSSL().certificate);

  std::unique_ptr<base::DictionaryValue> params2(new base::DictionaryValue());
  SendCommand("Security.showCertificateViewer", std::move(params2), true);
  EXPECT_EQ(transient_entry->GetSSL().certificate, last_shown_certificate());
}

IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, CertificateError) {
  net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
  https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_EXPIRED);
  https_server.ServeFilesFromSourceDirectory("content/test/data");
  ASSERT_TRUE(https_server.Start());
  GURL test_url = https_server.GetURL("/devtools/navigation.html");
  std::unique_ptr<base::DictionaryValue> params;
  std::unique_ptr<base::DictionaryValue> command_params;
  int eventId;

  shell()->LoadURL(GURL("about:blank"));
  WaitForLoadStop(shell()->web_contents());

  Attach();
  SendCommand("Network.enable", nullptr, true);
  SendCommand("Security.enable", nullptr, false);
  command_params.reset(new base::DictionaryValue());
  command_params->SetBoolean("override", true);
  SendCommand("Security.setOverrideCertificateErrors",
              std::move(command_params), true);

  // Test cancel.
  SendCommand("Network.clearBrowserCache", nullptr, true);
  SendCommand("Network.clearBrowserCookies", nullptr, true);
  TestNavigationObserver cancel_observer(shell()->web_contents(), 1);
  shell()->LoadURL(test_url);
  params = WaitForNotification("Security.certificateError", false);
  EXPECT_TRUE(shell()->web_contents()->GetController().GetPendingEntry());
  EXPECT_EQ(
      test_url,
      shell()->web_contents()->GetController().GetPendingEntry()->GetURL());
  EXPECT_TRUE(params->GetInteger("eventId", &eventId));
  command_params.reset(new base::DictionaryValue());
  command_params->SetInteger("eventId", eventId);
  command_params->SetString("action", "cancel");
  SendCommand("Security.handleCertificateError", std::move(command_params),
              false);
  cancel_observer.Wait();
  EXPECT_FALSE(shell()->web_contents()->GetController().GetPendingEntry());
  EXPECT_EQ(GURL("about:blank"), shell()
                                     ->web_contents()
                                     ->GetController()
                                     .GetLastCommittedEntry()
                                     ->GetURL());

  // Test continue.
  SendCommand("Network.clearBrowserCache", nullptr, true);
  SendCommand("Network.clearBrowserCookies", nullptr, true);
  TestNavigationObserver continue_observer(shell()->web_contents(), 1);
  shell()->LoadURL(test_url);
  params = WaitForNotification("Security.certificateError", false);
  EXPECT_TRUE(params->GetInteger("eventId", &eventId));
  command_params.reset(new base::DictionaryValue());
  command_params->SetInteger("eventId", eventId);
  command_params->SetString("action", "continue");
  SendCommand("Security.handleCertificateError", std::move(command_params),
              false);
  WaitForNotification("Network.loadingFinished", true);
  continue_observer.Wait();
  EXPECT_EQ(test_url, shell()
                          ->web_contents()
                          ->GetController()
                          .GetLastCommittedEntry()
                          ->GetURL());
}

IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, SubresourceWithCertificateError) {
  net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
  https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_EXPIRED);
  https_server.ServeFilesFromSourceDirectory("content/test/data/devtools");
  ASSERT_TRUE(https_server.Start());
  GURL test_url = https_server.GetURL("/image.html");
  std::unique_ptr<base::DictionaryValue> params;
  std::unique_ptr<base::DictionaryValue> command_params;
  int eventId;

  shell()->LoadURL(GURL("about:blank"));
  WaitForLoadStop(shell()->web_contents());

  Attach();
  SendCommand("Security.enable", nullptr, false);
  command_params.reset(new base::DictionaryValue());
  command_params->SetBoolean("override", true);
  SendCommand("Security.setOverrideCertificateErrors",
              std::move(command_params), true);

  TestNavigationObserver observer(shell()->web_contents(), 1);
  shell()->LoadURL(test_url);

  // Expect certificateError event for main frame.
  params = WaitForNotification("Security.certificateError", false);
  EXPECT_TRUE(params->GetInteger("eventId", &eventId));
  command_params.reset(new base::DictionaryValue());
  command_params->SetInteger("eventId", eventId);
  command_params->SetString("action", "continue");
  SendCommand("Security.handleCertificateError", std::move(command_params),
              false);

  // Expect certificateError event for image.
  params = WaitForNotification("Security.certificateError", false);
  EXPECT_TRUE(params->GetInteger("eventId", &eventId));
  command_params.reset(new base::DictionaryValue());
  command_params->SetInteger("eventId", eventId);
  command_params->SetString("action", "continue");
  SendCommand("Security.handleCertificateError", std::move(command_params),
              false);

  observer.Wait();
  EXPECT_EQ(test_url, shell()
                          ->web_contents()
                          ->GetController()
                          .GetLastCommittedEntry()
                          ->GetURL());
}

IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, TargetDiscovery) {
  std::string temp;
  std::set<std::string> ids;
  std::unique_ptr<base::DictionaryValue> command_params;
  std::unique_ptr<base::DictionaryValue> params;

  ASSERT_TRUE(embedded_test_server()->Start());
  GURL first_url = embedded_test_server()->GetURL("/devtools/navigation.html");
  NavigateToURLBlockUntilNavigationsComplete(shell(), first_url, 1);

  GURL second_url = embedded_test_server()->GetURL("/devtools/navigation.html");
  Shell* second = CreateBrowser();
  NavigateToURLBlockUntilNavigationsComplete(second, second_url, 1);

  Attach();
  command_params.reset(new base::DictionaryValue());
  command_params->SetBoolean("discover", true);
  SendCommand("Target.setDiscoverTargets", std::move(command_params), true);
  params = WaitForNotification("Target.targetCreated", true);
  EXPECT_TRUE(params->GetString("targetInfo.type", &temp));
  EXPECT_EQ("page", temp);
  EXPECT_TRUE(params->GetString("targetInfo.targetId", &temp));
  EXPECT_TRUE(ids.find(temp) == ids.end());
  ids.insert(temp);
  params = WaitForNotification("Target.targetCreated", true);
  EXPECT_TRUE(params->GetString("targetInfo.type", &temp));
  EXPECT_EQ("page", temp);
  EXPECT_TRUE(params->GetString("targetInfo.targetId", &temp));
  EXPECT_TRUE(ids.find(temp) == ids.end());
  ids.insert(temp);
  EXPECT_TRUE(notifications_.empty());

  GURL third_url = embedded_test_server()->GetURL("/devtools/navigation.html");
  Shell* third = CreateBrowser();
  NavigateToURLBlockUntilNavigationsComplete(third, third_url, 1);
  params = WaitForNotification("Target.targetCreated", true);
  EXPECT_TRUE(params->GetString("targetInfo.type", &temp));
  EXPECT_EQ("page", temp);
  EXPECT_TRUE(params->GetString("targetInfo.targetId", &temp));
  EXPECT_TRUE(ids.find(temp) == ids.end());
  std::string attached_id = temp;
  ids.insert(temp);
  EXPECT_TRUE(notifications_.empty());

  second->Close();
  second = nullptr;
  params = WaitForNotification("Target.targetDestroyed", true);
  EXPECT_TRUE(params->GetString("targetId", &temp));
  EXPECT_TRUE(ids.find(temp) != ids.end());
  ids.erase(temp);
  EXPECT_TRUE(notifications_.empty());

  command_params.reset(new base::DictionaryValue());
  command_params->SetString("targetId", attached_id);
  SendCommand("Target.attachToTarget", std::move(command_params), true);
  params = WaitForNotification("Target.attachedToTarget", true);
  EXPECT_TRUE(params->GetString("targetInfo.targetId", &temp));
  EXPECT_EQ(attached_id, temp);
  EXPECT_TRUE(notifications_.empty());

  command_params.reset(new base::DictionaryValue());
  command_params->SetBoolean("discover", false);
  SendCommand("Target.setDiscoverTargets", std::move(command_params), true);
  params = WaitForNotification("Target.targetDestroyed", true);
  EXPECT_TRUE(params->GetString("targetId", &temp));
  EXPECT_TRUE(ids.find(temp) != ids.end());
  ids.erase(temp);
  params = WaitForNotification("Target.targetDestroyed", true);
  EXPECT_TRUE(params->GetString("targetId", &temp));
  EXPECT_TRUE(ids.find(temp) != ids.end());
  ids.erase(temp);
  EXPECT_TRUE(notifications_.empty());

  command_params.reset(new base::DictionaryValue());
  command_params->SetString("targetId", attached_id);
  SendCommand("Target.detachFromTarget", std::move(command_params), true);
  params = WaitForNotification("Target.detachedFromTarget", true);
  EXPECT_TRUE(params->GetString("targetId", &temp));
  EXPECT_EQ(attached_id, temp);
  EXPECT_TRUE(notifications_.empty());
}

// Tests that an interstitialShown event is sent when an interstitial is showing
// on attach.
IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, InterstitialShownOnAttach) {
  TestInterstitialDelegate* delegate = new TestInterstitialDelegate;
  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(shell()->web_contents());
  GURL interstitial_url("https://example.test");
  InterstitialPageImpl* interstitial = new InterstitialPageImpl(
      web_contents, static_cast<RenderWidgetHostDelegate*>(web_contents), true,
      interstitial_url, delegate);
  interstitial->Show();
  WaitForInterstitialAttach(web_contents);
  Attach();
  SendCommand("Page.enable", nullptr, false);
  WaitForNotification("Page.interstitialShown", true);
}

class SitePerProcessDevToolsProtocolTest : public DevToolsProtocolTest {
 public:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    DevToolsProtocolTest::SetUpCommandLine(command_line);
    IsolateAllSitesForTesting(command_line);
  };

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

IN_PROC_BROWSER_TEST_F(SitePerProcessDevToolsProtocolTest, TargetNoDiscovery) {
  std::string temp;
  std::string target_id;
  std::unique_ptr<base::DictionaryValue> command_params;
  std::unique_ptr<base::DictionaryValue> params;

  GURL main_url(embedded_test_server()->GetURL("/site_per_process_main.html"));
  NavigateToURLBlockUntilNavigationsComplete(shell(), main_url, 1);
  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root =
      static_cast<WebContentsImpl*>(shell()->web_contents())->
          GetFrameTree()->root();

  // Load cross-site page into iframe.
  GURL::Replacements replace_host;
  GURL cross_site_url(embedded_test_server()->GetURL("/title1.html"));
  replace_host.SetHostStr("foo.com");
  cross_site_url = cross_site_url.ReplaceComponents(replace_host);
  NavigateFrameToURL(root->child_at(0), cross_site_url);

  // Enable auto-attach.
  Attach();
  command_params.reset(new base::DictionaryValue());
  command_params->SetBoolean("autoAttach", true);
  command_params->SetBoolean("waitForDebuggerOnStart", true);
  SendCommand("Target.setAutoAttach", std::move(command_params), true);
  EXPECT_TRUE(notifications_.empty());
  command_params.reset(new base::DictionaryValue());
  command_params->SetBoolean("value", true);
  SendCommand("Target.setAttachToFrames", std::move(command_params), false);
  params = WaitForNotification("Target.attachedToTarget", true);
  EXPECT_TRUE(params->GetString("targetInfo.targetId", &target_id));
  EXPECT_TRUE(params->GetString("targetInfo.type", &temp));
  EXPECT_EQ("iframe", temp);

  // Load same-site page into iframe.
  FrameTreeNode* child = root->child_at(0);
  GURL http_url(embedded_test_server()->GetURL("/title1.html"));
  NavigateFrameToURL(child, http_url);
  params = WaitForNotification("Target.detachedFromTarget", true);
  EXPECT_TRUE(params->GetString("targetId", &temp));
  EXPECT_EQ(target_id, temp);

  // Navigate back to cross-site iframe.
  NavigateFrameToURL(root->child_at(0), cross_site_url);
  params = WaitForNotification("Target.attachedToTarget", true);
  EXPECT_TRUE(params->GetString("targetInfo.targetId", &target_id));
  EXPECT_TRUE(params->GetString("targetInfo.type", &temp));
  EXPECT_EQ("iframe", temp);

  // Disable auto-attach.
  command_params.reset(new base::DictionaryValue());
  command_params->SetBoolean("autoAttach", false);
  command_params->SetBoolean("waitForDebuggerOnStart", false);
  SendCommand("Target.setAutoAttach", std::move(command_params), false);
  params = WaitForNotification("Target.detachedFromTarget", true);
  EXPECT_TRUE(params->GetString("targetId", &temp));
  EXPECT_EQ(target_id, temp);
}

IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, SetAndGetCookies) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL test_url = embedded_test_server()->GetURL("/title1.html");
  NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1);
  Attach();

  // Set two cookies, one of which matches the loaded URL and another that
  // doesn't.
  std::unique_ptr<base::DictionaryValue> command_params;
  command_params.reset(new base::DictionaryValue());
  command_params->SetString("url", test_url.spec());
  command_params->SetString("name", "cookie_for_this_url");
  command_params->SetString("value", "mendacious");
  SendCommand("Network.setCookie", std::move(command_params), false);

  command_params.reset(new base::DictionaryValue());
  command_params->SetString("url", "https://www.chromium.org");
  command_params->SetString("name", "cookie_for_another_url");
  command_params->SetString("value", "polyglottal");
  SendCommand("Network.setCookie", std::move(command_params), false);

  // First get the cookies for just the loaded URL.
  SendCommand("Network.getCookies", nullptr, true);

  base::ListValue* cookies;
  EXPECT_TRUE(result_->HasKey("cookies"));
  EXPECT_TRUE(result_->GetList("cookies", &cookies));
  EXPECT_EQ(1u, cookies->GetSize());

  base::DictionaryValue* cookie;
  std::string name;
  std::string value;
  EXPECT_TRUE(cookies->GetDictionary(0, &cookie));
  EXPECT_TRUE(cookie->GetString("name", &name));
  EXPECT_TRUE(cookie->GetString("value", &value));
  EXPECT_EQ("cookie_for_this_url", name);
  EXPECT_EQ("mendacious", value);

  // Then get all the cookies in the cookie jar.
  SendCommand("Network.getAllCookies", nullptr, true);

  EXPECT_TRUE(result_->HasKey("cookies"));
  EXPECT_TRUE(result_->GetList("cookies", &cookies));
  EXPECT_EQ(2u, cookies->GetSize());

  // Note: the cookies will be returned in unspecified order.
  size_t found = 0;
  for (size_t i = 0; i < cookies->GetSize(); i++) {
    EXPECT_TRUE(cookies->GetDictionary(i, &cookie));
    EXPECT_TRUE(cookie->GetString("name", &name));
    if (name == "cookie_for_this_url") {
      EXPECT_TRUE(cookie->GetString("value", &value));
      EXPECT_EQ("mendacious", value);
      found++;
    } else if (name == "cookie_for_another_url") {
      EXPECT_TRUE(cookie->GetString("value", &value));
      EXPECT_EQ("polyglottal", value);
      found++;
    } else {
      FAIL();
    }
  }
  EXPECT_EQ(2u, found);
}

}  // namespace content
