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

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

Issue 2549023003: Automated test for dragging between same-page, cross-site frames. (Closed)
Patch Set: Fix the pattern used in the test filter file. 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 | content/public/test/browser_test_utils.h » ('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 <algorithm>
6 #include <initializer_list>
5 #include <memory> 7 #include <memory>
6 #include <string> 8 #include <string>
9 #include <vector>
7 10
8 #include "base/callback.h" 11 #include "base/callback.h"
9 #include "base/macros.h" 12 #include "base/macros.h"
10 #include "base/memory/ref_counted.h" 13 #include "base/memory/ref_counted.h"
11 #include "base/sequenced_task_runner.h" 14 #include "base/sequenced_task_runner.h"
12 #include "base/strings/pattern.h" 15 #include "base/strings/pattern.h"
13 #include "base/strings/string_piece.h" 16 #include "base/strings/string_piece.h"
14 #include "base/strings/stringprintf.h" 17 #include "base/strings/stringprintf.h"
15 #include "base/strings/utf_string_conversions.h" 18 #include "base/strings/utf_string_conversions.h"
16 #include "base/threading/sequenced_task_runner_handle.h" 19 #include "base/threading/sequenced_task_runner_handle.h"
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 int operation_; 303 int operation_;
301 gfx::Point location_inside_web_contents_; 304 gfx::Point location_inside_web_contents_;
302 305
303 DISALLOW_COPY_AND_ASSIGN(DragStartWaiter); 306 DISALLOW_COPY_AND_ASSIGN(DragStartWaiter);
304 }; 307 };
305 308
306 // Helper for waiting for notifications from 309 // Helper for waiting for notifications from
307 // content/test/data/drag_and_drop/event_monitoring.js 310 // content/test/data/drag_and_drop/event_monitoring.js
308 class DOMDragEventWaiter { 311 class DOMDragEventWaiter {
309 public: 312 public:
310 explicit DOMDragEventWaiter(const std::string& event_type_to_wait_for, 313 DOMDragEventWaiter(const std::string& event_type_to_wait_for,
311 const content::ToRenderFrameHost& target) 314 const content::ToRenderFrameHost& target)
312 : target_frame_name_(target.render_frame_host()->GetFrameName()), 315 : target_frame_name_(target.render_frame_host()->GetFrameName()),
313 event_type_to_wait_for_(event_type_to_wait_for), 316 event_type_to_wait_for_(event_type_to_wait_for),
314 dom_message_queue_(content::WebContents::FromRenderFrameHost( 317 dom_message_queue_(content::WebContents::FromRenderFrameHost(
315 target.render_frame_host())) {} 318 target.render_frame_host())) {}
316 319
317 // Waits until |target| calls reportDragEvent in 320 // Waits until |target| calls reportDragEvent in
318 // chrome/test/data/drag_and_drop/event_monitoring.js with event_type 321 // chrome/test/data/drag_and_drop/event_monitoring.js with event_type
319 // property set to |event_type_to_wait_for|. (|target| and 322 // property set to |event_type_to_wait_for|. (|target| and
320 // |event_type_to_wait_for| are passed to the constructor). 323 // |event_type_to_wait_for| are passed to the constructor).
321 // 324 //
322 // Returns the event details via |found_event| (in form of a JSON-encoded 325 // Returns the event details via |found_event| (in form of a JSON-encoded
323 // object). See chrome/test/data/drag_and_drop/event_monitoring.js for keys 326 // object). See chrome/test/data/drag_and_drop/event_monitoring.js for keys
324 // and properties that |found_event| is expected to have. 327 // and properties that |found_event| is expected to have.
325 // 328 //
326 // Returns true upon success. It is okay if |response| is null. 329 // Returns true upon success. It is okay if |response| is null.
327 bool WaitForNextMatchingEvent(std::string* found_event) WARN_UNUSED_RESULT { 330 bool WaitForNextMatchingEvent(std::string* found_event) WARN_UNUSED_RESULT {
328 std::string candidate_event; 331 std::string candidate_event;
329 bool got_right_event_type = false; 332 bool got_right_event_type = false;
330 bool got_right_window_name = false; 333 bool got_right_window_name = false;
331 do { 334 do {
332 if (!dom_message_queue_.WaitForMessage(&candidate_event)) 335 if (!dom_message_queue_.WaitForMessage(&candidate_event))
333 return false; 336 return false;
334 337
335 got_right_event_type = base::MatchPattern( 338 got_right_event_type =
336 candidate_event, base::StringPrintf("*\"event_type\":\"%s\"*", 339 IsExpectedEventType(candidate_event, event_type_to_wait_for_);
337 event_type_to_wait_for_.c_str())); 340 got_right_window_name =
338 341 IsExpectedWindowName(candidate_event, target_frame_name_);
339 got_right_window_name = base::MatchPattern(
340 candidate_event, base::StringPrintf("*\"window_name\":\"%s\"*",
341 target_frame_name_.c_str()));
342 } while (!got_right_event_type || !got_right_window_name); 342 } while (!got_right_event_type || !got_right_window_name);
343 343
344 if (found_event) 344 if (found_event)
345 *found_event = candidate_event; 345 *found_event = candidate_event;
346 346
347 return true; 347 return true;
348 } 348 }
349 349
350 static bool IsExpectedEventType(const std::string& actual_event_body,
351 const std::string& expected_event_type) {
352 return IsExpectedPropertyValue(actual_event_body, "event_type",
353 expected_event_type);
354 }
355
356 static bool IsExpectedWindowName(const std::string& actual_event_body,
357 const std::string& expected_window_name) {
358 return IsExpectedPropertyValue(actual_event_body, "window_name",
359 expected_window_name);
360 }
361
350 private: 362 private:
363 static bool IsExpectedPropertyValue(
364 const std::string& actual_event_body,
365 const std::string& property_name,
366 const std::string& expected_property_value) {
367 return base::MatchPattern(
368 actual_event_body,
369 base::StringPrintf("*\"%s\":\"%s\"*", property_name.c_str(),
370 expected_property_value.c_str()));
371 }
372
351 std::string target_frame_name_; 373 std::string target_frame_name_;
352 std::string event_type_to_wait_for_; 374 std::string event_type_to_wait_for_;
353 content::DOMMessageQueue dom_message_queue_; 375 content::DOMMessageQueue dom_message_queue_;
354 376
355 DISALLOW_COPY_AND_ASSIGN(DOMDragEventWaiter); 377 DISALLOW_COPY_AND_ASSIGN(DOMDragEventWaiter);
356 }; 378 };
357 379
358 // Helper for verifying contents of DOM events associated with drag-and-drop. 380 // Helper for verifying contents of DOM events associated with drag-and-drop.
359 class DOMDragEventVerifier { 381 class DOMDragEventVerifier {
360 public: 382 public:
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 427
406 std::string expected_drop_effect_ = "<no expectation>"; 428 std::string expected_drop_effect_ = "<no expectation>";
407 std::string expected_effect_allowed_ = "<no expectation>"; 429 std::string expected_effect_allowed_ = "<no expectation>";
408 std::string expected_mime_types_ = "<no expectation>"; 430 std::string expected_mime_types_ = "<no expectation>";
409 std::string expected_client_position_ = "<no expectation>"; 431 std::string expected_client_position_ = "<no expectation>";
410 std::string expected_page_position_ = "<no expectation>"; 432 std::string expected_page_position_ = "<no expectation>";
411 433
412 DISALLOW_COPY_AND_ASSIGN(DOMDragEventVerifier); 434 DISALLOW_COPY_AND_ASSIGN(DOMDragEventVerifier);
413 }; 435 };
414 436
437 // Helper for monitoring event notifications from
438 // content/test/data/drag_and_drop/event_monitoring.js
439 // and counting how many events of a given type were received.
440 class DOMDragEventCounter {
441 public:
442 explicit DOMDragEventCounter(const content::ToRenderFrameHost& target)
443 : target_frame_name_(target.render_frame_host()->GetFrameName()),
444 dom_message_queue_(content::WebContents::FromRenderFrameHost(
445 target.render_frame_host())) {}
446
447 // Resets all the accumulated event counts to zeros.
448 void Reset() {
449 StoreAccumulatedEvents();
450 received_events_.clear();
451 }
452
453 // Returns the number of events of the specified |event_type| received since
454 // construction, or since the last time Reset was called. |event_type| should
455 // be one of possible |type| property values for a DOM drag-and-drop event -
456 // e.g. "dragenter" or "dragover".
457 int GetNumberOfReceivedEvents(const std::string& event_type) {
458 std::vector<std::string> v({event_type});
459 return GetNumberOfReceivedEvents(v.begin(), v.end());
460 }
461
462 // Returns the number of events of the specified |event_types| received since
463 // construction, or since the last time Reset was called. Elements of
464 // |event_types| should be one of possible |type| property values for a DOM
465 // drag-and-drop event - e.g. "dragenter" or "dragover".
466 int GetNumberOfReceivedEvents(
467 std::initializer_list<const char*> event_types) {
468 return GetNumberOfReceivedEvents(event_types.begin(), event_types.end());
469 }
470
471 private:
472 template <typename T>
473 int GetNumberOfReceivedEvents(T event_types_begin, T event_types_end) {
474 StoreAccumulatedEvents();
475
476 auto received_event_has_matching_event_type =
477 [&event_types_begin,
478 &event_types_end](const std::string& received_event) {
479 return std::any_of(event_types_begin, event_types_end,
480 [&received_event](const std::string& event_type) {
481 return DOMDragEventWaiter::IsExpectedEventType(
482 received_event, event_type);
483 });
484 };
485
486 return std::count_if(received_events_.begin(), received_events_.end(),
487 received_event_has_matching_event_type);
488 }
489
490 void StoreAccumulatedEvents() {
491 std::string candidate_event;
492 while (dom_message_queue_.PopMessage(&candidate_event)) {
493 if (DOMDragEventWaiter::IsExpectedWindowName(candidate_event,
494 target_frame_name_)) {
495 received_events_.push_back(candidate_event);
496 }
497 }
498 }
499
500 std::string target_frame_name_;
501 content::DOMMessageQueue dom_message_queue_;
502 std::vector<std::string> received_events_;
503
504 DISALLOW_COPY_AND_ASSIGN(DOMDragEventCounter);
505 };
506
415 const char kTestPagePath[] = "/drag_and_drop/page.html"; 507 const char kTestPagePath[] = "/drag_and_drop/page.html";
416 508
417 } // namespace 509 } // namespace
418 510
419 class DragAndDropBrowserTest : public InProcessBrowserTest, 511 class DragAndDropBrowserTest : public InProcessBrowserTest,
420 public testing::WithParamInterface<bool> { 512 public testing::WithParamInterface<bool> {
421 public: 513 public:
422 DragAndDropBrowserTest(){}; 514 DragAndDropBrowserTest(){};
423 515
424 struct DragImageBetweenFrames_TestState; 516 struct DragImageBetweenFrames_TestState;
425 void DragImageBetweenFrames_Step2(DragImageBetweenFrames_TestState*); 517 void DragImageBetweenFrames_Step2(DragImageBetweenFrames_TestState*);
426 void DragImageBetweenFrames_Step3(DragImageBetweenFrames_TestState*); 518 void DragImageBetweenFrames_Step3(DragImageBetweenFrames_TestState*);
427 519
520 struct CrossSiteDrag_TestState;
521 void CrossSiteDrag_Step2(CrossSiteDrag_TestState*);
522 void CrossSiteDrag_Step3(CrossSiteDrag_TestState*);
523
428 protected: 524 protected:
429 void SetUpOnMainThread() override { 525 void SetUpOnMainThread() override {
430 host_resolver()->AddRule("*", "127.0.0.1"); 526 host_resolver()->AddRule("*", "127.0.0.1");
431 content::SetupCrossSiteRedirector(embedded_test_server()); 527 content::SetupCrossSiteRedirector(embedded_test_server());
432 ASSERT_TRUE(embedded_test_server()->Start()); 528 ASSERT_TRUE(embedded_test_server()->Start());
433 drag_simulator_.reset(new DragAndDropSimulator(web_contents())); 529 drag_simulator_.reset(new DragAndDropSimulator(web_contents()));
434 } 530 }
435 531
436 bool use_cross_site_subframe() { 532 bool use_cross_site_subframe() {
437 // This is controlled by gtest's test param from INSTANTIATE_TEST_CASE_P. 533 // This is controlled by gtest's test param from INSTANTIATE_TEST_CASE_P.
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
723 #define MAYBE_DragImageBetweenFrames DragImageBetweenFrames 819 #define MAYBE_DragImageBetweenFrames DragImageBetweenFrames
724 #endif 820 #endif
725 821
726 // Data that needs to be shared across multiple test steps below 822 // Data that needs to be shared across multiple test steps below
727 // (i.e. across DragImageBetweenFrames_Step2 and DragImageBetweenFrames_Step3). 823 // (i.e. across DragImageBetweenFrames_Step2 and DragImageBetweenFrames_Step3).
728 struct DragAndDropBrowserTest::DragImageBetweenFrames_TestState { 824 struct DragAndDropBrowserTest::DragImageBetweenFrames_TestState {
729 DOMDragEventVerifier expected_dom_event_data; 825 DOMDragEventVerifier expected_dom_event_data;
730 std::unique_ptr<DOMDragEventWaiter> dragstart_event_waiter; 826 std::unique_ptr<DOMDragEventWaiter> dragstart_event_waiter;
731 std::unique_ptr<DOMDragEventWaiter> drop_event_waiter; 827 std::unique_ptr<DOMDragEventWaiter> drop_event_waiter;
732 std::unique_ptr<DOMDragEventWaiter> dragend_event_waiter; 828 std::unique_ptr<DOMDragEventWaiter> dragend_event_waiter;
829 std::unique_ptr<DOMDragEventCounter> left_frame_events_counter;
830 std::unique_ptr<DOMDragEventCounter> right_frame_events_counter;
733 }; 831 };
734 832
735 // Scenario: drag an image from the left into the right frame. 833 // Scenario: drag an image from the left into the right frame.
736 // Test coverage: dragleave, dragenter, dragover, dragend, drop DOM events. 834 // Test coverage: dragleave, dragenter, dragover, dragend, drop DOM events.
737 IN_PROC_BROWSER_TEST_P(DragAndDropBrowserTest, MAYBE_DragImageBetweenFrames) { 835 IN_PROC_BROWSER_TEST_P(DragAndDropBrowserTest, MAYBE_DragImageBetweenFrames) {
738 // Note that drag and drop will not expose data across cross-site frames on 836 // 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 837 // 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. 838 // 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"; 839 std::string frame_site = use_cross_site_subframe() ? "b.com" : "a.com";
742 ASSERT_TRUE(NavigateToTestPage("a.com")); 840 ASSERT_TRUE(NavigateToTestPage("a.com"));
743 ASSERT_TRUE(NavigateLeftFrame(frame_site, "image_source.html")); 841 ASSERT_TRUE(NavigateLeftFrame(frame_site, "image_source.html"));
744 ASSERT_TRUE(NavigateRightFrame(frame_site, "drop_target.html")); 842 ASSERT_TRUE(NavigateRightFrame(frame_site, "drop_target.html"));
745 843
746 // Setup test expectations. 844 // Setup test expectations.
747 DragAndDropBrowserTest::DragImageBetweenFrames_TestState state; 845 DragAndDropBrowserTest::DragImageBetweenFrames_TestState state;
846 state.left_frame_events_counter.reset(new DOMDragEventCounter(left_frame()));
847 state.right_frame_events_counter.reset(
848 new DOMDragEventCounter(right_frame()));
748 state.expected_dom_event_data.set_expected_client_position("(55, 50)"); 849 state.expected_dom_event_data.set_expected_client_position("(55, 50)");
749 state.expected_dom_event_data.set_expected_drop_effect("none"); 850 state.expected_dom_event_data.set_expected_drop_effect("none");
750 // (dragstart event handler in image_source.html is asking for "copy" only). 851 // (dragstart event handler in image_source.html is asking for "copy" only).
751 state.expected_dom_event_data.set_expected_effect_allowed("copy"); 852 state.expected_dom_event_data.set_expected_effect_allowed("copy");
752 state.expected_dom_event_data.set_expected_mime_types( 853 state.expected_dom_event_data.set_expected_mime_types(
753 "text/html,text/plain,text/uri-list"); 854 "text/html,text/plain,text/uri-list");
754 state.expected_dom_event_data.set_expected_page_position("(55, 50)"); 855 state.expected_dom_event_data.set_expected_page_position("(55, 50)");
755 856
756 // Start the drag in the left frame. 857 // Start the drag in the left frame.
757 DragStartWaiter drag_start_waiter(web_contents()); 858 DragStartWaiter drag_start_waiter(web_contents());
(...skipping 13 matching lines...) Expand all
771 } 872 }
772 873
773 void DragAndDropBrowserTest::DragImageBetweenFrames_Step2( 874 void DragAndDropBrowserTest::DragImageBetweenFrames_Step2(
774 DragAndDropBrowserTest::DragImageBetweenFrames_TestState* state) { 875 DragAndDropBrowserTest::DragImageBetweenFrames_TestState* state) {
775 // Verify dragstart DOM event. 876 // Verify dragstart DOM event.
776 { 877 {
777 std::string dragstart_event; 878 std::string dragstart_event;
778 EXPECT_TRUE(state->dragstart_event_waiter->WaitForNextMatchingEvent( 879 EXPECT_TRUE(state->dragstart_event_waiter->WaitForNextMatchingEvent(
779 &dragstart_event)); 880 &dragstart_event));
780 state->dragstart_event_waiter.reset(); 881 state->dragstart_event_waiter.reset();
882
883 // Only a single "dragstart" should have fired in the left frame since the
884 // start of the test. We also allow any number of "dragover" events.
885 EXPECT_EQ(1, state->left_frame_events_counter->GetNumberOfReceivedEvents(
886 "dragstart"));
887 EXPECT_EQ(0, state->left_frame_events_counter->GetNumberOfReceivedEvents(
888 {"dragleave", "dragenter", "drop", "dragend"}));
889
890 // No events should have fired in the right frame yet.
891 EXPECT_EQ(0, state->right_frame_events_counter->GetNumberOfReceivedEvents(
892 {"dragstart", "dragleave", "dragenter", "dragover", "drop",
893 "dragend"}));
781 } 894 }
782 895
783 // While dragging, move mouse within the left frame. 896 // While dragging, move mouse within the left frame.
784 // Without this extra mouse move we wouldn't get a dragleave event later on. 897 // Without this extra mouse move we wouldn't get a dragleave event later on.
785 ASSERT_TRUE(SimulateMouseMoveToLeftFrame()); 898 ASSERT_TRUE(SimulateMouseMoveToLeftFrame());
786 899
787 // While dragging, move mouse from the left into the right frame. 900 // While dragging, move mouse from the left into the right frame.
788 // This should trigger dragleave and dragenter events. 901 // This should trigger dragleave and dragenter events.
789 { 902 {
790 DOMDragEventWaiter dragleave_event_waiter("dragleave", left_frame()); 903 DOMDragEventWaiter dragleave_event_waiter("dragleave", left_frame());
791 DOMDragEventWaiter dragenter_event_waiter("dragenter", right_frame()); 904 DOMDragEventWaiter dragenter_event_waiter("dragenter", right_frame());
905 state->left_frame_events_counter->Reset();
906 state->right_frame_events_counter->Reset();
792 ASSERT_TRUE(SimulateMouseMoveToRightFrame()); 907 ASSERT_TRUE(SimulateMouseMoveToRightFrame());
793 908
794 { // Verify dragleave DOM event. 909 { // Verify dragleave DOM event.
795 std::string dragleave_event; 910 std::string dragleave_event;
796 911
797 // TODO(paulmeyer): https://crbug.com/669695: Need to unify coordinates 912 // TODO(paulmeyer): https://crbug.com/669695: Need to unify coordinates
798 // passed to dragend when OOPIFs are present or not. 913 // passed to dragend when OOPIFs are present or not.
799 state->expected_dom_event_data.set_expected_client_position( 914 state->expected_dom_event_data.set_expected_client_position(
800 "<no expectation>"); 915 "<no expectation>");
801 state->expected_dom_event_data.set_expected_page_position( 916 state->expected_dom_event_data.set_expected_page_position(
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
834 ASSERT_TRUE(SimulateMouseMoveToRightFrame()); 949 ASSERT_TRUE(SimulateMouseMoveToRightFrame());
835 950
836 { // Verify dragover DOM event. 951 { // Verify dragover DOM event.
837 std::string dragover_event; 952 std::string dragover_event;
838 EXPECT_TRUE( 953 EXPECT_TRUE(
839 dragover_event_waiter.WaitForNextMatchingEvent(&dragover_event)); 954 dragover_event_waiter.WaitForNextMatchingEvent(&dragover_event));
840 EXPECT_THAT(dragover_event, state->expected_dom_event_data.Matches()); 955 EXPECT_THAT(dragover_event, state->expected_dom_event_data.Matches());
841 } 956 }
842 } 957 }
843 958
959 // Only a single "dragleave" should have fired in the left frame since the
960 // last checkpoint. We also allow any number of "dragover" events.
961 EXPECT_EQ(1, state->left_frame_events_counter->GetNumberOfReceivedEvents(
962 "dragleave"));
963 EXPECT_EQ(0, state->left_frame_events_counter->GetNumberOfReceivedEvents(
964 {"dragstart", "dragenter", "drop", "dragend"}));
965
966 // A single "dragenter" + at least one "dragover" event should have fired in
967 // the right frame since the last checkpoint.
968 EXPECT_EQ(1, state->right_frame_events_counter->GetNumberOfReceivedEvents(
969 "dragenter"));
970 EXPECT_LE(1, state->right_frame_events_counter->GetNumberOfReceivedEvents(
971 "dragover"));
ncarter (slow) 2016/12/09 18:28:39 Is this value just inconsistent across platforms,
Łukasz Anforowicz 2016/12/09 22:33:27 It is inconsistent across platforms. For example
972 EXPECT_EQ(0, state->right_frame_events_counter->GetNumberOfReceivedEvents(
973 {"dragstart", "dragleave", "drop", "dragend"}));
974
844 // Release the mouse button to end the drag. 975 // Release the mouse button to end the drag.
845 state->drop_event_waiter.reset(new DOMDragEventWaiter("drop", right_frame())); 976 state->drop_event_waiter.reset(new DOMDragEventWaiter("drop", right_frame()));
846 state->dragend_event_waiter.reset( 977 state->dragend_event_waiter.reset(
847 new DOMDragEventWaiter("dragend", left_frame())); 978 new DOMDragEventWaiter("dragend", left_frame()));
979 state->left_frame_events_counter->Reset();
980 state->right_frame_events_counter->Reset();
848 SimulateMouseUp(); 981 SimulateMouseUp();
849 // The test will continue in DragImageBetweenFrames_Step3. 982 // The test will continue in DragImageBetweenFrames_Step3.
850 } 983 }
851 984
852 void DragAndDropBrowserTest::DragImageBetweenFrames_Step3( 985 void DragAndDropBrowserTest::DragImageBetweenFrames_Step3(
853 DragAndDropBrowserTest::DragImageBetweenFrames_TestState* state) { 986 DragAndDropBrowserTest::DragImageBetweenFrames_TestState* state) {
854 // Verify drop DOM event. 987 // Verify drop DOM event.
855 { 988 {
856 std::string drop_event; 989 std::string drop_event;
857 EXPECT_TRUE( 990 EXPECT_TRUE(
(...skipping 15 matching lines...) Expand all
873 "<no expectation>"); 1006 "<no expectation>");
874 state->expected_dom_event_data.set_expected_page_position( 1007 state->expected_dom_event_data.set_expected_page_position(
875 "<no expectation>"); 1008 "<no expectation>");
876 1009
877 std::string dragend_event; 1010 std::string dragend_event;
878 EXPECT_TRUE( 1011 EXPECT_TRUE(
879 state->dragend_event_waiter->WaitForNextMatchingEvent(&dragend_event)); 1012 state->dragend_event_waiter->WaitForNextMatchingEvent(&dragend_event));
880 state->dragend_event_waiter.reset(); 1013 state->dragend_event_waiter.reset();
881 EXPECT_THAT(dragend_event, state->expected_dom_event_data.Matches()); 1014 EXPECT_THAT(dragend_event, state->expected_dom_event_data.Matches());
882 } 1015 }
1016
1017 // Only a single "dragend" should have fired in the left frame since the last
1018 // checkpoint.
1019 EXPECT_EQ(1, state->left_frame_events_counter->GetNumberOfReceivedEvents(
1020 "dragend"));
1021 EXPECT_EQ(0,
1022 state->left_frame_events_counter->GetNumberOfReceivedEvents(
1023 {"dragstart", "dragleave", "dragenter", "dragover", "drop"}));
1024
1025 // A single "drop" + possibly some "dragover" events should have fired in the
1026 // right frame since the last checkpoint.
1027 EXPECT_EQ(
1028 1, state->right_frame_events_counter->GetNumberOfReceivedEvents("drop"));
1029 EXPECT_EQ(0, state->right_frame_events_counter->GetNumberOfReceivedEvents(
1030 {"dragstart", "dragleave", "dragenter", "dragend"}));
1031 }
1032
1033 // There is no known way to execute test-controlled tasks during
1034 // a drag-and-drop loop run by Windows OS.
1035 #if defined(OS_WIN)
1036 #define MAYBE_CrossSiteDrag DISABLED_CrossSiteDrag
1037 #else
1038 #define MAYBE_CrossSiteDrag CrossSiteDrag
1039 #endif
1040
1041 // Data that needs to be shared across multiple test steps below
1042 // (i.e. across CrossSiteDrag_Step2 and CrossSiteDrag_Step3).
1043 struct DragAndDropBrowserTest::CrossSiteDrag_TestState {
1044 std::unique_ptr<DOMDragEventWaiter> dragend_event_waiter;
1045 std::unique_ptr<DOMDragEventCounter> left_frame_events_counter;
1046 std::unique_ptr<DOMDragEventCounter> right_frame_events_counter;
1047 };
1048
1049 // Scenario: drag an image from the left into the right frame when the
1050 // left-vs-right frames are cross-site. This is a regression test for
1051 // https://crbug.com/59081.
1052 //
1053 // Test coverage: absence of dragenter, dragover, drop DOM events
1054 // + presence of dragstart, dragleave and dragend.
1055 IN_PROC_BROWSER_TEST_P(DragAndDropBrowserTest, MAYBE_CrossSiteDrag) {
1056 std::string left_frame_site = "c.com"; // Always cross-site VS main frame.
1057 std::string right_frame_site = use_cross_site_subframe() ? "b.com" : "a.com";
1058 ASSERT_TRUE(NavigateToTestPage("a.com"));
1059 ASSERT_TRUE(NavigateLeftFrame(left_frame_site, "image_source.html"));
1060 ASSERT_TRUE(NavigateRightFrame(right_frame_site, "drop_target.html"));
1061
1062 // Setup test expectations.
1063 DragAndDropBrowserTest::CrossSiteDrag_TestState state;
1064 state.left_frame_events_counter.reset(new DOMDragEventCounter(left_frame()));
1065 state.right_frame_events_counter.reset(
1066 new DOMDragEventCounter(right_frame()));
1067
1068 // Start the drag in the left frame.
1069 DragStartWaiter drag_start_waiter(web_contents());
1070 drag_start_waiter.PostTaskWhenDragStarts(
1071 base::Bind(&DragAndDropBrowserTest::CrossSiteDrag_Step2,
1072 base::Unretained(this), base::Unretained(&state)));
1073 EXPECT_TRUE(SimulateMouseDownAndDragStartInLeftFrame());
1074
1075 // The next step of the test (CrossSiteDrag_Step2) runs inside the
1076 // nested drag-and-drop message loop - the call below won't return until the
1077 // drag-and-drop has already ended.
1078 drag_start_waiter.WaitUntilDragStart(nullptr, nullptr, nullptr, nullptr);
1079
1080 CrossSiteDrag_Step3(&state);
1081 }
1082
1083 void DragAndDropBrowserTest::CrossSiteDrag_Step2(
1084 DragAndDropBrowserTest::CrossSiteDrag_TestState* state) {
1085 // While "dragleave" and "drop" events are not expected in this test, we
1086 // simulate extra mouse operations for consistency with
1087 // DragImageBetweenFrames_Step2.
1088 ASSERT_TRUE(SimulateMouseMoveToLeftFrame());
1089 for (int i = 0; i < 3; i++) {
1090 content::DOMMessageQueue dom_message_queue(web_contents());
1091 ASSERT_TRUE(SimulateMouseMoveToRightFrame());
1092
1093 // No events are expected from the right frame, so we can't wait for a
1094 // dragover event here. Still - we do want to wait until the right frame
1095 // has had a chance to process any previous browser IPCs, so that in case
1096 // there *is* a bug and a dragover event *does* happen, we won't terminate
1097 // the test before the event has had a chance to be reported back to the
1098 // browser.
1099 std::string expected_response = base::StringPrintf("\"i%d\"", i);
1100 right_frame()->ExecuteJavaScriptWithUserGestureForTests(base::UTF8ToUTF16(
ncarter (slow) 2016/12/09 18:28:39 It's unfortunate that we can't use ExecuteScript i
Łukasz Anforowicz 2016/12/09 22:33:27 We could either relax ExecuteScriptAndExtractFoo t
1101 base::StringPrintf("domAutomationController.setAutomationId(0);\n"
1102 "domAutomationController.send(%s);\n",
1103 expected_response.c_str())));
1104
1105 // Wait until our response comes back (it might be mixed with responses
1106 // carrying events that are sent by event_monitoring.js).
1107 std::string actual_response;
1108 do {
1109 ASSERT_TRUE(dom_message_queue.WaitForMessage(&actual_response));
1110 } while (actual_response != expected_response);
1111 }
1112
1113 // Release the mouse button to end the drag.
1114 state->dragend_event_waiter.reset(
1115 new DOMDragEventWaiter("dragend", left_frame()));
1116 SimulateMouseUp();
1117 // The test will continue in DragImageBetweenFrames_Step3.
1118 }
1119
1120 void DragAndDropBrowserTest::CrossSiteDrag_Step3(
1121 DragAndDropBrowserTest::CrossSiteDrag_TestState* state) {
1122 EXPECT_TRUE(state->dragend_event_waiter->WaitForNextMatchingEvent(nullptr));
1123
1124 // Since the start of the test the left frame should have seen a single
1125 // "dragstart",
1126 // and a "dragend" event (and possibly a "dragleave" and some "dragover"
1127 // events).
1128 EXPECT_EQ(1, state->left_frame_events_counter->GetNumberOfReceivedEvents(
1129 "dragstart"));
1130 EXPECT_EQ(1, state->left_frame_events_counter->GetNumberOfReceivedEvents(
1131 "dragend"));
1132 EXPECT_EQ(
1133 0, state->left_frame_events_counter->GetNumberOfReceivedEvents("drop"));
1134
1135 // No events should have fired in the right frame, because it is cross-site
1136 // from the source of the drag. This is the essence of this test.
1137 EXPECT_EQ(0, state->right_frame_events_counter->GetNumberOfReceivedEvents(
1138 {"dragstart", "dragleave", "dragenter", "dragover", "drop",
1139 "dragend"}));
883 } 1140 }
884 1141
885 INSTANTIATE_TEST_CASE_P( 1142 INSTANTIATE_TEST_CASE_P(
886 SameSiteSubframe, DragAndDropBrowserTest, ::testing::Values(false)); 1143 SameSiteSubframe, DragAndDropBrowserTest, ::testing::Values(false));
887 1144
888 INSTANTIATE_TEST_CASE_P( 1145 INSTANTIATE_TEST_CASE_P(
889 CrossSiteSubframe, DragAndDropBrowserTest, ::testing::Values(true)); 1146 CrossSiteSubframe, DragAndDropBrowserTest, ::testing::Values(true));
890 1147
891 } // namespace chrome 1148 } // namespace chrome
OLDNEW
« no previous file with comments | « no previous file | content/public/test/browser_test_utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698