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

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

Issue 2507223003: Tests for dragging between two frames (potentially cross-site from main frame). (Closed)
Patch Set: Added SuppressPassingStartDragFurther method + moved constant definitions. Created 4 years 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
« no previous file with comments | « no previous file | chrome/test/data/drag_and_drop/drop_target.html » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <memory> 5 #include <memory>
6 #include <string> 6 #include <string>
7 7
8 #include "base/callback.h" 8 #include "base/callback.h"
9 #include "base/macros.h" 9 #include "base/macros.h"
10 #include "base/memory/ref_counted.h" 10 #include "base/memory/ref_counted.h"
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 std::unique_ptr<ui::DropTargetEvent> active_drag_event_; 164 std::unique_ptr<ui::DropTargetEvent> active_drag_event_;
165 165
166 DISALLOW_COPY_AND_ASSIGN(DragAndDropSimulator); 166 DISALLOW_COPY_AND_ASSIGN(DragAndDropSimulator);
167 }; 167 };
168 168
169 // Helper for waiting until a drag-and-drop starts (e.g. in response to a 169 // Helper for waiting until a drag-and-drop starts (e.g. in response to a
170 // mouse-down + mouse-move simulated by the test). 170 // mouse-down + mouse-move simulated by the test).
171 class DragStartWaiter : public aura::client::DragDropClient { 171 class DragStartWaiter : public aura::client::DragDropClient {
172 public: 172 public:
173 // Starts monitoring |web_contents| for a start of a drag-and-drop. 173 // Starts monitoring |web_contents| for a start of a drag-and-drop.
174 // While alive, prevents a real, OS-level drag-and-drop from starting
175 // for this particular |web_contents|.
176 explicit DragStartWaiter(content::WebContents* web_contents) 174 explicit DragStartWaiter(content::WebContents* web_contents)
177 : web_contents_(web_contents), 175 : web_contents_(web_contents),
178 message_loop_runner_(new content::MessageLoopRunner), 176 message_loop_runner_(new content::MessageLoopRunner),
177 suppress_passing_of_start_drag_further_(false),
179 drag_started_(false) { 178 drag_started_(false) {
180 DCHECK(web_contents_); 179 DCHECK(web_contents_);
181 180
182 // Intercept calls to the old DragDropClient. 181 // Intercept calls to the old DragDropClient.
183 gfx::NativeWindow root_window = 182 gfx::NativeWindow root_window =
184 web_contents_->GetContentNativeView()->GetRootWindow(); 183 web_contents_->GetContentNativeView()->GetRootWindow();
185 old_client_ = aura::client::GetDragDropClient(root_window); 184 old_client_ = aura::client::GetDragDropClient(root_window);
186 aura::client::SetDragDropClient(root_window, this); 185 aura::client::SetDragDropClient(root_window, this);
187 } 186 }
188 187
189 ~DragStartWaiter() override { 188 ~DragStartWaiter() override {
190 // Restore the original DragDropClient. 189 // Restore the original DragDropClient.
191 gfx::NativeWindow root_window = 190 gfx::NativeWindow root_window =
192 web_contents_->GetContentNativeView()->GetRootWindow(); 191 web_contents_->GetContentNativeView()->GetRootWindow();
193 aura::client::SetDragDropClient(root_window, old_client_); 192 aura::client::SetDragDropClient(root_window, old_client_);
194 } 193 }
195 194
196 // Waits until we almost report a drag-and-drop start to the OS 195 // Waits until we almost report a drag-and-drop start to the OS.
197 // (notifying the OS will be prevented to help the test continue 196 // At that point
198 // without entering a nested message loop). 197 // 1) the callback from PostTaskWhenDragStarts will be posted.
198 // 2) the drag-start request will be forwarded to the OS
199 // (unless SuppressPassingStartDragFurther method was called).
199 // 200 //
200 // Returns true if drag and drop has indeed started (and in this 201 // Note that if SuppressPassingStartDragFurther was not called then
201 // case populates |text|, |html| and other parameters with data 202 // WaitUntilDragStart can take a long time to return (it returns only after
202 // that would have been passed to the OS). 203 // the OS decides that the drag-and-drop has ended).
203 void WaitUntilDragStartIsIntercepted( 204 //
204 std::string* text, 205 // Before returning populates |text|, |html| and other parameters with data
205 std::string* html, 206 // that would have been passed to the OS). If the caller is not interested in
206 int* operation, 207 // this data, then the corresponding argument can be null.
207 gfx::Point* location_inside_web_contents) { 208 void WaitUntilDragStart(std::string* text,
209 std::string* html,
210 int* operation,
211 gfx::Point* location_inside_web_contents) {
208 message_loop_runner_->Run(); 212 message_loop_runner_->Run();
209 213
210 // message_loop_runner_->Quit is only called from StartDragAndDrop. 214 // message_loop_runner_->Quit is only called from StartDragAndDrop.
211 DCHECK(drag_started_); 215 DCHECK(drag_started_);
212 216
213 *text = text_; 217 if (text)
214 *html = html_; 218 *text = text_;
215 *operation = operation_; 219 if (html)
216 *location_inside_web_contents = location_inside_web_contents_; 220 *html = html_;
221 if (operation)
222 *operation = operation_;
223 if (location_inside_web_contents)
224 *location_inside_web_contents = location_inside_web_contents_;
225 }
226
227 void SuppressPassingStartDragFurther() {
228 suppress_passing_of_start_drag_further_ = true;
229 }
230
231 void PostTaskWhenDragStarts(const base::Closure& callback) {
232 callback_to_run_inside_drag_and_drop_message_loop_ = callback;
217 } 233 }
218 234
219 // aura::client::DragDropClient overrides: 235 // aura::client::DragDropClient overrides:
220 int StartDragAndDrop(const ui::OSExchangeData& data, 236 int StartDragAndDrop(const ui::OSExchangeData& data,
221 aura::Window* root_window, 237 aura::Window* root_window,
222 aura::Window* source_window, 238 aura::Window* source_window,
223 const gfx::Point& screen_location, 239 const gfx::Point& screen_location,
224 int operation, 240 int operation,
225 ui::DragDropTypes::DragEventSource source) override { 241 ui::DragDropTypes::DragEventSource source) override {
226 DCHECK(!drag_started_); 242 DCHECK(!drag_started_);
(...skipping 15 matching lines...) Expand all
242 html_ = "<no html>"; 258 html_ = "<no html>";
243 259
244 gfx::Rect bounds = 260 gfx::Rect bounds =
245 web_contents_->GetContentNativeView()->GetBoundsInScreen(); 261 web_contents_->GetContentNativeView()->GetBoundsInScreen();
246 location_inside_web_contents_ = 262 location_inside_web_contents_ =
247 screen_location - gfx::Vector2d(bounds.x(), bounds.y()); 263 screen_location - gfx::Vector2d(bounds.x(), bounds.y());
248 264
249 operation_ = operation; 265 operation_ = operation;
250 } 266 }
251 267
252 // Forwarding to |old_client_| is undesirable, because test cannot control 268 if (!callback_to_run_inside_drag_and_drop_message_loop_.is_null()) {
253 // next steps after a nested drag-and-drop loop is entered at the OS level 269 base::SequencedTaskRunnerHandle::Get()->PostTask(
254 // (as is the case in Windows, via DoDragDrop). Instead, in the test we 270 FROM_HERE,
255 // kind of ignore renderer's request to start drag and drop and never 271 std::move(callback_to_run_inside_drag_and_drop_message_loop_));
256 // forward this request to the OS-specific layers. 272 callback_to_run_inside_drag_and_drop_message_loop_.Reset();
257 return 0; 273 }
274
275 if (suppress_passing_of_start_drag_further_)
276 return 0;
277
278 // Start a nested drag-and-drop loop (might not return for a long time).
279 return old_client_->StartDragAndDrop(data, root_window, source_window,
280 screen_location, operation, source);
258 } 281 }
259 282
260 void DragCancel() override { 283 void DragCancel() override {
261 ADD_FAILURE() << "Unexpected call to DragCancel"; 284 ADD_FAILURE() << "Unexpected call to DragCancel";
262 } 285 }
263 286
264 bool IsDragDropInProgress() override { return drag_started_; } 287 bool IsDragDropInProgress() override { return drag_started_; }
265 288
266 private: 289 private:
267 content::WebContents* web_contents_; 290 content::WebContents* web_contents_;
268 scoped_refptr<content::MessageLoopRunner> message_loop_runner_; 291 scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
269 aura::client::DragDropClient* old_client_; 292 aura::client::DragDropClient* old_client_;
293 base::Closure callback_to_run_inside_drag_and_drop_message_loop_;
294 bool suppress_passing_of_start_drag_further_;
270 295
271 // Data captured during the first intercepted StartDragAndDrop call. 296 // Data captured during the first intercepted StartDragAndDrop call.
272 bool drag_started_; 297 bool drag_started_;
273 std::string text_; 298 std::string text_;
274 std::string html_; 299 std::string html_;
275 int operation_; 300 int operation_;
276 gfx::Point location_inside_web_contents_; 301 gfx::Point location_inside_web_contents_;
277 302
278 DISALLOW_COPY_AND_ASSIGN(DragStartWaiter); 303 DISALLOW_COPY_AND_ASSIGN(DragStartWaiter);
279 }; 304 };
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 414
390 const char kTestPagePath[] = "/drag_and_drop/page.html"; 415 const char kTestPagePath[] = "/drag_and_drop/page.html";
391 416
392 } // namespace 417 } // namespace
393 418
394 class DragAndDropBrowserTest : public InProcessBrowserTest, 419 class DragAndDropBrowserTest : public InProcessBrowserTest,
395 public testing::WithParamInterface<bool> { 420 public testing::WithParamInterface<bool> {
396 public: 421 public:
397 DragAndDropBrowserTest(){}; 422 DragAndDropBrowserTest(){};
398 423
424 struct DragImageBetweenFrames_TestState;
425 void DragImageBetweenFrames_Step2(DragImageBetweenFrames_TestState*);
426 void DragImageBetweenFrames_Step3(DragImageBetweenFrames_TestState*);
427
399 protected: 428 protected:
400 void SetUpOnMainThread() override { 429 void SetUpOnMainThread() override {
401 host_resolver()->AddRule("*", "127.0.0.1"); 430 host_resolver()->AddRule("*", "127.0.0.1");
402 content::SetupCrossSiteRedirector(embedded_test_server()); 431 content::SetupCrossSiteRedirector(embedded_test_server());
403 ASSERT_TRUE(embedded_test_server()->Start()); 432 ASSERT_TRUE(embedded_test_server()->Start());
404 drag_simulator_.reset(new DragAndDropSimulator(web_contents())); 433 drag_simulator_.reset(new DragAndDropSimulator(web_contents()));
405 } 434 }
406 435
407 bool use_cross_site_subframe() { 436 bool use_cross_site_subframe() {
408 // This is controlled by gtest's test param from INSTANTIATE_TEST_CASE_P. 437 // This is controlled by gtest's test param from INSTANTIATE_TEST_CASE_P.
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 return true; 490 return true;
462 } 491 }
463 492
464 gfx::Point expected_location_of_drag_start_in_left_frame() { 493 gfx::Point expected_location_of_drag_start_in_left_frame() {
465 // TODO(crbug.com/653490): The delta below should exceed kDragThresholdX and 494 // TODO(crbug.com/653490): The delta below should exceed kDragThresholdX and
466 // kDragThresholdY from MouseEventManager.cpp in blink. Ideally, it would 495 // kDragThresholdY from MouseEventManager.cpp in blink. Ideally, it would
467 // come from the OS instead. 496 // come from the OS instead.
468 return kMiddleOfLeftFrame + gfx::Vector2d(10, 10); 497 return kMiddleOfLeftFrame + gfx::Vector2d(10, 10);
469 } 498 }
470 499
500 bool SimulateMouseMoveToLeftFrame() {
501 AssertTestPageIsLoaded();
502 return SimulateMouseMove(kMiddleOfLeftFrame);
503 }
504
505 bool SimulateMouseMoveToRightFrame() {
506 AssertTestPageIsLoaded();
507 return SimulateMouseMove(kMiddleOfRightFrame);
508 }
509
471 bool SimulateMouseUp() { 510 bool SimulateMouseUp() {
472 return ui_test_utils::SendMouseEventsSync(ui_controls::LEFT, 511 return ui_test_utils::SendMouseEventsSync(ui_controls::LEFT,
473 ui_controls::UP); 512 ui_controls::UP);
474 } 513 }
475 514
476 //////////////////////////////////////////////////////////////////// 515 ////////////////////////////////////////////////////////////////////
477 // Simulation of dragging from outside the browser into web contents 516 // Simulation of dragging from outside the browser into web contents
478 // (using DragAndDropSimulator, not simulating mouse events). 517 // (using DragAndDropSimulator, not simulating mouse events).
479 518
480 bool SimulateDragEnterToRightFrame(const std::string& text) { 519 bool SimulateDragEnterToRightFrame(const std::string& text) {
481 AssertTestPageIsLoaded(); 520 AssertTestPageIsLoaded();
482 return drag_simulator_->SimulateDragEnter(kMiddleOfRightFrame, text); 521 return drag_simulator_->SimulateDragEnter(kMiddleOfRightFrame, text);
483 } 522 }
484 523
485 bool SimulateDropInRightFrame() { 524 bool SimulateDropInRightFrame() {
486 AssertTestPageIsLoaded(); 525 AssertTestPageIsLoaded();
487 return drag_simulator_->SimulateDrop(kMiddleOfRightFrame); 526 return drag_simulator_->SimulateDrop(kMiddleOfRightFrame);
488 } 527 }
489 528
490 private: 529 private:
530 // Constants with coordinates within content/test/data/drag_and_drop/page.html
531 // The precise frame center is at 200,200 and 400,200 coordinates, but slight
532 // differences between left and right frame hopefully make it easier to detect
533 // incorrect dom_drag_and_drop_event.clientX/Y values in test asserts.
534 const gfx::Point kMiddleOfLeftFrame = gfx::Point(155, 150);
535 const gfx::Point kMiddleOfRightFrame = gfx::Point(455, 250);
536
491 bool SimulateMouseDown() { 537 bool SimulateMouseDown() {
492 return ui_test_utils::SendMouseEventsSync(ui_controls::LEFT, 538 return ui_test_utils::SendMouseEventsSync(ui_controls::LEFT,
493 ui_controls::DOWN); 539 ui_controls::DOWN);
494 } 540 }
495 541
496 bool SimulateMouseMove(const gfx::Point& location_inside_web_contents) { 542 bool SimulateMouseMove(const gfx::Point& location_inside_web_contents) {
497 gfx::Rect bounds = web_contents()->GetContainerBounds(); 543 gfx::Rect bounds = web_contents()->GetContainerBounds();
498 return ui_test_utils::SendMouseMoveSync( 544 return ui_test_utils::SendMouseMoveSync(
499 gfx::Point(bounds.x() + location_inside_web_contents.x(), 545 gfx::Point(bounds.x() + location_inside_web_contents.x(),
500 bounds.y() + location_inside_web_contents.y())); 546 bounds.y() + location_inside_web_contents.y()));
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 << "'" << name_to_find << "'"; 608 << "'" << name_to_find << "'";
563 return result; 609 return result;
564 } 610 }
565 611
566 void AssertTestPageIsLoaded() { 612 void AssertTestPageIsLoaded() {
567 ASSERT_EQ(kTestPagePath, web_contents()->GetLastCommittedURL().path()); 613 ASSERT_EQ(kTestPagePath, web_contents()->GetLastCommittedURL().path());
568 } 614 }
569 615
570 std::unique_ptr<DragAndDropSimulator> drag_simulator_; 616 std::unique_ptr<DragAndDropSimulator> drag_simulator_;
571 617
572 // Constants with coordinates within content/test/data/drag_and_drop/page.html
573 const gfx::Point kMiddleOfLeftFrame = gfx::Point(200, 200);
574 const gfx::Point kMiddleOfRightFrame = gfx::Point(400, 200);
575
576 DISALLOW_COPY_AND_ASSIGN(DragAndDropBrowserTest); 618 DISALLOW_COPY_AND_ASSIGN(DragAndDropBrowserTest);
577 }; 619 };
578 620
621 // Scenario: drag text from outside the browser and drop to the right frame.
622 // Test coverage: dragover, drop DOM events.
579 IN_PROC_BROWSER_TEST_P(DragAndDropBrowserTest, DropTextFromOutside) { 623 IN_PROC_BROWSER_TEST_P(DragAndDropBrowserTest, DropTextFromOutside) {
580 std::string frame_site = use_cross_site_subframe() ? "b.com" : "a.com"; 624 std::string frame_site = use_cross_site_subframe() ? "b.com" : "a.com";
581 ASSERT_TRUE(NavigateToTestPage("a.com")); 625 ASSERT_TRUE(NavigateToTestPage("a.com"));
582 ASSERT_TRUE(NavigateRightFrame(frame_site, "drop_target.html")); 626 ASSERT_TRUE(NavigateRightFrame(frame_site, "drop_target.html"));
583 627
584 // Setup test expectations. 628 // Setup test expectations.
585 DOMDragEventVerifier expected_dom_event_data; 629 DOMDragEventVerifier expected_dom_event_data;
586 expected_dom_event_data.set_expected_client_position("(100, 100)"); 630 expected_dom_event_data.set_expected_client_position("(155, 150)");
587 expected_dom_event_data.set_expected_drop_effect("none"); 631 expected_dom_event_data.set_expected_drop_effect("none");
588 expected_dom_event_data.set_expected_effect_allowed("all"); 632 expected_dom_event_data.set_expected_effect_allowed("all");
589 expected_dom_event_data.set_expected_mime_types("text/plain"); 633 expected_dom_event_data.set_expected_mime_types("text/plain");
590 expected_dom_event_data.set_expected_page_position("(100, 100)"); 634 expected_dom_event_data.set_expected_page_position("(155, 150)");
591 635
592 // Drag text from outside the browser into/over the right frame. 636 // Drag text from outside the browser into/over the right frame.
593 { 637 {
594 DOMDragEventWaiter dragover_waiter("dragover", right_frame()); 638 DOMDragEventWaiter dragover_waiter("dragover", right_frame());
595 ASSERT_TRUE(SimulateDragEnterToRightFrame("Dragged test text")); 639 ASSERT_TRUE(SimulateDragEnterToRightFrame("Dragged test text"));
596 640
597 std::string dragover_event; 641 std::string dragover_event;
598 ASSERT_TRUE(dragover_waiter.WaitForNextMatchingEvent(&dragover_event)); 642 ASSERT_TRUE(dragover_waiter.WaitForNextMatchingEvent(&dragover_event));
599 EXPECT_THAT(dragover_event, expected_dom_event_data.Matches()); 643 EXPECT_THAT(dragover_event, expected_dom_event_data.Matches());
600 } 644 }
601 645
602 // Drop into the right frame. 646 // Drop into the right frame.
603 { 647 {
604 DOMDragEventWaiter drop_waiter("drop", right_frame()); 648 DOMDragEventWaiter drop_waiter("drop", right_frame());
605 ASSERT_TRUE(SimulateDropInRightFrame()); 649 ASSERT_TRUE(SimulateDropInRightFrame());
606 650
607 std::string drop_event; 651 std::string drop_event;
608 ASSERT_TRUE(drop_waiter.WaitForNextMatchingEvent(&drop_event)); 652 ASSERT_TRUE(drop_waiter.WaitForNextMatchingEvent(&drop_event));
609 EXPECT_THAT(drop_event, expected_dom_event_data.Matches()); 653 EXPECT_THAT(drop_event, expected_dom_event_data.Matches());
610 } 654 }
611 } 655 }
612 656
657 // Scenario: starting a drag in left frame
658 // Test coverage: dragstart DOM event, dragstart data passed to the OS.
613 IN_PROC_BROWSER_TEST_P(DragAndDropBrowserTest, DragStartInFrame) { 659 IN_PROC_BROWSER_TEST_P(DragAndDropBrowserTest, DragStartInFrame) {
614 std::string frame_site = use_cross_site_subframe() ? "b.com" : "a.com"; 660 std::string frame_site = use_cross_site_subframe() ? "b.com" : "a.com";
615 ASSERT_TRUE(NavigateToTestPage("a.com")); 661 ASSERT_TRUE(NavigateToTestPage("a.com"));
616 ASSERT_TRUE(NavigateLeftFrame(frame_site, "image_source.html")); 662 ASSERT_TRUE(NavigateLeftFrame(frame_site, "image_source.html"));
617 663
618 // Setup test expectations. 664 // Setup test expectations.
665 DOMDragEventVerifier expected_dom_event_data;
666 expected_dom_event_data.set_expected_client_position("(55, 50)");
667 expected_dom_event_data.set_expected_drop_effect("none");
619 // (dragstart event handler in image_source.html is asking for "copy" only). 668 // (dragstart event handler in image_source.html is asking for "copy" only).
620 DOMDragEventVerifier expected_dom_event_data;
621 expected_dom_event_data.set_expected_client_position("(100, 100)");
622 expected_dom_event_data.set_expected_drop_effect("none");
623 expected_dom_event_data.set_expected_effect_allowed("copy"); 669 expected_dom_event_data.set_expected_effect_allowed("copy");
670 expected_dom_event_data.set_expected_page_position("(55, 50)");
671
672 // TODO(lukasza): Figure out why the dragstart event
673 // - lists "Files" on the mime types list,
674 // - doesn't list "text/plain" on the mime types list.
675 // (i.e. why expectations below differ from expectations for dragenter,
676 // dragover, dragend and/or drop events in DragImageBetweenFrames test).
624 expected_dom_event_data.set_expected_mime_types( 677 expected_dom_event_data.set_expected_mime_types(
625 "Files,text/html,text/uri-list"); 678 "Files,text/html,text/uri-list");
626 expected_dom_event_data.set_expected_page_position("(100, 100)");
627 679
628 // Start the drag in the left frame. 680 // Start the drag in the left frame.
629 DragStartWaiter drag_start_waiter(web_contents()); 681 DragStartWaiter drag_start_waiter(web_contents());
682 drag_start_waiter.SuppressPassingStartDragFurther();
630 DOMDragEventWaiter dragstart_event_waiter("dragstart", left_frame()); 683 DOMDragEventWaiter dragstart_event_waiter("dragstart", left_frame());
631 EXPECT_TRUE(SimulateMouseDownAndDragStartInLeftFrame()); 684 EXPECT_TRUE(SimulateMouseDownAndDragStartInLeftFrame());
632 685
633 // Verify Javascript event data. 686 // Verify Javascript event data.
634 { 687 {
635 std::string dragstart_event; 688 std::string dragstart_event;
636 EXPECT_TRUE( 689 EXPECT_TRUE(
637 dragstart_event_waiter.WaitForNextMatchingEvent(&dragstart_event)); 690 dragstart_event_waiter.WaitForNextMatchingEvent(&dragstart_event));
638 EXPECT_THAT(dragstart_event, expected_dom_event_data.Matches()); 691 EXPECT_THAT(dragstart_event, expected_dom_event_data.Matches());
639 } 692 }
640 693
641 // Verify data being passed to the OS. 694 // Verify data being passed to the OS.
642 { 695 {
643 std::string text; 696 std::string text;
644 std::string html; 697 std::string html;
645 int operation = 0; 698 int operation = 0;
646 gfx::Point location_inside_web_contents; 699 gfx::Point location_inside_web_contents;
647 drag_start_waiter.WaitUntilDragStartIsIntercepted( 700 drag_start_waiter.WaitUntilDragStart(&text, &html, &operation,
648 &text, &html, &operation, &location_inside_web_contents); 701 &location_inside_web_contents);
649 EXPECT_EQ(embedded_test_server()->GetURL(frame_site, 702 EXPECT_EQ(embedded_test_server()->GetURL(frame_site,
650 "/image_decoding/droids.jpg"), 703 "/image_decoding/droids.jpg"),
651 text); 704 text);
652 EXPECT_THAT(html, 705 EXPECT_THAT(html,
653 testing::MatchesRegex("<img .*src=\"" 706 testing::MatchesRegex("<img .*src=\""
654 "http://.*/image_decoding/droids.jpg" 707 "http://.*/image_decoding/droids.jpg"
655 "\">")); 708 "\">"));
656 EXPECT_EQ(expected_location_of_drag_start_in_left_frame(), 709 EXPECT_EQ(expected_location_of_drag_start_in_left_frame(),
657 location_inside_web_contents); 710 location_inside_web_contents);
658 EXPECT_EQ(ui::DragDropTypes::DRAG_COPY, operation); 711 EXPECT_EQ(ui::DragDropTypes::DRAG_COPY, operation);
659 } 712 }
660 713
661 // Try to leave everything in a clean state. 714 // Try to leave everything in a clean state.
662 SimulateMouseUp(); 715 SimulateMouseUp();
663 } 716 }
664 717
718 // There is no known way to execute test-controlled tasks during
719 // a drag-and-drop loop run by Windows OS.
720 #if defined(OS_WIN)
721 #define MAYBE_DragImageBetweenFrames DISABLED_DragImageBetweenFrames
722 #else
723 #define MAYBE_DragImageBetweenFrames DragImageBetweenFrames
724 #endif
725
726 // Data that needs to be shared across multiple test steps below
727 // (i.e. across DragImageBetweenFrames_Step2 and DragImageBetweenFrames_Step3).
728 struct DragAndDropBrowserTest::DragImageBetweenFrames_TestState {
729 DOMDragEventVerifier expected_dom_event_data;
730 std::unique_ptr<DOMDragEventWaiter> dragstart_event_waiter;
731 std::unique_ptr<DOMDragEventWaiter> drop_event_waiter;
732 std::unique_ptr<DOMDragEventWaiter> dragend_event_waiter;
733 };
734
735 // Scenario: drag an image from the left into the right frame.
736 // Test coverage: dragleave, dragenter, dragover, dragend, drop DOM events.
737 IN_PROC_BROWSER_TEST_P(DragAndDropBrowserTest, MAYBE_DragImageBetweenFrames) {
738 // Note that drag and drop will not expose data across cross-site frames on
739 // the same page - this is why the same |frame_site| is used below both for
740 // the left and the right frame. See also https://crbug.com/59081.
741 std::string frame_site = use_cross_site_subframe() ? "b.com" : "a.com";
742 ASSERT_TRUE(NavigateToTestPage("a.com"));
743 ASSERT_TRUE(NavigateLeftFrame(frame_site, "image_source.html"));
744 ASSERT_TRUE(NavigateRightFrame(frame_site, "drop_target.html"));
745
746 // Setup test expectations.
747 DragAndDropBrowserTest::DragImageBetweenFrames_TestState state;
748 state.expected_dom_event_data.set_expected_client_position("(55, 50)");
749 state.expected_dom_event_data.set_expected_drop_effect("none");
750 // (dragstart event handler in image_source.html is asking for "copy" only).
751 state.expected_dom_event_data.set_expected_effect_allowed("copy");
752 state.expected_dom_event_data.set_expected_mime_types(
753 "text/html,text/plain,text/uri-list");
754 state.expected_dom_event_data.set_expected_page_position("(55, 50)");
755
756 // Start the drag in the left frame.
757 DragStartWaiter drag_start_waiter(web_contents());
758 drag_start_waiter.PostTaskWhenDragStarts(
759 base::Bind(&DragAndDropBrowserTest::DragImageBetweenFrames_Step2,
760 base::Unretained(this), base::Unretained(&state)));
761 state.dragstart_event_waiter.reset(
762 new DOMDragEventWaiter("dragstart", left_frame()));
763 EXPECT_TRUE(SimulateMouseDownAndDragStartInLeftFrame());
764
765 // The next step of the test (DragImageBetweenFrames_Step2) runs inside the
766 // nested drag-and-drop message loop - the call below won't return until the
767 // drag-and-drop has already ended.
768 drag_start_waiter.WaitUntilDragStart(nullptr, nullptr, nullptr, nullptr);
769
770 DragImageBetweenFrames_Step3(&state);
771 }
772
773 void DragAndDropBrowserTest::DragImageBetweenFrames_Step2(
774 DragAndDropBrowserTest::DragImageBetweenFrames_TestState* state) {
775 // Verify dragstart DOM event.
776 {
777 std::string dragstart_event;
778 EXPECT_TRUE(state->dragstart_event_waiter->WaitForNextMatchingEvent(
779 &dragstart_event));
780 state->dragstart_event_waiter.reset();
781 }
782
783 // While dragging, move mouse within the left frame.
784 // Without this extra mouse move we wouldn't get a dragleave event later on.
785 ASSERT_TRUE(SimulateMouseMoveToLeftFrame());
786
787 // While dragging, move mouse from the left into the right frame.
788 // This should trigger dragleave and dragenter events.
789 {
790 DOMDragEventWaiter dragleave_event_waiter("dragleave", left_frame());
791 DOMDragEventWaiter dragenter_event_waiter("dragenter", right_frame());
792 ASSERT_TRUE(SimulateMouseMoveToRightFrame());
793
794 { // Verify dragleave DOM event.
795 std::string dragleave_event;
796
797 // TODO(paulmeyer): https://crbug.com/669695: Need to unify coordinates
798 // passed to dragend when OOPIFs are present or not.
799 state->expected_dom_event_data.set_expected_client_position(
800 "<no expectation>");
801 state->expected_dom_event_data.set_expected_page_position(
802 "<no expectation>");
803
804 EXPECT_TRUE(
805 dragleave_event_waiter.WaitForNextMatchingEvent(&dragleave_event));
806 EXPECT_THAT(dragleave_event, state->expected_dom_event_data.Matches());
807 }
808
809 { // Verify dragenter DOM event.
810 std::string dragenter_event;
811
812 // Update expected event coordinates after SimulateMouseMoveToRightFrame
813 // (these coordinates are relative to the right frame).
814 state->expected_dom_event_data.set_expected_client_position("(155, 150)");
815 state->expected_dom_event_data.set_expected_page_position("(155, 150)");
816
817 EXPECT_TRUE(
818 dragenter_event_waiter.WaitForNextMatchingEvent(&dragenter_event));
819 EXPECT_THAT(dragenter_event, state->expected_dom_event_data.Matches());
820 }
821
822 // Note that ash (unlike aura/x11) will not fire dragover event in response
823 // to the same mouse event that trigerred a dragenter. Because of that, we
824 // postpone dragover testing until the next test step below. See
825 // implementation of ash::DragDropController::DragUpdate for details.
826 }
827
828 // Move the mouse twice in the right frame. The 1st move will ensure that
829 // allowed operations communicated by the renderer will be stored in
830 // WebContentsViewAura::current_drag_op_. The 2nd move will ensure that this
831 // gets be copied into DesktopDragDropClientAuraX11::negotiated_operation_.
832 for (int i = 0; i < 2; i++) {
833 DOMDragEventWaiter dragover_event_waiter("dragover", right_frame());
834 ASSERT_TRUE(SimulateMouseMoveToRightFrame());
835
836 { // Verify dragover DOM event.
837 std::string dragover_event;
838 EXPECT_TRUE(
839 dragover_event_waiter.WaitForNextMatchingEvent(&dragover_event));
840 EXPECT_THAT(dragover_event, state->expected_dom_event_data.Matches());
841 }
842 }
843
844 // Release the mouse button to end the drag.
845 state->drop_event_waiter.reset(new DOMDragEventWaiter("drop", right_frame()));
846 state->dragend_event_waiter.reset(
847 new DOMDragEventWaiter("dragend", left_frame()));
848 SimulateMouseUp();
849 // The test will continue in DragImageBetweenFrames_Step3.
850 }
851
852 void DragAndDropBrowserTest::DragImageBetweenFrames_Step3(
853 DragAndDropBrowserTest::DragImageBetweenFrames_TestState* state) {
854 // Verify drop DOM event.
855 {
856 std::string drop_event;
857 EXPECT_TRUE(
858 state->drop_event_waiter->WaitForNextMatchingEvent(&drop_event));
859 state->drop_event_waiter.reset();
860 EXPECT_THAT(drop_event, state->expected_dom_event_data.Matches());
861 }
862
863 // Verify dragend DOM event.
864 {
865 // TODO(lukasza): Figure out why the drop event sees different values of
866 // DataTransfer.dropEffect and DataTransfer.types properties.
867 state->expected_dom_event_data.set_expected_drop_effect("copy");
868 state->expected_dom_event_data.set_expected_mime_types("");
869
870 // TODO(paulmeyer): https://crbug.com/669695: Need to unify coordinates
871 // passed to dragend when OOPIFs are present or not.
872 state->expected_dom_event_data.set_expected_client_position(
873 "<no expectation>");
874 state->expected_dom_event_data.set_expected_page_position(
875 "<no expectation>");
876
877 std::string dragend_event;
878 EXPECT_TRUE(
879 state->dragend_event_waiter->WaitForNextMatchingEvent(&dragend_event));
880 state->dragend_event_waiter.reset();
881 EXPECT_THAT(dragend_event, state->expected_dom_event_data.Matches());
882 }
883 }
884
665 INSTANTIATE_TEST_CASE_P( 885 INSTANTIATE_TEST_CASE_P(
666 SameSiteSubframe, DragAndDropBrowserTest, ::testing::Values(false)); 886 SameSiteSubframe, DragAndDropBrowserTest, ::testing::Values(false));
667 887
668 INSTANTIATE_TEST_CASE_P( 888 INSTANTIATE_TEST_CASE_P(
669 CrossSiteSubframe, DragAndDropBrowserTest, ::testing::Values(true)); 889 CrossSiteSubframe, DragAndDropBrowserTest, ::testing::Values(true));
670 890
671 } // namespace chrome 891 } // namespace chrome
OLDNEW
« no previous file with comments | « no previous file | chrome/test/data/drag_and_drop/drop_target.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698