Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(220)

Side by Side Diff: chrome/browser/ui/views/drag_and_drop_interactive_uitest.cc

Issue 2622733002: Mac Support for drag-and-drop tests that start dragging via mouse simulation.
Patch Set: . Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/views/drag_and_drop_interactive_uitest.h"
6
5 #include <algorithm> 7 #include <algorithm>
6 #include <initializer_list> 8 #include <initializer_list>
7 #include <memory> 9 #include <memory>
8 #include <string> 10 #include <string>
9 #include <vector> 11 #include <vector>
10 12
11 #include "base/callback.h" 13 #include "base/callback.h"
12 #include "base/macros.h" 14 #include "base/macros.h"
13 #include "base/memory/ref_counted.h" 15 #include "base/memory/ref_counted.h"
14 #include "base/sequenced_task_runner.h" 16 #include "base/sequenced_task_runner.h"
15 #include "base/strings/pattern.h" 17 #include "base/strings/pattern.h"
16 #include "base/strings/string_piece.h" 18 #include "base/strings/string_piece.h"
17 #include "base/strings/stringprintf.h" 19 #include "base/strings/stringprintf.h"
18 #include "base/strings/utf_string_conversions.h" 20 #include "base/strings/utf_string_conversions.h"
19 #include "base/threading/sequenced_task_runner_handle.h" 21 #include "base/threading/sequenced_task_runner_handle.h"
20 #include "chrome/browser/ui/browser.h" 22 #include "chrome/browser/ui/browser.h"
21 #include "chrome/browser/ui/tabs/tab_strip_model.h" 23 #include "chrome/browser/ui/tabs/tab_strip_model.h"
22 #include "chrome/test/base/in_process_browser_test.h" 24 #include "chrome/test/base/in_process_browser_test.h"
23 #include "chrome/test/base/interactive_test_utils.h" 25 #include "chrome/test/base/interactive_test_utils.h"
24 #include "chrome/test/base/ui_test_utils.h" 26 #include "chrome/test/base/ui_test_utils.h"
25 #include "content/public/browser/render_frame_host.h" 27 #include "content/public/browser/render_frame_host.h"
26 #include "content/public/browser/web_contents.h" 28 #include "content/public/browser/web_contents.h"
29 #include "content/public/common/drop_data.h"
27 #include "content/public/test/browser_test_utils.h" 30 #include "content/public/test/browser_test_utils.h"
28 #include "content/public/test/content_browser_test.h" 31 #include "content/public/test/content_browser_test.h"
29 #include "content/public/test/content_browser_test_utils.h" 32 #include "content/public/test/content_browser_test_utils.h"
30 #include "content/public/test/test_frame_navigation_observer.h" 33 #include "content/public/test/test_frame_navigation_observer.h"
31 #include "content/public/test/test_utils.h" 34 #include "content/public/test/test_utils.h"
32 #include "net/base/escape.h" 35 #include "net/base/escape.h"
33 #include "net/dns/mock_host_resolver.h" 36 #include "net/dns/mock_host_resolver.h"
34 #include "net/test/embedded_test_server/embedded_test_server.h" 37 #include "net/test/embedded_test_server/embedded_test_server.h"
35 #include "testing/gmock/include/gmock/gmock.h" 38 #include "testing/gmock/include/gmock/gmock.h"
36 #include "testing/gtest/include/gtest/gtest.h" 39 #include "testing/gtest/include/gtest/gtest.h"
37 #include "ui/aura/client/drag_drop_client.h"
38 #include "ui/aura/client/drag_drop_delegate.h"
39 #include "ui/aura/client/screen_position_client.h"
40 #include "ui/aura/window.h"
41 #include "ui/base/dragdrop/drag_drop_types.h"
42 #include "ui/base/dragdrop/drop_target_event.h"
43 #include "ui/base/dragdrop/os_exchange_data.h"
44 #include "ui/gfx/geometry/point.h" 40 #include "ui/gfx/geometry/point.h"
45 #include "ui/gfx/geometry/rect.h" 41 #include "ui/gfx/geometry/rect.h"
46 #include "url/gurl.h" 42 #include "url/gurl.h"
47 43
48 namespace chrome { 44 namespace chrome {
49 45
50 namespace { 46 namespace {
51 47
52 // TODO(lukasza): Support testing on non-Aura platforms (i.e. Android + Mac?). 48 // Helper for waiting until a drag-and-drop starts (e.g. in response to a
53 // 49 // mouse-down + mouse-move simulated by the test).
54 // Notes for the TODO above: 50 class DragStartWaiter {
55 //
56 // - Why inject/simulate drag-and-drop events at the aura::Window* level.
57 //
58 // - It seems better to inject into UI libraries to cover code *inside* these
59 // libraries. This might complicate simulation a little bit (i.e. picking
60 // the right aura::Window and/or aura::client::DragDropDelegate to target),
61 // but otherwise important bits of code wouldn't get test coverage (i.e.
62 // directly injecting into RenderViewHost->DragTargetDragEnter seems wrong).
63 //
64 // - In theory, we could introduce WebContentsImpl::DragTargetDragEnter (to be
65 // used by all UI platforms - so reused by web_contents_view_android.cc,
66 // web_contents_view_aura.cc, web_drag_dest_mac.mm), but it feels wrong - UI
67 // libraries should already know which widget is the target of the event and
68 // so should be able to talk directly to the right widget (i.e. WebContents
69 // should not be responsible for mapping coordinates to a widget - this is
70 // the job of the UI library).
71 //
72 // - Unknowns:
73 //
74 // - Will this work for WebView and Plugin testing.
75
76 // Test helper for simulating drag and drop happening in WebContents.
77 class DragAndDropSimulator {
78 public: 51 public:
79 explicit DragAndDropSimulator(content::WebContents* web_contents) 52 // Starts globally monitoring for a start of a drag-and-drop that originates
80 : web_contents_(web_contents) {} 53 // from web contents.
81 54 DragStartWaiter()
82 // Simulates notification that |text| was dragged from outside of the browser, 55 : message_loop_runner_(new content::MessageLoopRunner),
83 // into the specified |location| inside |web_contents|. 56 suppress_passing_of_start_drag_further_(false),
84 // |location| is relative to |web_contents|. 57 drag_started_(false) {
85 // Returns true upon success. 58 content::RegisterDragStartCallback(
86 bool SimulateDragEnter(gfx::Point location, const std::string& text) { 59 base::Bind(&DragStartWaiter::StartDragAndDrop, base::Unretained(this)));
87 ui::OSExchangeData data;
88 data.SetString(base::UTF8ToUTF16(text));
89 return SimulateDragEnter(location, data);
90 } 60 }
91 61
92 // Simulates dropping of the drag-and-dropped item. 62 ~DragStartWaiter() {
93 // SimulateDragEnter needs to be called first. 63 // Unregister our callback.
94 // Returns true upon success. 64 content::RegisterDragStartCallback(content::DragStartCallback());
95 bool SimulateDrop(gfx::Point location) {
96 if (!active_drag_event_) {
97 ADD_FAILURE() << "Cannot drop a drag that hasn't started yet.";
98 return false;
99 }
100
101 aura::client::DragDropDelegate* delegate = GetDragDropDelegate();
102 if (!delegate)
103 return false;
104
105 gfx::Point event_location;
106 gfx::Point event_root_location;
107 CalculateEventLocations(location, &event_location, &event_root_location);
108 active_drag_event_->set_location(event_location);
109 active_drag_event_->set_root_location(event_root_location);
110
111 delegate->OnDragUpdated(*active_drag_event_);
112 delegate->OnPerformDrop(*active_drag_event_);
113 return true;
114 }
115
116 private:
117 bool SimulateDragEnter(gfx::Point location, const ui::OSExchangeData& data) {
118 if (active_drag_event_) {
119 ADD_FAILURE() << "Cannot start a new drag when old one hasn't ended yet.";
120 return false;
121 }
122
123 aura::client::DragDropDelegate* delegate = GetDragDropDelegate();
124 if (!delegate)
125 return false;
126
127 gfx::Point event_location;
128 gfx::Point event_root_location;
129 CalculateEventLocations(location, &event_location, &event_root_location);
130 active_drag_event_.reset(new ui::DropTargetEvent(
131 data, event_location, event_root_location, kDefaultSourceOperations));
132
133 delegate->OnDragEntered(*active_drag_event_);
134 delegate->OnDragUpdated(*active_drag_event_);
135 return true;
136 }
137
138 aura::client::DragDropDelegate* GetDragDropDelegate() {
139 gfx::NativeView view = web_contents_->GetContentNativeView();
140 aura::client::DragDropDelegate* delegate =
141 aura::client::GetDragDropDelegate(view);
142 EXPECT_TRUE(delegate) << "Expecting WebContents to have DragDropDelegate";
143 return delegate;
144 }
145
146 void CalculateEventLocations(gfx::Point web_contents_relative_location,
147 gfx::Point* out_event_location,
148 gfx::Point* out_event_root_location) {
149 gfx::NativeView view = web_contents_->GetNativeView();
150
151 *out_event_location = web_contents_relative_location;
152
153 gfx::Point root_location = web_contents_relative_location;
154 aura::Window::ConvertPointToTarget(view, view->GetRootWindow(),
155 &root_location);
156 *out_event_root_location = root_location;
157 }
158
159 // These are ui::DropTargetEvent::source_operations_ being sent when manually
160 // trying out drag&drop of an image file from Nemo (Ubuntu's file explorer)
161 // into a content_shell.
162 static constexpr int kDefaultSourceOperations = ui::DragDropTypes::DRAG_MOVE |
163 ui::DragDropTypes::DRAG_COPY |
164 ui::DragDropTypes::DRAG_LINK;
165
166 content::WebContents* web_contents_;
167 std::unique_ptr<ui::DropTargetEvent> active_drag_event_;
168
169 DISALLOW_COPY_AND_ASSIGN(DragAndDropSimulator);
170 };
171
172 // Helper for waiting until a drag-and-drop starts (e.g. in response to a
173 // mouse-down + mouse-move simulated by the test).
174 class DragStartWaiter : public aura::client::DragDropClient {
175 public:
176 // Starts monitoring |web_contents| for a start of a drag-and-drop.
177 explicit DragStartWaiter(content::WebContents* web_contents)
178 : web_contents_(web_contents),
179 message_loop_runner_(new content::MessageLoopRunner),
180 suppress_passing_of_start_drag_further_(false),
181 drag_started_(false) {
182 DCHECK(web_contents_);
183
184 // Intercept calls to the old DragDropClient.
185 gfx::NativeWindow root_window =
186 web_contents_->GetContentNativeView()->GetRootWindow();
187 old_client_ = aura::client::GetDragDropClient(root_window);
188 aura::client::SetDragDropClient(root_window, this);
189 }
190
191 ~DragStartWaiter() override {
192 // Restore the original DragDropClient.
193 gfx::NativeWindow root_window =
194 web_contents_->GetContentNativeView()->GetRootWindow();
195 aura::client::SetDragDropClient(root_window, old_client_);
196 } 65 }
197 66
198 // Waits until we almost report a drag-and-drop start to the OS. 67 // Waits until we almost report a drag-and-drop start to the OS.
199 // At that point 68 // At that point
200 // 1) the callback from PostTaskWhenDragStarts will be posted. 69 // 1) the callback from PostTaskWhenDragStarts will be posted.
201 // 2) the drag-start request will be forwarded to the OS 70 // 2) the drag-start request will be forwarded to the OS
202 // (unless SuppressPassingStartDragFurther method was called). 71 // (unless SuppressPassingStartDragFurther method was called).
203 // 72 //
204 // Note that if SuppressPassingStartDragFurther was not called then 73 // Note that if SuppressPassingStartDragFurther was not called then
205 // WaitUntilDragStart can take a long time to return (it returns only after 74 // WaitUntilDragStart can take a long time to return (it returns only after
206 // the OS decides that the drag-and-drop has ended). 75 // the OS decides that the drag-and-drop has ended).
207 // 76 //
208 // Before returning populates |text|, |html| and other parameters with data 77 // Before returning populates |text|, |html| and other parameters with data
209 // that would have been passed to the OS). If the caller is not interested in 78 // that would have been passed to the OS). If the caller is not interested in
210 // this data, then the corresponding argument can be null. 79 // this data, then the corresponding argument can be null.
211 void WaitUntilDragStart(std::string* text, 80 void WaitUntilDragStart(content::DropData* drop_data,
212 std::string* html, 81 blink::WebDragOperationsMask* drag_operations_mask) {
213 int* operation,
214 gfx::Point* location_inside_web_contents) {
215 message_loop_runner_->Run(); 82 message_loop_runner_->Run();
216 83
217 // message_loop_runner_->Quit is only called from StartDragAndDrop. 84 // message_loop_runner_->Quit is only called from StartDragAndDrop.
218 DCHECK(drag_started_); 85 DCHECK(drag_started_);
219 86
220 if (text) 87 if (drop_data)
221 *text = text_; 88 *drop_data = drop_data_;
222 if (html) 89 if (drag_operations_mask)
223 *html = html_; 90 *drag_operations_mask = drag_operations_mask_;
224 if (operation)
225 *operation = operation_;
226 if (location_inside_web_contents)
227 *location_inside_web_contents = location_inside_web_contents_;
228 } 91 }
229 92
230 void SuppressPassingStartDragFurther() { 93 void SuppressPassingStartDragFurther() {
231 suppress_passing_of_start_drag_further_ = true; 94 suppress_passing_of_start_drag_further_ = true;
232 } 95 }
233 96
234 void PostTaskWhenDragStarts(const base::Closure& callback) { 97 void PostTaskWhenDragStarts(const base::Closure& callback) {
235 callback_to_run_inside_drag_and_drop_message_loop_ = callback; 98 callback_to_run_inside_drag_and_drop_message_loop_ = callback;
236 } 99 }
237 100
238 // aura::client::DragDropClient overrides: 101 // Implementation of DragStartCallback passed to RegisterDragStartCallback.
239 int StartDragAndDrop(const ui::OSExchangeData& data, 102 bool StartDragAndDrop(const content::DropData& drop_data,
240 aura::Window* root_window, 103 blink::WebDragOperationsMask drag_operations_mask) {
241 aura::Window* source_window,
242 const gfx::Point& screen_location,
243 int operation,
244 ui::DragDropTypes::DragEventSource source) override {
245 DCHECK(!drag_started_); 104 DCHECK(!drag_started_);
246 if (!drag_started_) { 105 if (!drag_started_) {
247 drag_started_ = true; 106 drag_started_ = true;
107 drop_data_ = drop_data;
108 drag_operations_mask_ = drag_operations_mask;
248 message_loop_runner_->Quit(); 109 message_loop_runner_->Quit();
249
250 base::string16 text;
251 if (data.GetString(&text))
252 text_ = base::UTF16ToUTF8(text);
253 else
254 text_ = "<no text>";
255
256 GURL base_url;
257 base::string16 html;
258 if (data.GetHtml(&html, &base_url))
259 html_ = base::UTF16ToUTF8(html);
260 else
261 html_ = "<no html>";
262
263 gfx::Rect bounds =
264 web_contents_->GetContentNativeView()->GetBoundsInScreen();
265 location_inside_web_contents_ =
266 screen_location - gfx::Vector2d(bounds.x(), bounds.y());
267
268 operation_ = operation;
269 } 110 }
270 111
271 if (!callback_to_run_inside_drag_and_drop_message_loop_.is_null()) { 112 if (!callback_to_run_inside_drag_and_drop_message_loop_.is_null()) {
272 base::SequencedTaskRunnerHandle::Get()->PostTask( 113 base::SequencedTaskRunnerHandle::Get()->PostTask(
273 FROM_HERE, 114 FROM_HERE,
274 std::move(callback_to_run_inside_drag_and_drop_message_loop_)); 115 std::move(callback_to_run_inside_drag_and_drop_message_loop_));
275 callback_to_run_inside_drag_and_drop_message_loop_.Reset(); 116 callback_to_run_inside_drag_and_drop_message_loop_.Reset();
276 } 117 }
277 118
278 if (suppress_passing_of_start_drag_further_) 119 return suppress_passing_of_start_drag_further_;
279 return 0;
280
281 // Start a nested drag-and-drop loop (might not return for a long time).
282 return old_client_->StartDragAndDrop(data, root_window, source_window,
283 screen_location, operation, source);
284 } 120 }
285 121
286 void DragCancel() override {
287 ADD_FAILURE() << "Unexpected call to DragCancel";
288 }
289
290 bool IsDragDropInProgress() override { return drag_started_; }
291
292 private: 122 private:
293 content::WebContents* web_contents_;
294 scoped_refptr<content::MessageLoopRunner> message_loop_runner_; 123 scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
295 aura::client::DragDropClient* old_client_;
296 base::Closure callback_to_run_inside_drag_and_drop_message_loop_; 124 base::Closure callback_to_run_inside_drag_and_drop_message_loop_;
297 bool suppress_passing_of_start_drag_further_; 125 bool suppress_passing_of_start_drag_further_;
298 126
299 // Data captured during the first intercepted StartDragAndDrop call. 127 // Data captured during the first intercepted StartDragAndDrop call.
300 bool drag_started_; 128 bool drag_started_;
301 std::string text_; 129 content::DropData drop_data_;
302 std::string html_; 130 blink::WebDragOperationsMask drag_operations_mask_;
303 int operation_;
304 gfx::Point location_inside_web_contents_;
305 131
306 DISALLOW_COPY_AND_ASSIGN(DragStartWaiter); 132 DISALLOW_COPY_AND_ASSIGN(DragStartWaiter);
307 }; 133 };
308 134
309 // Helper for waiting for notifications from 135 // Helper for waiting for notifications from
310 // content/test/data/drag_and_drop/event_monitoring.js 136 // content/test/data/drag_and_drop/event_monitoring.js
311 class DOMDragEventWaiter { 137 class DOMDragEventWaiter {
312 public: 138 public:
313 DOMDragEventWaiter(const std::string& event_type_to_wait_for, 139 DOMDragEventWaiter(const std::string& event_type_to_wait_for,
314 const content::ToRenderFrameHost& target) 140 const content::ToRenderFrameHost& target)
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
519 345
520 struct CrossSiteDrag_TestState; 346 struct CrossSiteDrag_TestState;
521 void CrossSiteDrag_Step2(CrossSiteDrag_TestState*); 347 void CrossSiteDrag_Step2(CrossSiteDrag_TestState*);
522 void CrossSiteDrag_Step3(CrossSiteDrag_TestState*); 348 void CrossSiteDrag_Step3(CrossSiteDrag_TestState*);
523 349
524 protected: 350 protected:
525 void SetUpOnMainThread() override { 351 void SetUpOnMainThread() override {
526 host_resolver()->AddRule("*", "127.0.0.1"); 352 host_resolver()->AddRule("*", "127.0.0.1");
527 content::SetupCrossSiteRedirector(embedded_test_server()); 353 content::SetupCrossSiteRedirector(embedded_test_server());
528 ASSERT_TRUE(embedded_test_server()->Start()); 354 ASSERT_TRUE(embedded_test_server()->Start());
529 drag_simulator_.reset(new DragAndDropSimulator(web_contents())); 355
356 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
530 } 357 }
531 358
532 bool use_cross_site_subframe() { 359 bool use_cross_site_subframe() {
533 // This is controlled by gtest's test param from INSTANTIATE_TEST_CASE_P. 360 // This is controlled by gtest's test param from INSTANTIATE_TEST_CASE_P.
534 return GetParam(); 361 return GetParam();
535 } 362 }
536 363
537 content::RenderFrameHost* left_frame() { 364 content::RenderFrameHost* left_frame() {
538 AssertTestPageIsLoaded(); 365 AssertTestPageIsLoaded();
539 return GetFrameByName("left"); 366 return GetFrameByName("left");
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 return true; 432 return true;
606 } 433 }
607 434
608 gfx::Point expected_location_of_drag_start_in_left_frame() { 435 gfx::Point expected_location_of_drag_start_in_left_frame() {
609 // TODO(crbug.com/653490): The delta below should exceed kDragThresholdX and 436 // TODO(crbug.com/653490): The delta below should exceed kDragThresholdX and
610 // kDragThresholdY from MouseEventManager.cpp in blink. Ideally, it would 437 // kDragThresholdY from MouseEventManager.cpp in blink. Ideally, it would
611 // come from the OS instead. 438 // come from the OS instead.
612 return kMiddleOfLeftFrame + gfx::Vector2d(10, 10); 439 return kMiddleOfLeftFrame + gfx::Vector2d(10, 10);
613 } 440 }
614 441
442 gfx::Point middle_of_right_frame() { return kMiddleOfRightFrame; }
443
615 bool SimulateMouseMoveToLeftFrame() { 444 bool SimulateMouseMoveToLeftFrame() {
616 AssertTestPageIsLoaded(); 445 AssertTestPageIsLoaded();
617 return SimulateMouseMove(kMiddleOfLeftFrame); 446 return SimulateMouseMove(kMiddleOfLeftFrame);
618 } 447 }
619 448
620 bool SimulateMouseMoveToRightFrame() { 449 bool SimulateMouseMoveToRightFrame() {
621 AssertTestPageIsLoaded(); 450 AssertTestPageIsLoaded();
622 return SimulateMouseMove(kMiddleOfRightFrame); 451 return SimulateMouseMove(kMiddleOfRightFrame);
623 } 452 }
624 453
625 bool SimulateMouseUp() { 454 bool SimulateMouseUp() {
626 return ui_test_utils::SendMouseEventsSync(ui_controls::LEFT, 455 return ui_test_utils::SendMouseEventsSync(ui_controls::LEFT,
627 ui_controls::UP); 456 ui_controls::UP);
628 } 457 }
629 458
630 ////////////////////////////////////////////////////////////////////
631 // Simulation of dragging from outside the browser into web contents
632 // (using DragAndDropSimulator, not simulating mouse events).
633
634 bool SimulateDragEnterToRightFrame(const std::string& text) {
635 AssertTestPageIsLoaded();
636 return drag_simulator_->SimulateDragEnter(kMiddleOfRightFrame, text);
637 }
638
639 bool SimulateDropInRightFrame() {
640 AssertTestPageIsLoaded();
641 return drag_simulator_->SimulateDrop(kMiddleOfRightFrame);
642 }
643
644 private: 459 private:
645 // Constants with coordinates within content/test/data/drag_and_drop/page.html 460 // Constants with coordinates within content/test/data/drag_and_drop/page.html
646 // The precise frame center is at 200,200 and 400,200 coordinates, but slight 461 // The precise frame center is at 200,200 and 400,200 coordinates, but slight
647 // differences between left and right frame hopefully make it easier to detect 462 // differences between left and right frame hopefully make it easier to detect
648 // incorrect dom_drag_and_drop_event.clientX/Y values in test asserts. 463 // incorrect dom_drag_and_drop_event.clientX/Y values in test asserts.
649 const gfx::Point kMiddleOfLeftFrame = gfx::Point(155, 150); 464 const gfx::Point kMiddleOfLeftFrame = gfx::Point(155, 150);
650 const gfx::Point kMiddleOfRightFrame = gfx::Point(455, 250); 465 const gfx::Point kMiddleOfRightFrame = gfx::Point(455, 250);
651 466
652 bool SimulateMouseDown() { 467 bool SimulateMouseDown() {
653 return ui_test_utils::SendMouseEventsSync(ui_controls::LEFT, 468 return ui_test_utils::SendMouseEventsSync(ui_controls::LEFT,
654 ui_controls::DOWN); 469 ui_controls::DOWN);
655 } 470 }
656 471
657 bool SimulateMouseMove(const gfx::Point& location_inside_web_contents) { 472 bool SimulateMouseMove(const gfx::Point& location_inside_web_contents) {
658 gfx::Rect bounds = web_contents()->GetContainerBounds(); 473 gfx::Rect bounds = web_contents()->GetContainerBounds();
659 return ui_test_utils::SendMouseMoveSync( 474 gfx::Point pos(bounds.x() + location_inside_web_contents.x(),
660 gfx::Point(bounds.x() + location_inside_web_contents.x(), 475 bounds.y() + location_inside_web_contents.y());
661 bounds.y() + location_inside_web_contents.y())); 476 LOG(ERROR) << "SimulateMouseMove"
477 << "; pos=(" << pos.x() << "," << pos.y() << ")";
478 return ui_test_utils::SendMouseMoveSync(pos);
662 } 479 }
663 480
664 bool NavigateNamedFrame(const std::string& frame_name, 481 bool NavigateNamedFrame(const std::string& frame_name,
665 const std::string& origin, 482 const std::string& origin,
666 const std::string& filename) { 483 const std::string& filename) {
667 content::RenderFrameHost* frame = GetFrameByName(frame_name); 484 content::RenderFrameHost* frame = GetFrameByName(frame_name);
668 if (!frame) 485 if (!frame)
669 return false; 486 return false;
670 487
671 std::string script; 488 std::string script;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
721 538
722 EXPECT_TRUE(result) << "Couldn't find a frame named " 539 EXPECT_TRUE(result) << "Couldn't find a frame named "
723 << "'" << name_to_find << "'"; 540 << "'" << name_to_find << "'";
724 return result; 541 return result;
725 } 542 }
726 543
727 void AssertTestPageIsLoaded() { 544 void AssertTestPageIsLoaded() {
728 ASSERT_EQ(kTestPagePath, web_contents()->GetLastCommittedURL().path()); 545 ASSERT_EQ(kTestPagePath, web_contents()->GetLastCommittedURL().path());
729 } 546 }
730 547
731 std::unique_ptr<DragAndDropSimulator> drag_simulator_;
732
733 DISALLOW_COPY_AND_ASSIGN(DragAndDropBrowserTest); 548 DISALLOW_COPY_AND_ASSIGN(DragAndDropBrowserTest);
734 }; 549 };
735 550
551 // TODO(lukasza): Implement ExternalDragEnterSimulator for Mac.
552 #if !defined(OS_MACOSX)
553
736 // Scenario: drag text from outside the browser and drop to the right frame. 554 // Scenario: drag text from outside the browser and drop to the right frame.
737 // Test coverage: dragover, drop DOM events. 555 // Test coverage: dragover, drop DOM events.
738 IN_PROC_BROWSER_TEST_P(DragAndDropBrowserTest, DropTextFromOutside) { 556 IN_PROC_BROWSER_TEST_P(DragAndDropBrowserTest, DropTextFromOutside) {
557 std::unique_ptr<ExternalDragEnterSimulator> drag_simulator =
558 ExternalDragEnterSimulator::Create(web_contents());
559
739 std::string frame_site = use_cross_site_subframe() ? "b.com" : "a.com"; 560 std::string frame_site = use_cross_site_subframe() ? "b.com" : "a.com";
740 ASSERT_TRUE(NavigateToTestPage("a.com")); 561 ASSERT_TRUE(NavigateToTestPage("a.com"));
741 ASSERT_TRUE(NavigateRightFrame(frame_site, "drop_target.html")); 562 ASSERT_TRUE(NavigateRightFrame(frame_site, "drop_target.html"));
742 563
743 // Setup test expectations. 564 // Setup test expectations.
744 DOMDragEventVerifier expected_dom_event_data; 565 DOMDragEventVerifier expected_dom_event_data;
745 expected_dom_event_data.set_expected_client_position("(155, 150)"); 566 expected_dom_event_data.set_expected_client_position("(155, 150)");
746 expected_dom_event_data.set_expected_drop_effect("none"); 567 expected_dom_event_data.set_expected_drop_effect("none");
747 expected_dom_event_data.set_expected_effect_allowed("all"); 568 expected_dom_event_data.set_expected_effect_allowed("all");
748 expected_dom_event_data.set_expected_mime_types("text/plain"); 569 expected_dom_event_data.set_expected_mime_types("text/plain");
749 expected_dom_event_data.set_expected_page_position("(155, 150)"); 570 expected_dom_event_data.set_expected_page_position("(155, 150)");
750 571
751 // Drag text from outside the browser into/over the right frame. 572 // Drag text from outside the browser into/over the right frame.
752 { 573 {
753 DOMDragEventWaiter dragover_waiter("dragover", right_frame()); 574 DOMDragEventWaiter dragover_waiter("dragover", right_frame());
754 ASSERT_TRUE(SimulateDragEnterToRightFrame("Dragged test text")); 575 ASSERT_TRUE(drag_simulator->SimulateDragEnter(middle_of_right_frame(),
576 "Dragged test text"));
755 577
756 std::string dragover_event; 578 std::string dragover_event;
757 ASSERT_TRUE(dragover_waiter.WaitForNextMatchingEvent(&dragover_event)); 579 ASSERT_TRUE(dragover_waiter.WaitForNextMatchingEvent(&dragover_event));
758 EXPECT_THAT(dragover_event, expected_dom_event_data.Matches()); 580 EXPECT_THAT(dragover_event, expected_dom_event_data.Matches());
759 } 581 }
760 582
761 // Drop into the right frame. 583 // Drop into the right frame.
762 { 584 {
763 DOMDragEventWaiter drop_waiter("drop", right_frame()); 585 DOMDragEventWaiter drop_waiter("drop", right_frame());
764 ASSERT_TRUE(SimulateDropInRightFrame()); 586 ASSERT_TRUE(drag_simulator->SimulateDrop(middle_of_right_frame()));
765 587
766 std::string drop_event; 588 std::string drop_event;
767 ASSERT_TRUE(drop_waiter.WaitForNextMatchingEvent(&drop_event)); 589 ASSERT_TRUE(drop_waiter.WaitForNextMatchingEvent(&drop_event));
768 EXPECT_THAT(drop_event, expected_dom_event_data.Matches()); 590 EXPECT_THAT(drop_event, expected_dom_event_data.Matches());
769 } 591 }
770 } 592 }
771 593
594 #endif
595
772 // Scenario: starting a drag in left frame 596 // Scenario: starting a drag in left frame
773 // Test coverage: dragstart DOM event, dragstart data passed to the OS. 597 // Test coverage: dragstart DOM event, dragstart data passed to the OS.
774 IN_PROC_BROWSER_TEST_P(DragAndDropBrowserTest, DragStartInFrame) { 598 IN_PROC_BROWSER_TEST_P(DragAndDropBrowserTest, DragStartInFrame) {
775 std::string frame_site = use_cross_site_subframe() ? "b.com" : "a.com"; 599 std::string frame_site = use_cross_site_subframe() ? "b.com" : "a.com";
776 ASSERT_TRUE(NavigateToTestPage("a.com")); 600 ASSERT_TRUE(NavigateToTestPage("a.com"));
777 ASSERT_TRUE(NavigateLeftFrame(frame_site, "image_source.html")); 601 ASSERT_TRUE(NavigateLeftFrame(frame_site, "image_source.html"));
778 602
779 // Setup test expectations. 603 // Setup test expectations.
780 DOMDragEventVerifier expected_dom_event_data; 604 DOMDragEventVerifier expected_dom_event_data;
781 expected_dom_event_data.set_expected_client_position("(55, 50)"); 605 expected_dom_event_data.set_expected_client_position("(55, 50)");
782 expected_dom_event_data.set_expected_drop_effect("none"); 606 expected_dom_event_data.set_expected_drop_effect("none");
783 // (dragstart event handler in image_source.html is asking for "copy" only). 607 // (dragstart event handler in image_source.html is asking for "copy" only).
784 expected_dom_event_data.set_expected_effect_allowed("copy"); 608 expected_dom_event_data.set_expected_effect_allowed("copy");
785 expected_dom_event_data.set_expected_page_position("(55, 50)"); 609 expected_dom_event_data.set_expected_page_position("(55, 50)");
786 610
787 // TODO(lukasza): Figure out why the dragstart event 611 // TODO(lukasza): Figure out why the dragstart event
788 // - lists "Files" on the mime types list, 612 // - lists "Files" on the mime types list,
789 // - doesn't list "text/plain" on the mime types list. 613 // - doesn't list "text/plain" on the mime types list.
790 // (i.e. why expectations below differ from expectations for dragenter, 614 // (i.e. why expectations below differ from expectations for dragenter,
791 // dragover, dragend and/or drop events in DragImageBetweenFrames test). 615 // dragover, dragend and/or drop events in DragImageBetweenFrames test).
792 expected_dom_event_data.set_expected_mime_types( 616 expected_dom_event_data.set_expected_mime_types(
793 "Files,text/html,text/uri-list"); 617 "Files,text/html,text/uri-list");
794 618
795 // Start the drag in the left frame. 619 // Start the drag in the left frame.
796 DragStartWaiter drag_start_waiter(web_contents()); 620 DragStartWaiter drag_start_waiter;
797 drag_start_waiter.SuppressPassingStartDragFurther(); 621 drag_start_waiter.SuppressPassingStartDragFurther();
798 DOMDragEventWaiter dragstart_event_waiter("dragstart", left_frame()); 622 DOMDragEventWaiter dragstart_event_waiter("dragstart", left_frame());
799 EXPECT_TRUE(SimulateMouseDownAndDragStartInLeftFrame()); 623 EXPECT_TRUE(SimulateMouseDownAndDragStartInLeftFrame());
800 624
801 // Verify Javascript event data. 625 // Verify Javascript event data.
802 { 626 {
803 std::string dragstart_event; 627 std::string dragstart_event;
804 EXPECT_TRUE( 628 EXPECT_TRUE(
805 dragstart_event_waiter.WaitForNextMatchingEvent(&dragstart_event)); 629 dragstart_event_waiter.WaitForNextMatchingEvent(&dragstart_event));
806 EXPECT_THAT(dragstart_event, expected_dom_event_data.Matches()); 630 EXPECT_THAT(dragstart_event, expected_dom_event_data.Matches());
807 } 631 }
808 632
809 // Verify data being passed to the OS. 633 // Verify data being passed to the OS.
810 { 634 {
811 std::string text; 635 content::DropData drop_data;
812 std::string html; 636 blink::WebDragOperationsMask operation;
813 int operation = 0; 637 drag_start_waiter.WaitUntilDragStart(&drop_data, &operation);
814 gfx::Point location_inside_web_contents; 638
815 drag_start_waiter.WaitUntilDragStart(&text, &html, &operation, 639 EXPECT_EQ("Alternative image text", base::UTF16ToUTF8(drop_data.url_title));
816 &location_inside_web_contents); 640 EXPECT_TRUE(drop_data.text.is_null());
641
642 EXPECT_EQ("droids.jpg",
643 base::UTF16ToUTF8(drop_data.file_description_filename));
817 EXPECT_EQ(embedded_test_server()->GetURL(frame_site, 644 EXPECT_EQ(embedded_test_server()->GetURL(frame_site,
818 "/image_decoding/droids.jpg"), 645 "/image_decoding/droids.jpg"),
819 text); 646 drop_data.url);
820 EXPECT_THAT(html, 647
821 testing::MatchesRegex("<img .*src=\"" 648 ASSERT_FALSE(drop_data.html.is_null());
649 EXPECT_THAT(base::UTF16ToUTF8(drop_data.html.string()),
650 testing::MatchesRegex("^<img .*src=\""
822 "http://.*/image_decoding/droids.jpg" 651 "http://.*/image_decoding/droids.jpg"
823 "\">")); 652 "\".*$"));
824 EXPECT_EQ(expected_location_of_drag_start_in_left_frame(), 653
825 location_inside_web_contents); 654 EXPECT_THAT(drop_data.filenames, testing::IsEmpty());
826 EXPECT_EQ(ui::DragDropTypes::DRAG_COPY, operation); 655 EXPECT_THAT(drop_data.file_mime_types, testing::IsEmpty());
656
657 EXPECT_THAT(drop_data.custom_data, testing::IsEmpty());
658
659 EXPECT_EQ("", base::UTF16ToUTF8(drop_data.filesystem_id));
660 EXPECT_THAT(drop_data.file_system_files, testing::IsEmpty());
661
662 EXPECT_EQ(blink::WebDragOperationCopy, operation);
827 } 663 }
828 664
829 // Try to leave everything in a clean state. 665 // Try to leave everything in a clean state.
830 SimulateMouseUp(); 666 SimulateMouseUp();
831 } 667 }
832 668
833 // There is no known way to execute test-controlled tasks during 669 // There is no known way to execute test-controlled tasks during
834 // a drag-and-drop loop run by Windows OS. 670 // a drag-and-drop loop run by Windows OS.
835 #if defined(OS_WIN) 671 #if defined(OS_WIN)
836 #define MAYBE_DragImageBetweenFrames DISABLED_DragImageBetweenFrames 672 #define MAYBE_DragImageBetweenFrames DISABLED_DragImageBetweenFrames
(...skipping 30 matching lines...) Expand all
867 new DOMDragEventCounter(right_frame())); 703 new DOMDragEventCounter(right_frame()));
868 state.expected_dom_event_data.set_expected_client_position("(55, 50)"); 704 state.expected_dom_event_data.set_expected_client_position("(55, 50)");
869 state.expected_dom_event_data.set_expected_drop_effect("none"); 705 state.expected_dom_event_data.set_expected_drop_effect("none");
870 // (dragstart event handler in image_source.html is asking for "copy" only). 706 // (dragstart event handler in image_source.html is asking for "copy" only).
871 state.expected_dom_event_data.set_expected_effect_allowed("copy"); 707 state.expected_dom_event_data.set_expected_effect_allowed("copy");
872 state.expected_dom_event_data.set_expected_mime_types( 708 state.expected_dom_event_data.set_expected_mime_types(
873 "text/html,text/plain,text/uri-list"); 709 "text/html,text/plain,text/uri-list");
874 state.expected_dom_event_data.set_expected_page_position("(55, 50)"); 710 state.expected_dom_event_data.set_expected_page_position("(55, 50)");
875 711
876 // Start the drag in the left frame. 712 // Start the drag in the left frame.
877 DragStartWaiter drag_start_waiter(web_contents()); 713 DragStartWaiter drag_start_waiter;
878 drag_start_waiter.PostTaskWhenDragStarts( 714 drag_start_waiter.PostTaskWhenDragStarts(
879 base::Bind(&DragAndDropBrowserTest::DragImageBetweenFrames_Step2, 715 base::Bind(&DragAndDropBrowserTest::DragImageBetweenFrames_Step2,
880 base::Unretained(this), base::Unretained(&state))); 716 base::Unretained(this), base::Unretained(&state)));
881 state.dragstart_event_waiter.reset( 717 state.dragstart_event_waiter.reset(
882 new DOMDragEventWaiter("dragstart", left_frame())); 718 new DOMDragEventWaiter("dragstart", left_frame()));
883 EXPECT_TRUE(SimulateMouseDownAndDragStartInLeftFrame()); 719 EXPECT_TRUE(SimulateMouseDownAndDragStartInLeftFrame());
884 720
885 // The next step of the test (DragImageBetweenFrames_Step2) runs inside the 721 // The next step of the test (DragImageBetweenFrames_Step2) runs inside the
886 // nested drag-and-drop message loop - the call below won't return until the 722 // nested drag-and-drop message loop - the call below won't return until the
887 // drag-and-drop has already ended. 723 // drag-and-drop has already ended.
888 drag_start_waiter.WaitUntilDragStart(nullptr, nullptr, nullptr, nullptr); 724 drag_start_waiter.WaitUntilDragStart(nullptr, nullptr);
889 725
890 DragImageBetweenFrames_Step3(&state); 726 DragImageBetweenFrames_Step3(&state);
891 } 727 }
892 728
893 void DragAndDropBrowserTest::DragImageBetweenFrames_Step2( 729 void DragAndDropBrowserTest::DragImageBetweenFrames_Step2(
894 DragAndDropBrowserTest::DragImageBetweenFrames_TestState* state) { 730 DragAndDropBrowserTest::DragImageBetweenFrames_TestState* state) {
895 // Verify dragstart DOM event. 731 // Verify dragstart DOM event.
896 { 732 {
897 std::string dragstart_event; 733 std::string dragstart_event;
898 EXPECT_TRUE(state->dragstart_event_waiter->WaitForNextMatchingEvent( 734 EXPECT_TRUE(state->dragstart_event_waiter->WaitForNextMatchingEvent(
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
1078 ASSERT_TRUE(NavigateLeftFrame(left_frame_site, "image_source.html")); 914 ASSERT_TRUE(NavigateLeftFrame(left_frame_site, "image_source.html"));
1079 ASSERT_TRUE(NavigateRightFrame(right_frame_site, "drop_target.html")); 915 ASSERT_TRUE(NavigateRightFrame(right_frame_site, "drop_target.html"));
1080 916
1081 // Setup test expectations. 917 // Setup test expectations.
1082 DragAndDropBrowserTest::CrossSiteDrag_TestState state; 918 DragAndDropBrowserTest::CrossSiteDrag_TestState state;
1083 state.left_frame_events_counter.reset(new DOMDragEventCounter(left_frame())); 919 state.left_frame_events_counter.reset(new DOMDragEventCounter(left_frame()));
1084 state.right_frame_events_counter.reset( 920 state.right_frame_events_counter.reset(
1085 new DOMDragEventCounter(right_frame())); 921 new DOMDragEventCounter(right_frame()));
1086 922
1087 // Start the drag in the left frame. 923 // Start the drag in the left frame.
1088 DragStartWaiter drag_start_waiter(web_contents()); 924 DragStartWaiter drag_start_waiter;
1089 drag_start_waiter.PostTaskWhenDragStarts( 925 drag_start_waiter.PostTaskWhenDragStarts(
1090 base::Bind(&DragAndDropBrowserTest::CrossSiteDrag_Step2, 926 base::Bind(&DragAndDropBrowserTest::CrossSiteDrag_Step2,
1091 base::Unretained(this), base::Unretained(&state))); 927 base::Unretained(this), base::Unretained(&state)));
1092 EXPECT_TRUE(SimulateMouseDownAndDragStartInLeftFrame()); 928 EXPECT_TRUE(SimulateMouseDownAndDragStartInLeftFrame());
1093 929
1094 // The next step of the test (CrossSiteDrag_Step2) runs inside the 930 // The next step of the test (CrossSiteDrag_Step2) runs inside the
1095 // nested drag-and-drop message loop - the call below won't return until the 931 // nested drag-and-drop message loop - the call below won't return until the
1096 // drag-and-drop has already ended. 932 // drag-and-drop has already ended.
1097 drag_start_waiter.WaitUntilDragStart(nullptr, nullptr, nullptr, nullptr); 933 drag_start_waiter.WaitUntilDragStart(nullptr, nullptr);
1098 934
1099 CrossSiteDrag_Step3(&state); 935 CrossSiteDrag_Step3(&state);
1100 } 936 }
1101 937
1102 void DragAndDropBrowserTest::CrossSiteDrag_Step2( 938 void DragAndDropBrowserTest::CrossSiteDrag_Step2(
1103 DragAndDropBrowserTest::CrossSiteDrag_TestState* state) { 939 DragAndDropBrowserTest::CrossSiteDrag_TestState* state) {
1104 // While "dragleave" and "drop" events are not expected in this test, we 940 // While "dragleave" and "drop" events are not expected in this test, we
1105 // simulate extra mouse operations for consistency with 941 // simulate extra mouse operations for consistency with
1106 // DragImageBetweenFrames_Step2. 942 // DragImageBetweenFrames_Step2.
1107 ASSERT_TRUE(SimulateMouseMoveToLeftFrame()); 943 ASSERT_TRUE(SimulateMouseMoveToLeftFrame());
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1162 // of a drag operation, and cross-site drags should be allowed across a 998 // of a drag operation, and cross-site drags should be allowed across a
1163 // navigation. 999 // navigation.
1164 1000
1165 INSTANTIATE_TEST_CASE_P( 1001 INSTANTIATE_TEST_CASE_P(
1166 SameSiteSubframe, DragAndDropBrowserTest, ::testing::Values(false)); 1002 SameSiteSubframe, DragAndDropBrowserTest, ::testing::Values(false));
1167 1003
1168 INSTANTIATE_TEST_CASE_P( 1004 INSTANTIATE_TEST_CASE_P(
1169 CrossSiteSubframe, DragAndDropBrowserTest, ::testing::Values(true)); 1005 CrossSiteSubframe, DragAndDropBrowserTest, ::testing::Values(true));
1170 1006
1171 } // namespace chrome 1007 } // namespace chrome
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698