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

#include <algorithm>
#include <initializer_list>
#include <memory>
#include <string>
#include <vector>

#include "base/bind.h"
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/pattern.h"
#include "base/strings/string_piece.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "build/build_config.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/interactive_test_utils.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.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/hit_test_region_observer.h"
#include "content/public/test/test_frame_navigation_observer.h"
#include "content/public/test/test_utils.h"
#include "net/base/escape.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/aura/client/drag_drop_client.h"
#include "ui/aura/client/drag_drop_delegate.h"
#include "ui/aura/client/screen_position_client.h"
#include "ui/aura/window.h"
#include "ui/base/dragdrop/drag_drop_types.h"
#include "ui/base/dragdrop/drop_target_event.h"
#include "ui/base/dragdrop/os_exchange_data.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
#include "url/gurl.h"

namespace chrome {

namespace {

// TODO(lukasza): Support testing on non-Aura platforms (i.e. Android + Mac?).
//
// Notes for the TODO above:
//
// - Why inject/simulate drag-and-drop events at the aura::Window* level.
//
//   - It seems better to inject into UI libraries to cover code *inside* these
//     libraries.  This might complicate simulation a little bit (i.e. picking
//     the right aura::Window and/or aura::client::DragDropDelegate to target),
//     but otherwise important bits of code wouldn't get test coverage (i.e.
//     directly injecting into RenderViewHost->DragTargetDragEnter seems wrong).
//
//   - In theory, we could introduce WebContentsImpl::DragTargetDragEnter (to be
//     used by all UI platforms - so reused by web_contents_view_android.cc,
//     web_contents_view_aura.cc, web_drag_dest_mac.mm), but it feels wrong - UI
//     libraries should already know which widget is the target of the event and
//     so should be able to talk directly to the right widget (i.e. WebContents
//     should not be responsible for mapping coordinates to a widget - this is
//     the job of the UI library).
//
// - Unknowns:
//
//   - Will this work for WebView and Plugin testing.

// Test helper for simulating drag and drop happening in WebContents.
class DragAndDropSimulator {
 public:
  explicit DragAndDropSimulator(content::WebContents* web_contents)
      : web_contents_(web_contents) {}

  // Simulates notification that |text| was dragged from outside of the browser,
  // into the specified |location| inside |web_contents|.
  // |location| is relative to |web_contents|.
  // Returns true upon success.
  bool SimulateDragEnter(gfx::Point location, const std::string& text) {
    ui::OSExchangeData data;
    data.SetString(base::UTF8ToUTF16(text));
    return SimulateDragEnter(location, data);
  }

  // Simulates dropping of the drag-and-dropped item.
  // SimulateDragEnter needs to be called first.
  // Returns true upon success.
  bool SimulateDrop(gfx::Point location) {
    if (!active_drag_event_) {
      ADD_FAILURE() << "Cannot drop a drag that hasn't started yet.";
      return false;
    }

    aura::client::DragDropDelegate* delegate = GetDragDropDelegate();
    if (!delegate)
      return false;

    gfx::PointF event_location;
    gfx::PointF event_root_location;
    CalculateEventLocations(location, &event_location, &event_root_location);
    active_drag_event_->set_location_f(event_location);
    active_drag_event_->set_root_location_f(event_root_location);

    delegate->OnDragUpdated(*active_drag_event_);
    delegate->OnPerformDrop(*active_drag_event_);
    return true;
  }

 private:
  bool SimulateDragEnter(gfx::Point location, const ui::OSExchangeData& data) {
    if (active_drag_event_) {
      ADD_FAILURE() << "Cannot start a new drag when old one hasn't ended yet.";
      return false;
    }

    aura::client::DragDropDelegate* delegate = GetDragDropDelegate();
    if (!delegate)
      return false;

    gfx::PointF event_location;
    gfx::PointF event_root_location;
    CalculateEventLocations(location, &event_location, &event_root_location);
    active_drag_event_.reset(new ui::DropTargetEvent(
        data, event_location, event_root_location, kDefaultSourceOperations));

    delegate->OnDragEntered(*active_drag_event_);
    delegate->OnDragUpdated(*active_drag_event_);
    return true;
  }

  aura::client::DragDropDelegate* GetDragDropDelegate() {
    gfx::NativeView view = web_contents_->GetContentNativeView();
    aura::client::DragDropDelegate* delegate =
        aura::client::GetDragDropDelegate(view);
    EXPECT_TRUE(delegate) << "Expecting WebContents to have DragDropDelegate";
    return delegate;
  }

  void CalculateEventLocations(gfx::Point web_contents_relative_location,
                               gfx::PointF* out_event_location,
                               gfx::PointF* out_event_root_location) {
    gfx::NativeView view = web_contents_->GetNativeView();

    *out_event_location = gfx::PointF(web_contents_relative_location);

    gfx::Point root_location = web_contents_relative_location;
    aura::Window::ConvertPointToTarget(view, view->GetRootWindow(),
                                       &root_location);
    *out_event_root_location = gfx::PointF(root_location);
  }

  // These are ui::DropTargetEvent::source_operations_ being sent when manually
  // trying out drag&drop of an image file from Nemo (Ubuntu's file explorer)
  // into a content_shell.
  static constexpr int kDefaultSourceOperations = ui::DragDropTypes::DRAG_MOVE |
                                                  ui::DragDropTypes::DRAG_COPY |
                                                  ui::DragDropTypes::DRAG_LINK;

  content::WebContents* web_contents_;
  std::unique_ptr<ui::DropTargetEvent> active_drag_event_;

  DISALLOW_COPY_AND_ASSIGN(DragAndDropSimulator);
};

// Helper for waiting until a drag-and-drop starts (e.g. in response to a
// mouse-down + mouse-move simulated by the test).
class DragStartWaiter : public aura::client::DragDropClient {
 public:
  // Starts monitoring |web_contents| for a start of a drag-and-drop.
  explicit DragStartWaiter(content::WebContents* web_contents)
      : web_contents_(web_contents),
        message_loop_runner_(new content::MessageLoopRunner),
        suppress_passing_of_start_drag_further_(false),
        drag_started_(false) {
    DCHECK(web_contents_);

    // Intercept calls to the old DragDropClient.
    gfx::NativeWindow root_window =
        web_contents_->GetContentNativeView()->GetRootWindow();
    old_client_ = aura::client::GetDragDropClient(root_window);
    aura::client::SetDragDropClient(root_window, this);
  }

  ~DragStartWaiter() override {
    // Restore the original DragDropClient.
    gfx::NativeWindow root_window =
        web_contents_->GetContentNativeView()->GetRootWindow();
    aura::client::SetDragDropClient(root_window, old_client_);
  }

  // Waits until we almost report a drag-and-drop start to the OS.
  // At that point
  // 1) the callback from PostTaskWhenDragStarts will be posted.
  // 2) the drag-start request will be forwarded to the OS
  //    (unless SuppressPassingStartDragFurther method was called).
  //
  // Note that if SuppressPassingStartDragFurther was not called then
  // WaitUntilDragStart can take a long time to return (it returns only after
  // the OS decides that the drag-and-drop has ended).
  //
  // Before returning populates |text|, |html| and other parameters with data
  // that would have been passed to the OS).  If the caller is not interested in
  // this data, then the corresponding argument can be null.
  void WaitUntilDragStart(std::string* text,
                          std::string* html,
                          int* operation,
                          gfx::Point* location_inside_web_contents) {
    message_loop_runner_->Run();

    // message_loop_runner_->Quit is only called from StartDragAndDrop.
    DCHECK(drag_started_);

    if (text)
      *text = text_;
    if (html)
      *html = html_;
    if (operation)
      *operation = operation_;
    if (location_inside_web_contents)
      *location_inside_web_contents = location_inside_web_contents_;
  }

  void SuppressPassingStartDragFurther() {
    suppress_passing_of_start_drag_further_ = true;
  }

  void PostTaskWhenDragStarts(const base::Closure& callback) {
    callback_to_run_inside_drag_and_drop_message_loop_ = callback;
  }

  // aura::client::DragDropClient overrides:
  int StartDragAndDrop(const ui::OSExchangeData& data,
                       aura::Window* root_window,
                       aura::Window* source_window,
                       const gfx::Point& screen_location,
                       int operation,
                       ui::DragDropTypes::DragEventSource source) override {
    DCHECK(!drag_started_);
    if (!drag_started_) {
      drag_started_ = true;
      message_loop_runner_->Quit();

      base::string16 text;
      if (data.GetString(&text))
        text_ = base::UTF16ToUTF8(text);
      else
        text_ = "<no text>";

      GURL base_url;
      base::string16 html;
      if (data.GetHtml(&html, &base_url))
        html_ = base::UTF16ToUTF8(html);
      else
        html_ = "<no html>";

      gfx::Rect bounds =
          web_contents_->GetContentNativeView()->GetBoundsInScreen();
      location_inside_web_contents_ =
          screen_location - gfx::Vector2d(bounds.x(), bounds.y());

      operation_ = operation;
    }

    if (!callback_to_run_inside_drag_and_drop_message_loop_.is_null()) {
      base::SequencedTaskRunnerHandle::Get()->PostTask(
          FROM_HERE,
          std::move(callback_to_run_inside_drag_and_drop_message_loop_));
      callback_to_run_inside_drag_and_drop_message_loop_.Reset();
    }

    if (suppress_passing_of_start_drag_further_)
      return 0;

    // Start a nested drag-and-drop loop (might not return for a long time).
    return old_client_->StartDragAndDrop(data, root_window, source_window,
                                         screen_location, operation, source);
  }

  void DragCancel() override {
    ADD_FAILURE() << "Unexpected call to DragCancel";
  }

  bool IsDragDropInProgress() override { return drag_started_; }

  void AddObserver(aura::client::DragDropClientObserver* observer) override {}
  void RemoveObserver(aura::client::DragDropClientObserver* observer) override {
  }

 private:
  content::WebContents* web_contents_;
  scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
  aura::client::DragDropClient* old_client_;
  base::Closure callback_to_run_inside_drag_and_drop_message_loop_;
  bool suppress_passing_of_start_drag_further_;

  // Data captured during the first intercepted StartDragAndDrop call.
  bool drag_started_;
  std::string text_;
  std::string html_;
  int operation_;
  gfx::Point location_inside_web_contents_;

  DISALLOW_COPY_AND_ASSIGN(DragStartWaiter);
};

// Helper for waiting for notifications from
// content/test/data/drag_and_drop/event_monitoring.js
class DOMDragEventWaiter {
 public:
  DOMDragEventWaiter(const std::string& event_type_to_wait_for,
                     const content::ToRenderFrameHost& target)
      : target_frame_name_(target.render_frame_host()->GetFrameName()),
        event_type_to_wait_for_(event_type_to_wait_for),
        dom_message_queue_(content::WebContents::FromRenderFrameHost(
            target.render_frame_host())) {}

  // Waits until |target| calls reportDragEvent in
  // chrome/test/data/drag_and_drop/event_monitoring.js with event_type
  // property set to |event_type_to_wait_for|.  (|target| and
  // |event_type_to_wait_for| are passed to the constructor).
  //
  // Returns the event details via |found_event| (in form of a JSON-encoded
  // object).  See chrome/test/data/drag_and_drop/event_monitoring.js for keys
  // and properties that |found_event| is expected to have.
  //
  // Returns true upon success.  It is okay if |response| is null.
  bool WaitForNextMatchingEvent(std::string* found_event) WARN_UNUSED_RESULT {
    std::string candidate_event;
    bool got_right_event_type = false;
    bool got_right_window_name = false;
    do {
      if (!dom_message_queue_.WaitForMessage(&candidate_event))
        return false;

      got_right_event_type =
          IsExpectedEventType(candidate_event, event_type_to_wait_for_);
      got_right_window_name =
          IsExpectedWindowName(candidate_event, target_frame_name_);
    } while (!got_right_event_type || !got_right_window_name);

    if (found_event)
      *found_event = candidate_event;

    return true;
  }

  static bool IsExpectedEventType(const std::string& actual_event_body,
                                  const std::string& expected_event_type) {
    return IsExpectedPropertyValue(actual_event_body, "event_type",
                                   expected_event_type);
  }

  static bool IsExpectedWindowName(const std::string& actual_event_body,
                                   const std::string& expected_window_name) {
    return IsExpectedPropertyValue(actual_event_body, "window_name",
                                   expected_window_name);
  }

 private:
  static bool IsExpectedPropertyValue(
      const std::string& actual_event_body,
      const std::string& property_name,
      const std::string& expected_property_value) {
    return base::MatchPattern(
        actual_event_body,
        base::StringPrintf("*\"%s\":\"%s\"*", property_name.c_str(),
                           expected_property_value.c_str()));
  }

  std::string target_frame_name_;
  std::string event_type_to_wait_for_;
  content::DOMMessageQueue dom_message_queue_;

  DISALLOW_COPY_AND_ASSIGN(DOMDragEventWaiter);
};

// Helper for verifying contents of DOM events associated with drag-and-drop.
class DOMDragEventVerifier {
 public:
  DOMDragEventVerifier() {}

  void set_expected_client_position(const std::string& value) {
    expected_client_position_ = value;
  }

  void set_expected_drop_effect(const std::string& value) {
    expected_drop_effect_ = value;
  }

  void set_expected_effect_allowed(const std::string& value) {
    expected_effect_allowed_ = value;
  }

  void set_expected_mime_types(const std::string& value) {
    expected_mime_types_ = value;
  }

  void set_expected_page_position(const std::string& value) {
    expected_page_position_ = value;
  }

  // Returns a matcher that will match a std::string (drag event data - e.g.
  // one returned by DOMDragEventWaiter::WaitForNextMatchingEvent) if it matches
  // the expectations of this DOMDragEventVerifier.
  testing::Matcher<std::string> Matches() const {
    return testing::AllOf(
        FieldMatches("client_position", expected_client_position_),
        FieldMatches("drop_effect", expected_drop_effect_),
        FieldMatches("effect_allowed", expected_effect_allowed_),
        FieldMatches("mime_types", expected_mime_types_),
        FieldMatches("page_position", expected_page_position_));
  }

 private:
  static testing::Matcher<std::string> FieldMatches(
      const std::string& field_name,
      const std::string& expected_value) {
    if (expected_value == "<no expectation>")
      return testing::A<std::string>();

    return testing::HasSubstr(base::StringPrintf(
        "\"%s\":\"%s\"", field_name.c_str(), expected_value.c_str()));
  }

  std::string expected_drop_effect_ = "<no expectation>";
  std::string expected_effect_allowed_ = "<no expectation>";
  std::string expected_mime_types_ = "<no expectation>";
  std::string expected_client_position_ = "<no expectation>";
  std::string expected_page_position_ = "<no expectation>";

  DISALLOW_COPY_AND_ASSIGN(DOMDragEventVerifier);
};

// Helper for monitoring event notifications from
// content/test/data/drag_and_drop/event_monitoring.js
// and counting how many events of a given type were received.
class DOMDragEventCounter {
 public:
  explicit DOMDragEventCounter(const content::ToRenderFrameHost& target)
      : target_frame_name_(target.render_frame_host()->GetFrameName()),
        dom_message_queue_(content::WebContents::FromRenderFrameHost(
            target.render_frame_host())) {}

  // Resets all the accumulated event counts to zeros.
  void Reset() {
    StoreAccumulatedEvents();
    received_events_.clear();
  }

  // Returns the number of events of the specified |event_type| received since
  // construction, or since the last time Reset was called.  |event_type| should
  // be one of possible |type| property values for a DOM drag-and-drop event -
  // e.g.  "dragenter" or "dragover".
  int GetNumberOfReceivedEvents(const std::string& event_type) {
    std::vector<std::string> v({event_type});
    return GetNumberOfReceivedEvents(v.begin(), v.end());
  }

  // Returns the number of events of the specified |event_types| received since
  // construction, or since the last time Reset was called.  Elements of
  // |event_types| should be one of possible |type| property values for a DOM
  // drag-and-drop event - e.g.  "dragenter" or "dragover".
  int GetNumberOfReceivedEvents(
      std::initializer_list<const char*> event_types) {
    return GetNumberOfReceivedEvents(event_types.begin(), event_types.end());
  }

 private:
  template <typename T>
  int GetNumberOfReceivedEvents(T event_types_begin, T event_types_end) {
    StoreAccumulatedEvents();

    auto received_event_has_matching_event_type =
        [&event_types_begin,
         &event_types_end](const std::string& received_event) {
          return std::any_of(event_types_begin, event_types_end,
                             [&received_event](const std::string& event_type) {
                               return DOMDragEventWaiter::IsExpectedEventType(
                                   received_event, event_type);
                             });
        };

    return std::count_if(received_events_.begin(), received_events_.end(),
                         received_event_has_matching_event_type);
  }

  void StoreAccumulatedEvents() {
    std::string candidate_event;
    while (dom_message_queue_.PopMessage(&candidate_event)) {
      if (DOMDragEventWaiter::IsExpectedWindowName(candidate_event,
                                                   target_frame_name_)) {
        received_events_.push_back(candidate_event);
      }
    }
  }

  std::string target_frame_name_;
  content::DOMMessageQueue dom_message_queue_;
  std::vector<std::string> received_events_;

  DISALLOW_COPY_AND_ASSIGN(DOMDragEventCounter);
};

const char kTestPagePath[] = "/drag_and_drop/page.html";

}  // namespace

class DragAndDropBrowserTest : public InProcessBrowserTest,
                               public testing::WithParamInterface<bool> {
 public:
  DragAndDropBrowserTest() {}

  struct DragImageBetweenFrames_TestState;
  void DragImageBetweenFrames_Step2(DragImageBetweenFrames_TestState*);
  void DragImageBetweenFrames_Step3(DragImageBetweenFrames_TestState*);

  struct DragImageFromDisappearingFrame_TestState;
  void DragImageFromDisappearingFrame_Step2(
      DragImageFromDisappearingFrame_TestState*);
  void DragImageFromDisappearingFrame_Step3(
      DragImageFromDisappearingFrame_TestState*);

  struct CrossSiteDrag_TestState;
  void CrossSiteDrag_Step2(CrossSiteDrag_TestState*);
  void CrossSiteDrag_Step3(CrossSiteDrag_TestState*);

 protected:
  void SetUpOnMainThread() override {
    host_resolver()->AddRule("*", "127.0.0.1");
    content::SetupCrossSiteRedirector(embedded_test_server());
    ASSERT_TRUE(embedded_test_server()->Start());
    drag_simulator_.reset(new DragAndDropSimulator(web_contents()));
  }

  bool use_cross_site_subframe() {
    // This is controlled by gtest's test param from INSTANTIATE_TEST_SUITE_P.
    return GetParam();
  }

  content::RenderFrameHost* left_frame() {
    AssertTestPageIsLoaded();
    return GetFrameByName("left");
  }

  content::RenderFrameHost* right_frame() {
    AssertTestPageIsLoaded();
    return GetFrameByName("right");
  }

  content::WebContents* web_contents() {
    return browser()->tab_strip_model()->GetActiveWebContents();
  }

  //////////////////////
  // Navigation helpers.

  bool NavigateToTestPage(const std::string& origin_of_main_frame) {
    GURL url =
        embedded_test_server()->GetURL(origin_of_main_frame, kTestPagePath);
    ui_test_utils::NavigateToURL(browser(), url);
    return web_contents()->GetLastCommittedURL() == url;
  }

  // Navigates the left frame to |filename| (found under
  // chrome/test/data/drag_and_drop directory).
  bool NavigateLeftFrame(const std::string& origin,
                         const std::string& filename) {
    AssertTestPageIsLoaded();
    return NavigateNamedFrame("left", origin, filename);
  }

  // Navigates the right frame to |filename| (found under
  // chrome/test/data/drag_and_drop directory).
  bool NavigateRightFrame(const std::string& origin,
                          const std::string& filename) {
    AssertTestPageIsLoaded();
    return NavigateNamedFrame("right", origin, filename);
  }

  ////////////////////////////////////////////////////////////
  // Simulation of starting a drag-and-drop (using the mouse).

  bool SimulateMouseDownAndDragStartInLeftFrame() {
    AssertTestPageIsLoaded();

    // Waiting until the mousemove and mousedown events reach the right renderer
    // is needed to avoid flakiness reported in https://crbug.com/671445 (which
    // has its root cause in https://crbug.com/647378).  Once the latter bug
    // is fixed, we should no longer need to wait for these events (because
    // fixing https://crbug.com/647378 should guarantee that events arrive
    // to the renderer in the right order).
    DOMDragEventWaiter mouse_move_event_waiter("mousemove", left_frame());
    DOMDragEventWaiter mouse_down_event_waiter("mousedown", left_frame());

    if (!SimulateMouseMove(kMiddleOfLeftFrame))
      return false;
    if (!mouse_move_event_waiter.WaitForNextMatchingEvent(nullptr))
      return false;

    if (!SimulateMouseDown())
      return false;
    if (!mouse_down_event_waiter.WaitForNextMatchingEvent(nullptr))
      return false;

    if (!SimulateMouseMove(expected_location_of_drag_start_in_left_frame()))
      return false;

    return true;
  }

  gfx::Point expected_location_of_drag_start_in_left_frame() {
    // TODO(crbug.com/653490): The delta below should exceed kDragThresholdX and
    // kDragThresholdY from MouseEventManager.cpp in blink.  Ideally, it would
    // come from the OS instead.
    return kMiddleOfLeftFrame + gfx::Vector2d(10, 10);
  }

  bool SimulateMouseMoveToLeftFrame() {
    AssertTestPageIsLoaded();
    return SimulateMouseMove(kMiddleOfLeftFrame);
  }

  bool SimulateMouseMoveToRightFrame() {
    AssertTestPageIsLoaded();
    return SimulateMouseMove(kMiddleOfRightFrame);
  }

  bool SimulateMouseUp() {
    return ui_test_utils::SendMouseEventsSync(ui_controls::LEFT,
                                              ui_controls::UP);
  }

  ////////////////////////////////////////////////////////////////////
  // Simulation of dragging from outside the browser into web contents
  // (using DragAndDropSimulator, not simulating mouse events).

  bool SimulateDragEnterToRightFrame(const std::string& text) {
    AssertTestPageIsLoaded();
    return drag_simulator_->SimulateDragEnter(kMiddleOfRightFrame, text);
  }

  bool SimulateDropInRightFrame() {
    AssertTestPageIsLoaded();
    return drag_simulator_->SimulateDrop(kMiddleOfRightFrame);
  }

 private:
  // Constants with coordinates within content/test/data/drag_and_drop/page.html
  // The precise frame center is at 200,200 and 400,200 coordinates, but slight
  // differences between left and right frame hopefully make it easier to detect
  // incorrect dom_drag_and_drop_event.clientX/Y values in test asserts.
  const gfx::Point kMiddleOfLeftFrame = gfx::Point(155, 150);
  const gfx::Point kMiddleOfRightFrame = gfx::Point(455, 250);

  bool SimulateMouseDown() {
    return ui_test_utils::SendMouseEventsSync(ui_controls::LEFT,
                                              ui_controls::DOWN);
  }

  bool SimulateMouseMove(const gfx::Point& location_inside_web_contents) {
    gfx::Rect bounds = web_contents()->GetContainerBounds();
    return ui_test_utils::SendMouseMoveSync(
        gfx::Point(bounds.x() + location_inside_web_contents.x(),
                   bounds.y() + location_inside_web_contents.y()));
  }

  bool NavigateNamedFrame(const std::string& frame_name,
                          const std::string& origin,
                          const std::string& filename) {
    content::RenderFrameHost* frame = GetFrameByName(frame_name);
    if (!frame)
      return false;

    std::string script;
    int response = 0;

    // Navigate the frame and wait for the load event.
    script = base::StringPrintf(
        "location.href = '/cross-site/%s/drag_and_drop/%s';\n"
        "setTimeout(function() { domAutomationController.send(42); }, 0);",
        origin.c_str(), filename.c_str());
    content::TestFrameNavigationObserver observer(frame);
    if (!content::ExecuteScriptAndExtractInt(frame, script, &response))
      return false;
    if (response != 42)
      return false;
    observer.Wait();

    // |frame| might have been swapped-out during a cross-site navigation,
    // therefore we need to get the current RenderFrameHost to work against
    // going forward.
    frame = GetFrameByName(frame_name);
    DCHECK(frame);

    // Wait until hit testing data is ready.
    WaitForHitTestDataOrChildSurfaceReady(frame);

    return true;
  }

  content::RenderFrameHost* GetFrameByName(const std::string& name_to_find) {
    return content::FrameMatchingPredicate(
        web_contents(), base::Bind(&content::FrameMatchesName, name_to_find));
  }

  void AssertTestPageIsLoaded() {
    ASSERT_EQ(kTestPagePath, web_contents()->GetLastCommittedURL().path());
  }

  std::unique_ptr<DragAndDropSimulator> drag_simulator_;

  DISALLOW_COPY_AND_ASSIGN(DragAndDropBrowserTest);
};

#if defined(OS_CHROMEOS)
// Flaky: https://crbug.com/835774
#define MAYBE_DropTextFromOutside DISABLED_DropTextFromOutside
#else
#define MAYBE_DropTextFromOutside DropTextFromOutside
#endif
// Scenario: drag text from outside the browser and drop to the right frame.
// Test coverage: dragover, drop DOM events.
IN_PROC_BROWSER_TEST_P(DragAndDropBrowserTest, MAYBE_DropTextFromOutside) {
  std::string frame_site = use_cross_site_subframe() ? "b.com" : "a.com";
  ASSERT_TRUE(NavigateToTestPage("a.com"));
  ASSERT_TRUE(NavigateRightFrame(frame_site, "drop_target.html"));

  // Setup test expectations.
  DOMDragEventVerifier expected_dom_event_data;
  expected_dom_event_data.set_expected_client_position("(155, 150)");
  expected_dom_event_data.set_expected_drop_effect("none");
  expected_dom_event_data.set_expected_effect_allowed("all");
  expected_dom_event_data.set_expected_mime_types("text/plain");
  expected_dom_event_data.set_expected_page_position("(155, 150)");

  // Drag text from outside the browser into/over the right frame.
  {
    DOMDragEventWaiter dragover_waiter("dragover", right_frame());
    ASSERT_TRUE(SimulateDragEnterToRightFrame("Dragged test text"));

    std::string dragover_event;
    ASSERT_TRUE(dragover_waiter.WaitForNextMatchingEvent(&dragover_event));
    EXPECT_THAT(dragover_event, expected_dom_event_data.Matches());
  }

  // Drop into the right frame.
  {
    DOMDragEventWaiter drop_waiter("drop", right_frame());
    ASSERT_TRUE(SimulateDropInRightFrame());

    std::string drop_event;
    ASSERT_TRUE(drop_waiter.WaitForNextMatchingEvent(&drop_event));
    EXPECT_THAT(drop_event, expected_dom_event_data.Matches());
  }
}

#if defined(OS_CHROMEOS) || !defined(NDEBUG)
// Flaky: https://crbug.com/835774
#define MAYBE_DragStartInFrame DISABLED_DragStartInFrame
#else
#define MAYBE_DragStartInFrame DragStartInFrame
#endif
// Scenario: starting a drag in left frame
// Test coverage: dragstart DOM event, dragstart data passed to the OS.
IN_PROC_BROWSER_TEST_P(DragAndDropBrowserTest, MAYBE_DragStartInFrame) {
  std::string frame_site = use_cross_site_subframe() ? "b.com" : "a.com";
  ASSERT_TRUE(NavigateToTestPage("a.com"));
  ASSERT_TRUE(NavigateLeftFrame(frame_site, "image_source.html"));

  // Setup test expectations.
  DOMDragEventVerifier expected_dom_event_data;
  expected_dom_event_data.set_expected_client_position("(55, 50)");
  expected_dom_event_data.set_expected_drop_effect("none");
  // (dragstart event handler in image_source.html is asking for "copy" only).
  expected_dom_event_data.set_expected_effect_allowed("copy");
  expected_dom_event_data.set_expected_page_position("(55, 50)");

  // TODO(lukasza): Figure out why the dragstart event
  // - lists "Files" on the mime types list,
  // - doesn't list "text/plain" on the mime types list.
  // (i.e. why expectations below differ from expectations for dragenter,
  // dragover, dragend and/or drop events in DragImageBetweenFrames test).
  expected_dom_event_data.set_expected_mime_types(
      "Files,text/html,text/uri-list");

  // Start the drag in the left frame.
  DragStartWaiter drag_start_waiter(web_contents());
  drag_start_waiter.SuppressPassingStartDragFurther();
  DOMDragEventWaiter dragstart_event_waiter("dragstart", left_frame());
  EXPECT_TRUE(SimulateMouseDownAndDragStartInLeftFrame());

  // Verify Javascript event data.
  {
    std::string dragstart_event;
    EXPECT_TRUE(
        dragstart_event_waiter.WaitForNextMatchingEvent(&dragstart_event));
    EXPECT_THAT(dragstart_event, expected_dom_event_data.Matches());
  }

  // Verify data being passed to the OS.
  {
    std::string text;
    std::string html;
    int operation = 0;
    gfx::Point location_inside_web_contents;
    drag_start_waiter.WaitUntilDragStart(&text, &html, &operation,
                                         &location_inside_web_contents);
    EXPECT_EQ(embedded_test_server()->GetURL(frame_site,
                                             "/image_decoding/droids.jpg"),
              text);
    EXPECT_THAT(html,
                testing::MatchesRegex("<img .*src=\""
                                      "http://.*/image_decoding/droids.jpg"
                                      "\">"));
    EXPECT_EQ(expected_location_of_drag_start_in_left_frame(),
              location_inside_web_contents);
    EXPECT_EQ(ui::DragDropTypes::DRAG_COPY, operation);
  }

  // Try to leave everything in a clean state.
  SimulateMouseUp();
}

#if defined(OS_WIN)
// There is no known way to execute test-controlled tasks during
// a drag-and-drop loop run by Windows OS.
#define MAYBE_DragImageBetweenFrames DISABLED_DragImageBetweenFrames
#elif defined(OS_CHROMEOS) || defined(OS_LINUX)
// Flakiness on CrOS tracked by https://crbug.com/835573.
#define MAYBE_DragImageBetweenFrames DISABLED_DragImageBetweenFrames
#else
#define MAYBE_DragImageBetweenFrames DragImageBetweenFrames
#endif

// Data that needs to be shared across multiple test steps below
// (i.e. across DragImageBetweenFrames_Step2 and DragImageBetweenFrames_Step3).
struct DragAndDropBrowserTest::DragImageBetweenFrames_TestState {
  DOMDragEventVerifier expected_dom_event_data;
  std::unique_ptr<DOMDragEventWaiter> dragstart_event_waiter;
  std::unique_ptr<DOMDragEventWaiter> drop_event_waiter;
  std::unique_ptr<DOMDragEventWaiter> dragend_event_waiter;
  std::unique_ptr<DOMDragEventCounter> left_frame_events_counter;
  std::unique_ptr<DOMDragEventCounter> right_frame_events_counter;
};

// Scenario: drag an image from the left into the right frame.
// Test coverage: dragleave, dragenter, dragover, dragend, drop DOM events.
IN_PROC_BROWSER_TEST_P(DragAndDropBrowserTest, MAYBE_DragImageBetweenFrames) {
  // Note that drag and drop will not expose data across cross-site frames on
  // the same page - this is why the same |frame_site| is used below both for
  // the left and the right frame.  See also https://crbug.com/59081.
  std::string frame_site = use_cross_site_subframe() ? "b.com" : "a.com";
  ASSERT_TRUE(NavigateToTestPage("a.com"));
  ASSERT_TRUE(NavigateLeftFrame(frame_site, "image_source.html"));
  ASSERT_TRUE(NavigateRightFrame(frame_site, "drop_target.html"));

  // Setup test expectations.
  DragAndDropBrowserTest::DragImageBetweenFrames_TestState state;
  state.left_frame_events_counter.reset(new DOMDragEventCounter(left_frame()));
  state.right_frame_events_counter.reset(
      new DOMDragEventCounter(right_frame()));
  state.expected_dom_event_data.set_expected_client_position("(55, 50)");
  state.expected_dom_event_data.set_expected_drop_effect("none");
  // (dragstart event handler in image_source.html is asking for "copy" only).
  state.expected_dom_event_data.set_expected_effect_allowed("copy");
  state.expected_dom_event_data.set_expected_mime_types(
      "text/html,text/plain,text/uri-list");
  state.expected_dom_event_data.set_expected_page_position("(55, 50)");

  // Start the drag in the left frame.
  DragStartWaiter drag_start_waiter(web_contents());
  drag_start_waiter.PostTaskWhenDragStarts(
      base::Bind(&DragAndDropBrowserTest::DragImageBetweenFrames_Step2,
                 base::Unretained(this), base::Unretained(&state)));
  state.dragstart_event_waiter.reset(
      new DOMDragEventWaiter("dragstart", left_frame()));
  EXPECT_TRUE(SimulateMouseDownAndDragStartInLeftFrame());

  // The next step of the test (DragImageBetweenFrames_Step2) runs inside the
  // nested drag-and-drop message loop - the call below won't return until the
  // drag-and-drop has already ended.
  drag_start_waiter.WaitUntilDragStart(nullptr, nullptr, nullptr, nullptr);

  DragImageBetweenFrames_Step3(&state);
}

void DragAndDropBrowserTest::DragImageBetweenFrames_Step2(
    DragAndDropBrowserTest::DragImageBetweenFrames_TestState* state) {
  // Verify dragstart DOM event.
  {
    std::string dragstart_event;
    EXPECT_TRUE(state->dragstart_event_waiter->WaitForNextMatchingEvent(
        &dragstart_event));
    state->dragstart_event_waiter.reset();

    // Only a single "dragstart" should have fired in the left frame since the
    // start of the test.  We also allow any number of "dragover" events.
    EXPECT_EQ(1, state->left_frame_events_counter->GetNumberOfReceivedEvents(
                     "dragstart"));
    EXPECT_EQ(0, state->left_frame_events_counter->GetNumberOfReceivedEvents(
                     {"dragleave", "dragenter", "drop", "dragend"}));

    // No events should have fired in the right frame yet.
    EXPECT_EQ(0, state->right_frame_events_counter->GetNumberOfReceivedEvents(
                     {"dragstart", "dragleave", "dragenter", "dragover", "drop",
                      "dragend"}));
  }

  // While dragging, move mouse within the left frame.
  // Without this extra mouse move we wouldn't get a dragleave event later on.
  ASSERT_TRUE(SimulateMouseMoveToLeftFrame());

  // While dragging, move mouse from the left into the right frame.
  // This should trigger dragleave and dragenter events.
  {
    DOMDragEventWaiter dragleave_event_waiter("dragleave", left_frame());
    DOMDragEventWaiter dragenter_event_waiter("dragenter", right_frame());
    state->left_frame_events_counter->Reset();
    state->right_frame_events_counter->Reset();
    ASSERT_TRUE(SimulateMouseMoveToRightFrame());

    {  // Verify dragleave DOM event.
      std::string dragleave_event;

      state->expected_dom_event_data.set_expected_client_position("(355, 150)");
      state->expected_dom_event_data.set_expected_page_position("(355, 150)");

      EXPECT_TRUE(
          dragleave_event_waiter.WaitForNextMatchingEvent(&dragleave_event));
      EXPECT_THAT(dragleave_event, state->expected_dom_event_data.Matches());
    }

    {  // Verify dragenter DOM event.
      std::string dragenter_event;

      // Update expected event coordinates after SimulateMouseMoveToRightFrame
      // (these coordinates are relative to the right frame).
      state->expected_dom_event_data.set_expected_client_position("(155, 150)");
      state->expected_dom_event_data.set_expected_page_position("(155, 150)");

      EXPECT_TRUE(
          dragenter_event_waiter.WaitForNextMatchingEvent(&dragenter_event));
      EXPECT_THAT(dragenter_event, state->expected_dom_event_data.Matches());
    }

    // Note that ash (unlike aura/x11) will not fire dragover event in response
    // to the same mouse event that trigerred a dragenter.  Because of that, we
    // postpone dragover testing until the next test step below.  See
    // implementation of ash::DragDropController::DragUpdate for details.
  }

  // Move the mouse twice in the right frame.  The 1st move will ensure that
  // allowed operations communicated by the renderer will be stored in
  // WebContentsViewAura::current_drag_op_.  The 2nd move will ensure that this
  // gets be copied into DesktopDragDropClientAuraX11::negotiated_operation_.
  for (int i = 0; i < 2; i++) {
    DOMDragEventWaiter dragover_event_waiter("dragover", right_frame());
    ASSERT_TRUE(SimulateMouseMoveToRightFrame());

    {  // Verify dragover DOM event.
      std::string dragover_event;
      EXPECT_TRUE(
          dragover_event_waiter.WaitForNextMatchingEvent(&dragover_event));
      EXPECT_THAT(dragover_event, state->expected_dom_event_data.Matches());
    }
  }

  // Only a single "dragleave" should have fired in the left frame since the
  // last checkpoint.  We also allow any number of "dragover" events.
  EXPECT_EQ(1, state->left_frame_events_counter->GetNumberOfReceivedEvents(
                   "dragleave"));
  EXPECT_EQ(0, state->left_frame_events_counter->GetNumberOfReceivedEvents(
                   {"dragstart", "dragenter", "drop", "dragend"}));

  // A single "dragenter" + at least one "dragover" event should have fired in
  // the right frame since the last checkpoint.
  EXPECT_EQ(1, state->right_frame_events_counter->GetNumberOfReceivedEvents(
                   "dragenter"));
  EXPECT_LE(1, state->right_frame_events_counter->GetNumberOfReceivedEvents(
                   "dragover"));
  EXPECT_EQ(0, state->right_frame_events_counter->GetNumberOfReceivedEvents(
                   {"dragstart", "dragleave", "drop", "dragend"}));

  // Release the mouse button to end the drag.
  state->drop_event_waiter.reset(new DOMDragEventWaiter("drop", right_frame()));
  state->dragend_event_waiter.reset(
      new DOMDragEventWaiter("dragend", left_frame()));
  state->left_frame_events_counter->Reset();
  state->right_frame_events_counter->Reset();
  SimulateMouseUp();
  // The test will continue in DragImageBetweenFrames_Step3.
}

void DragAndDropBrowserTest::DragImageBetweenFrames_Step3(
    DragAndDropBrowserTest::DragImageBetweenFrames_TestState* state) {
  // Verify drop DOM event.
  {
    std::string drop_event;
    EXPECT_TRUE(
        state->drop_event_waiter->WaitForNextMatchingEvent(&drop_event));
    state->drop_event_waiter.reset();
    EXPECT_THAT(drop_event, state->expected_dom_event_data.Matches());
  }

  // Verify dragend DOM event.
  {
    // TODO(lukasza): Figure out why the drop event sees different values of
    // DataTransfer.dropEffect and DataTransfer.types properties.
    state->expected_dom_event_data.set_expected_drop_effect("copy");
    state->expected_dom_event_data.set_expected_mime_types("");

    // TODO: https://crbug.com/686136: dragEnd coordinates for non-OOPIF
    // scenarios are currently broken.
    state->expected_dom_event_data.set_expected_client_position(
        "<no expectation>");
    state->expected_dom_event_data.set_expected_page_position(
        "<no expectation>");

    std::string dragend_event;
    EXPECT_TRUE(
        state->dragend_event_waiter->WaitForNextMatchingEvent(&dragend_event));
    state->dragend_event_waiter.reset();
    EXPECT_THAT(dragend_event, state->expected_dom_event_data.Matches());
  }

  // Only a single "dragend" should have fired in the left frame since the last
  // checkpoint.
  EXPECT_EQ(1, state->left_frame_events_counter->GetNumberOfReceivedEvents(
                   "dragend"));
  EXPECT_EQ(0,
            state->left_frame_events_counter->GetNumberOfReceivedEvents(
                {"dragstart", "dragleave", "dragenter", "dragover", "drop"}));

  // A single "drop" + possibly some "dragover" events should have fired in the
  // right frame since the last checkpoint.
  EXPECT_EQ(
      1, state->right_frame_events_counter->GetNumberOfReceivedEvents("drop"));
  EXPECT_EQ(0, state->right_frame_events_counter->GetNumberOfReceivedEvents(
                   {"dragstart", "dragleave", "dragenter", "dragend"}));
}

#if defined(OS_WIN)
// There is no known way to execute test-controlled tasks during
// a drag-and-drop loop run by Windows OS.
#define MAYBE_DragImageFromDisappearingFrame \
  DISABLED_DragImageFromDisappearingFrame
#elif defined(OS_CHROMEOS)
// Flakiness on CrOS tracked by https://crbug.com/835572.
#define MAYBE_DragImageFromDisappearingFrame \
  DISABLED_DragImageFromDisappearingFrame
#else
#define MAYBE_DragImageFromDisappearingFrame DragImageFromDisappearingFrame
#endif

// Data that needs to be shared across multiple test steps below
// (i.e. across DragImageFromDisappearingFrame_Step2 and
// DragImageFromDisappearingFrame_Step3).
struct DragAndDropBrowserTest::DragImageFromDisappearingFrame_TestState {
  DOMDragEventVerifier expected_dom_event_data;
  std::unique_ptr<DOMDragEventWaiter> drop_event_waiter;
};

// Scenario: drag an image from the left into the right frame and delete the
// left frame during the drag.  This is a regression test for
// https://crbug.com/670123.
// Test coverage: dragenter, dragover, drop DOM events.
IN_PROC_BROWSER_TEST_P(DragAndDropBrowserTest,
                       MAYBE_DragImageFromDisappearingFrame) {
  // Load the test page.
  std::string frame_site = use_cross_site_subframe() ? "b.com" : "a.com";
  ASSERT_TRUE(NavigateToTestPage("a.com"));
  ASSERT_TRUE(NavigateLeftFrame(frame_site, "image_source.html"));
  ASSERT_TRUE(NavigateRightFrame(frame_site, "drop_target.html"));

  // Setup test expectations.
  DragAndDropBrowserTest::DragImageFromDisappearingFrame_TestState state;
  state.expected_dom_event_data.set_expected_drop_effect("none");
  // (dragstart event handler in image_source.html is asking for "copy" only).
  state.expected_dom_event_data.set_expected_effect_allowed("copy");
  state.expected_dom_event_data.set_expected_mime_types(
      "text/html,text/plain,text/uri-list");
  state.expected_dom_event_data.set_expected_client_position("(155, 150)");
  state.expected_dom_event_data.set_expected_page_position("(155, 150)");

  // Start the drag in the left frame.
  DragStartWaiter drag_start_waiter(web_contents());
  drag_start_waiter.PostTaskWhenDragStarts(
      base::Bind(&DragAndDropBrowserTest::DragImageFromDisappearingFrame_Step2,
                 base::Unretained(this), base::Unretained(&state)));
  EXPECT_TRUE(SimulateMouseDownAndDragStartInLeftFrame());

  // The next step of the test (DragImageFromDisappearingFrame_Step2) runs
  // inside the nested drag-and-drop message loop - the call below won't return
  // until the drag-and-drop has already ended.
  drag_start_waiter.WaitUntilDragStart(nullptr, nullptr, nullptr, nullptr);

  DragImageFromDisappearingFrame_Step3(&state);
}

void DragAndDropBrowserTest::DragImageFromDisappearingFrame_Step2(
    DragAndDropBrowserTest::DragImageFromDisappearingFrame_TestState* state) {
  // Delete the left frame in an attempt to repro https://crbug.com/670123.
  content::RenderFrameDeletedObserver frame_deleted_observer(left_frame());
  ASSERT_TRUE(ExecuteScript(web_contents()->GetMainFrame(),
                            "frame = document.getElementById('left');\n"
                            "frame.parentNode.removeChild(frame);\n"));
  frame_deleted_observer.WaitUntilDeleted();

  // While dragging, move mouse from the left into the right frame.
  // This should trigger dragleave and dragenter events.
  {
    DOMDragEventWaiter dragenter_event_waiter("dragenter", right_frame());
    ASSERT_TRUE(SimulateMouseMoveToRightFrame());

    {  // Verify dragenter DOM event.
      std::string dragenter_event;
      EXPECT_TRUE(
          dragenter_event_waiter.WaitForNextMatchingEvent(&dragenter_event));
      EXPECT_THAT(dragenter_event, state->expected_dom_event_data.Matches());
    }

    // Note that ash (unlike aura/x11) will not fire dragover event in response
    // to the same mouse event that trigerred a dragenter.  Because of that, we
    // postpone dragover testing until the next test step below.  See
    // implementation of ash::DragDropController::DragUpdate for details.
  }

  // Move the mouse twice in the right frame.  The 1st move will ensure that
  // allowed operations communicated by the renderer will be stored in
  // WebContentsViewAura::current_drag_op_.  The 2nd move will ensure that this
  // gets be copied into DesktopDragDropClientAuraX11::negotiated_operation_.
  for (int i = 0; i < 2; i++) {
    DOMDragEventWaiter dragover_event_waiter("dragover", right_frame());
    ASSERT_TRUE(SimulateMouseMoveToRightFrame());

    {  // Verify dragover DOM event.
      std::string dragover_event;
      EXPECT_TRUE(
          dragover_event_waiter.WaitForNextMatchingEvent(&dragover_event));
      EXPECT_THAT(dragover_event, state->expected_dom_event_data.Matches());
    }
  }

  // Release the mouse button to end the drag.
  state->drop_event_waiter.reset(new DOMDragEventWaiter("drop", right_frame()));
  SimulateMouseUp();
  // The test will continue in DragImageFromDisappearingFrame_Step3.
}

void DragAndDropBrowserTest::DragImageFromDisappearingFrame_Step3(
    DragAndDropBrowserTest::DragImageFromDisappearingFrame_TestState* state) {
  // Verify drop DOM event.
  {
    std::string drop_event;
    EXPECT_TRUE(
        state->drop_event_waiter->WaitForNextMatchingEvent(&drop_event));
    state->drop_event_waiter.reset();
    EXPECT_THAT(drop_event, state->expected_dom_event_data.Matches());
  }
}

// There is no known way to execute test-controlled tasks during
// a drag-and-drop loop run by Windows OS.
#if defined(OS_WIN)
#define MAYBE_CrossSiteDrag DISABLED_CrossSiteDrag
#elif defined(OS_CHROMEOS)
// Flaky: https://crbug.com/835774
#define MAYBE_CrossSiteDrag DISABLED_CrossSiteDrag
#else
#define MAYBE_CrossSiteDrag CrossSiteDrag
#endif

// Data that needs to be shared across multiple test steps below
// (i.e. across CrossSiteDrag_Step2 and CrossSiteDrag_Step3).
struct DragAndDropBrowserTest::CrossSiteDrag_TestState {
  std::unique_ptr<DOMDragEventWaiter> dragend_event_waiter;
  std::unique_ptr<DOMDragEventCounter> left_frame_events_counter;
  std::unique_ptr<DOMDragEventCounter> right_frame_events_counter;
};

// Scenario: drag an image from the left into the right frame when the
// left-vs-right frames are cross-site.  This is a regression test for
// https://crbug.com/59081.
//
// Test coverage: absence of dragenter, dragover, drop DOM events
// + presence of dragstart, dragleave and dragend.
IN_PROC_BROWSER_TEST_P(DragAndDropBrowserTest, MAYBE_CrossSiteDrag) {
  std::string left_frame_site = "c.com";  // Always cross-site VS main frame.
  std::string right_frame_site = use_cross_site_subframe() ? "b.com" : "a.com";
  ASSERT_TRUE(NavigateToTestPage("a.com"));
  ASSERT_TRUE(NavigateLeftFrame(left_frame_site, "image_source.html"));
  ASSERT_TRUE(NavigateRightFrame(right_frame_site, "drop_target.html"));

  // Setup test expectations.
  DragAndDropBrowserTest::CrossSiteDrag_TestState state;
  state.left_frame_events_counter.reset(new DOMDragEventCounter(left_frame()));
  state.right_frame_events_counter.reset(
      new DOMDragEventCounter(right_frame()));

  // Start the drag in the left frame.
  DragStartWaiter drag_start_waiter(web_contents());
  drag_start_waiter.PostTaskWhenDragStarts(
      base::Bind(&DragAndDropBrowserTest::CrossSiteDrag_Step2,
                 base::Unretained(this), base::Unretained(&state)));
  EXPECT_TRUE(SimulateMouseDownAndDragStartInLeftFrame());

  // The next step of the test (CrossSiteDrag_Step2) runs inside the
  // nested drag-and-drop message loop - the call below won't return until the
  // drag-and-drop has already ended.
  drag_start_waiter.WaitUntilDragStart(nullptr, nullptr, nullptr, nullptr);

  CrossSiteDrag_Step3(&state);
}

void DragAndDropBrowserTest::CrossSiteDrag_Step2(
    DragAndDropBrowserTest::CrossSiteDrag_TestState* state) {
  // While "dragleave" and "drop" events are not expected in this test, we
  // simulate extra mouse operations for consistency with
  // DragImageBetweenFrames_Step2.
  ASSERT_TRUE(SimulateMouseMoveToLeftFrame());
  for (int i = 0; i < 3; i++) {
    content::DOMMessageQueue dom_message_queue(web_contents());
    ASSERT_TRUE(SimulateMouseMoveToRightFrame());

    // No events are expected from the right frame, so we can't wait for a
    // dragover event here.  Still - we do want to wait until the right frame
    // has had a chance to process any previous browser IPCs, so that in case
    // there *is* a bug and a dragover event *does* happen, we won't terminate
    // the test before the event has had a chance to be reported back to the
    // browser.
    std::string expected_response = base::StringPrintf("\"i%d\"", i);
    right_frame()->ExecuteJavaScriptWithUserGestureForTests(
        base::UTF8ToUTF16(base::StringPrintf(
            "domAutomationController.send(%s);", expected_response.c_str())));

    // Wait until our response comes back (it might be mixed with responses
    // carrying events that are sent by event_monitoring.js).
    std::string actual_response;
    do {
      ASSERT_TRUE(dom_message_queue.WaitForMessage(&actual_response));
    } while (actual_response != expected_response);
  }

  // Release the mouse button to end the drag.
  state->dragend_event_waiter.reset(
      new DOMDragEventWaiter("dragend", left_frame()));
  SimulateMouseUp();
  // The test will continue in DragImageBetweenFrames_Step3.
}

void DragAndDropBrowserTest::CrossSiteDrag_Step3(
    DragAndDropBrowserTest::CrossSiteDrag_TestState* state) {
  EXPECT_TRUE(state->dragend_event_waiter->WaitForNextMatchingEvent(nullptr));

  // Since the start of the test the left frame should have seen a single
  // "dragstart",
  // and a "dragend" event (and possibly a "dragleave" and some "dragover"
  // events).
  EXPECT_EQ(1, state->left_frame_events_counter->GetNumberOfReceivedEvents(
                   "dragstart"));
  EXPECT_EQ(1, state->left_frame_events_counter->GetNumberOfReceivedEvents(
                   "dragend"));
  EXPECT_EQ(
      0, state->left_frame_events_counter->GetNumberOfReceivedEvents("drop"));

  // No events should have fired in the right frame, because it is cross-site
  // from the source of the drag.  This is the essence of this test.
  EXPECT_EQ(0, state->right_frame_events_counter->GetNumberOfReceivedEvents(
                   {"dragstart", "dragleave", "dragenter", "dragover", "drop",
                    "dragend"}));
}

// TODO(paulmeyer): Should test the case of navigation happening in the middle
// of a drag operation, and cross-site drags should be allowed across a
// navigation.

INSTANTIATE_TEST_SUITE_P(SameSiteSubframe,
                         DragAndDropBrowserTest,
                         ::testing::Values(false));

INSTANTIATE_TEST_SUITE_P(CrossSiteSubframe,
                         DragAndDropBrowserTest,
                         ::testing::Values(true));

}  // namespace chrome
