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

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