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

Side by Side Diff: chrome/browser/drag_and_drop_browsertest.cc

Issue 2478583005: Browser tests for starting a drag-and-drop out of an OOPIF. (Closed)
Patch Set: Integrate the test with the nested drag-and-drop message loop. Created 4 years, 1 month 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/BUILD.gn » ('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/macros.h" 9 #include "base/macros.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/sequenced_task_runner.h"
9 #include "base/strings/pattern.h" 12 #include "base/strings/pattern.h"
10 #include "base/strings/string_piece.h" 13 #include "base/strings/string_piece.h"
11 #include "base/strings/stringprintf.h" 14 #include "base/strings/stringprintf.h"
12 #include "base/strings/utf_string_conversions.h" 15 #include "base/strings/utf_string_conversions.h"
13 #include "content/browser/frame_host/frame_tree.h" 16 #include "base/threading/sequenced_task_runner_handle.h"
14 #include "content/browser/frame_host/frame_tree_node.h" 17 #include "chrome/browser/ui/browser.h"
15 #include "content/browser/frame_host/render_frame_host_impl.h" 18 #include "chrome/browser/ui/tabs/tab_strip_model.h"
16 #include "content/browser/web_contents/web_contents_impl.h" 19 #include "chrome/test/base/in_process_browser_test.h"
20 #include "chrome/test/base/interactive_test_utils.h"
21 #include "chrome/test/base/ui_test_utils.h"
17 #include "content/public/browser/render_frame_host.h" 22 #include "content/public/browser/render_frame_host.h"
18 #include "content/public/browser/web_contents.h" 23 #include "content/public/browser/web_contents.h"
19 #include "content/public/test/browser_test_utils.h" 24 #include "content/public/test/browser_test_utils.h"
20 #include "content/public/test/content_browser_test.h" 25 #include "content/public/test/content_browser_test.h"
21 #include "content/public/test/content_browser_test_utils.h" 26 #include "content/public/test/content_browser_test_utils.h"
27 #include "content/public/test/test_frame_navigation_observer.h"
22 #include "content/public/test/test_utils.h" 28 #include "content/public/test/test_utils.h"
23 #include "content/shell/browser/shell.h"
24 #include "net/base/escape.h" 29 #include "net/base/escape.h"
25 #include "net/dns/mock_host_resolver.h" 30 #include "net/dns/mock_host_resolver.h"
26 #include "net/test/embedded_test_server/embedded_test_server.h" 31 #include "net/test/embedded_test_server/embedded_test_server.h"
27 #include "testing/gmock/include/gmock/gmock.h" 32 #include "testing/gmock/include/gmock/gmock.h"
28 #include "testing/gtest/include/gtest/gtest.h" 33 #include "testing/gtest/include/gtest/gtest.h"
34 #include "ui/aura/client/drag_drop_client.h"
29 #include "ui/aura/client/drag_drop_delegate.h" 35 #include "ui/aura/client/drag_drop_delegate.h"
30 #include "ui/aura/client/screen_position_client.h" 36 #include "ui/aura/client/screen_position_client.h"
31 #include "ui/aura/window.h" 37 #include "ui/aura/window.h"
32 #include "ui/base/dragdrop/drag_drop_types.h" 38 #include "ui/base/dragdrop/drag_drop_types.h"
33 #include "ui/base/dragdrop/drop_target_event.h" 39 #include "ui/base/dragdrop/drop_target_event.h"
34 #include "ui/base/dragdrop/os_exchange_data.h" 40 #include "ui/base/dragdrop/os_exchange_data.h"
35 #include "ui/gfx/geometry/point.h" 41 #include "ui/gfx/geometry/point.h"
36 #include "ui/gfx/geometry/rect.h" 42 #include "ui/gfx/geometry/rect.h"
37 #include "url/gurl.h" 43 #include "url/gurl.h"
38 44
39 namespace content { 45 namespace chrome {
40 46
41 namespace { 47 namespace {
42 48
43 // TODO(lukasza): Support testing on non-Aura platforms (i.e. Android + Mac?). 49 // TODO(lukasza): Support testing on non-Aura platforms (i.e. Android + Mac?).
44 // 50 //
45 // Notes for the TODO above: 51 // Notes for the TODO above:
46 // 52 //
47 // - Why inject/simulate drag-and-drop events at the aura::Window* level. 53 // - Why inject/simulate drag-and-drop events at the aura::Window* level.
48 // 54 //
49 // - It seems better to inject into UI libraries to cover code *inside* these 55 // - It seems better to inject into UI libraries to cover code *inside* these
(...skipping 13 matching lines...) Expand all
63 // - Unknowns: 69 // - Unknowns:
64 // 70 //
65 // - Will this work for WebView and Plugin testing. 71 // - Will this work for WebView and Plugin testing.
66 // 72 //
67 // - Will this work for simulating dragging from WebContents into outside of 73 // - Will this work for simulating dragging from WebContents into outside of
68 // the browser (without leaving OS drag&drop machinery in a weird state). 74 // the browser (without leaving OS drag&drop machinery in a weird state).
69 75
70 // Test helper for simulating drag and drop happening in WebContents. 76 // Test helper for simulating drag and drop happening in WebContents.
71 class DragAndDropSimulator { 77 class DragAndDropSimulator {
72 public: 78 public:
73 explicit DragAndDropSimulator(WebContents* web_contents) 79 explicit DragAndDropSimulator(content::WebContents* web_contents)
74 : web_contents_(web_contents) {} 80 : web_contents_(web_contents) {}
75 81
76 // Simulates notification that |text| was dragged from outside of the browser, 82 // Simulates notification that |text| was dragged from outside of the browser,
77 // into the specified |location| inside |web_contents|. 83 // into the specified |location| inside |web_contents|.
78 // |location| is relative to |web_contents|. 84 // |location| is relative to |web_contents|.
79 // Returns true upon success. 85 // Returns true upon success.
80 bool SimulateDragEnter(gfx::Point location, const std::string& text) { 86 bool SimulateDragEnter(gfx::Point location, const std::string& text) {
81 ui::OSExchangeData data; 87 ui::OSExchangeData data;
82 data.SetString(base::UTF8ToUTF16(text)); 88 data.SetString(base::UTF8ToUTF16(text));
83 return SimulateDragEnter(location, data); 89 return SimulateDragEnter(location, data);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 *out_event_location = root_location; 156 *out_event_location = root_location;
151 } 157 }
152 158
153 // These are ui::DropTargetEvent::source_operations_ being sent when manually 159 // These are ui::DropTargetEvent::source_operations_ being sent when manually
154 // trying out drag&drop of an image file from Nemo (Ubuntu's file explorer) 160 // trying out drag&drop of an image file from Nemo (Ubuntu's file explorer)
155 // into a content_shell. 161 // into a content_shell.
156 static constexpr int kDefaultSourceOperations = ui::DragDropTypes::DRAG_MOVE | 162 static constexpr int kDefaultSourceOperations = ui::DragDropTypes::DRAG_MOVE |
157 ui::DragDropTypes::DRAG_COPY | 163 ui::DragDropTypes::DRAG_COPY |
158 ui::DragDropTypes::DRAG_LINK; 164 ui::DragDropTypes::DRAG_LINK;
159 165
160 WebContents* web_contents_; 166 content::WebContents* web_contents_;
161 std::unique_ptr<ui::DropTargetEvent> active_drag_event_; 167 std::unique_ptr<ui::DropTargetEvent> active_drag_event_;
162 168
163 DISALLOW_COPY_AND_ASSIGN(DragAndDropSimulator); 169 DISALLOW_COPY_AND_ASSIGN(DragAndDropSimulator);
164 }; 170 };
165 171
172 // Helper for waiting until a drag-and-drop nested message loop starts
173 // (i.e. in response to a mouse-down + mouse-move simulated by the test)
174 // and for running a test continuation inside the nested message loop.
175 class DragStartWaiter : public aura::client::DragDropClient {
176 public:
177 using TestContinuationCallback =
178 base::Callback<void(const std::string& text,
179 const std::string& html,
180 int operation,
181 bool did_originate_from_renderer)>;
182
183 // Starts monitoring |web_contents| for a start of a drag-and-drop.
184 // Will call |test_continuation| when drag-and-drop starts.
185 DragStartWaiter(content::WebContents* web_contents,
186 const TestContinuationCallback& test_continuation)
187 : web_contents_(web_contents),
188 test_continuation_(test_continuation),
189 message_loop_runner_(new content::MessageLoopRunner) {
190 DCHECK(web_contents_);
191 DCHECK(!test_continuation_.is_null());
192
193 // Intercept calls to the old DragDropClient.
194 gfx::NativeWindow root_window =
195 web_contents_->GetContentNativeView()->GetRootWindow();
196 old_client_ = aura::client::GetDragDropClient(root_window);
197 aura::client::SetDragDropClient(root_window, this);
198 }
199
200 ~DragStartWaiter() override {
201 // Restore the original DragDropClient.
202 gfx::NativeWindow root_window =
203 web_contents_->GetContentNativeView()->GetRootWindow();
204 aura::client::SetDragDropClient(root_window, old_client_);
205 }
206
207 // Waits until drag-and-drop starts, ensures |test_continuation| is run (see
208 // the constructor) and then returns after the drag-and-drop has ended.
209 void WaitUntilFullDragAndDropCompletes() { message_loop_runner_->Run(); }
210
211 int StartDragAndDrop(const ui::OSExchangeData& data,
212 aura::Window* root_window,
213 aura::Window* source_window,
214 const gfx::Point& screen_location,
215 int operation,
216 ui::DragDropTypes::DragEventSource source) override {
217 if (!test_continuation_.is_null()) {
218 base::string16 text;
219 if (!data.GetString(&text))
220 text = base::ASCIIToUTF16("<no text>");
221
222 GURL base_url;
223 base::string16 html;
224 if (!data.GetHtml(&html, &base_url))
225 html = base::ASCIIToUTF16("<no html>");
226
227 base::SequencedTaskRunnerHandle::Get()->PostTask(
228 FROM_HERE,
229 base::Bind(std::move(test_continuation_), base::UTF16ToUTF8(text),
230 base::UTF16ToUTF8(html), operation,
231 data.DidOriginateFromRenderer()));
232
233 test_continuation_.Reset();
234 message_loop_runner_->Quit();
235 }
236
237 // This will kick-off a nested message loop and won't return until
238 // drag-and-drop ends.
239 return old_client_->StartDragAndDrop(data, root_window, source_window,
240 screen_location, operation, source);
241 }
242
243 void DragCancel() override { old_client_->DragCancel(); }
244
245 bool IsDragDropInProgress() override {
246 return old_client_->IsDragDropInProgress();
247 }
248
249 private:
250 content::WebContents* web_contents_;
251 DragStartWaiter::TestContinuationCallback test_continuation_;
252 scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
253 aura::client::DragDropClient* old_client_;
254 };
255
166 // Helper for waiting for notifications from 256 // Helper for waiting for notifications from
167 // content/test/data/drag_and_drop/event_monitoring.js 257 // content/test/data/drag_and_drop/event_monitoring.js
168 class DOMDragEventWaiter { 258 class DOMDragEventWaiter {
169 public: 259 public:
170 explicit DOMDragEventWaiter(const std::string& event_type_to_wait_for, 260 explicit DOMDragEventWaiter(const std::string& event_type_to_wait_for,
171 const ToRenderFrameHost& target) 261 const content::ToRenderFrameHost& target)
172 : target_frame_name_(target.render_frame_host()->GetFrameName()), 262 : target_frame_name_(target.render_frame_host()->GetFrameName()),
173 event_type_to_wait_for_(event_type_to_wait_for), 263 event_type_to_wait_for_(event_type_to_wait_for),
174 dom_message_queue_( 264 dom_message_queue_(content::WebContents::FromRenderFrameHost(
175 WebContents::FromRenderFrameHost(target.render_frame_host())) {} 265 target.render_frame_host())) {}
176 266
177 // Waits until |target| calls reportDragEvent in 267 // Waits until |target| calls reportDragEvent in
178 // content/test/data/drag_and_drop/event_monitoring.js with event_type 268 // chrome/test/data/drag_and_drop/event_monitoring.js with event_type
179 // property set to |event_type_to_wait_for|. (|target| and 269 // property set to |event_type_to_wait_for|. (|target| and
180 // |event_type_to_wait_for| are passed to the constructor). 270 // |event_type_to_wait_for| are passed to the constructor).
181 // 271 //
182 // Returns the event details via |found_event| (in form of a JSON-encoded 272 // Returns the event details via |found_event| (in form of a JSON-encoded
183 // object). See content/test/data/drag_and_drop/event_monitoring.js for keys 273 // object). See chrome/test/data/drag_and_drop/event_monitoring.js for keys
184 // and properties that |found_event| is expected to have. 274 // and properties that |found_event| is expected to have.
185 // 275 //
186 // Returns true upon success. It is okay if |response| is null. 276 // Returns true upon success. It is okay if |response| is null.
187 bool WaitForNextMatchingEvent(std::string* found_event) WARN_UNUSED_RESULT { 277 bool WaitForNextMatchingEvent(std::string* found_event) WARN_UNUSED_RESULT {
188 std::string candidate_event; 278 std::string candidate_event;
189 bool got_right_event_type = false; 279 bool got_right_event_type = false;
190 bool got_right_window_name = false; 280 bool got_right_window_name = false;
191 do { 281 do {
192 if (!dom_message_queue_.WaitForMessage(&candidate_event)) 282 if (!dom_message_queue_.WaitForMessage(&candidate_event))
193 return false; 283 return false;
194 284
195 got_right_event_type = base::MatchPattern( 285 got_right_event_type = base::MatchPattern(
196 candidate_event, base::StringPrintf("*\"event_type\":\"%s\"*", 286 candidate_event, base::StringPrintf("*\"event_type\":\"%s\"*",
197 event_type_to_wait_for_.c_str())); 287 event_type_to_wait_for_.c_str()));
198 288
199 got_right_window_name = base::MatchPattern( 289 got_right_window_name = base::MatchPattern(
200 candidate_event, base::StringPrintf("*\"window_name\":\"%s\"*", 290 candidate_event, base::StringPrintf("*\"window_name\":\"%s\"*",
201 target_frame_name_.c_str())); 291 target_frame_name_.c_str()));
202 } while (!got_right_event_type || !got_right_window_name); 292 } while (!got_right_event_type || !got_right_window_name);
203 293
204 if (found_event) 294 if (found_event)
205 *found_event = candidate_event; 295 *found_event = candidate_event;
206 296
207 return true; 297 return true;
208 } 298 }
209 299
210 private: 300 private:
211 std::string target_frame_name_; 301 std::string target_frame_name_;
212 std::string event_type_to_wait_for_; 302 std::string event_type_to_wait_for_;
213 DOMMessageQueue dom_message_queue_; 303 content::DOMMessageQueue dom_message_queue_;
214 }; 304 };
215 305
216 const char kTestPagePath[] = "/drag_and_drop/page.html"; 306 const char kTestPagePath[] = "/drag_and_drop/page.html";
217 307
218 } // namespace 308 } // namespace
219 309
220 class DragAndDropBrowserTest : public ContentBrowserTest { 310 class DragAndDropBrowserTest : public InProcessBrowserTest {
221 public: 311 public:
222 DragAndDropBrowserTest(){}; 312 DragAndDropBrowserTest(){};
223 313
314 // Declarations of test continuations.
315 void DragStartInFrame_Step2(const std::string& frame_site,
316 const std::string& text,
317 const std::string& html,
318 int operation,
319 bool did_originate_from_renderer);
320
224 protected: 321 protected:
225 void SetUpOnMainThread() override { 322 void SetUpOnMainThread() override {
226 host_resolver()->AddRule("*", "127.0.0.1"); 323 host_resolver()->AddRule("*", "127.0.0.1");
227 ASSERT_TRUE(embedded_test_server()->Start()); 324 ASSERT_TRUE(embedded_test_server()->Start());
228 content::SetupCrossSiteRedirector(embedded_test_server()); 325 content::SetupCrossSiteRedirector(embedded_test_server());
229 drag_simulator_.reset(new DragAndDropSimulator(shell()->web_contents())); 326 drag_simulator_.reset(new DragAndDropSimulator(web_contents()));
230 } 327 }
231 328
232 // Navigates to content/test/data/drag_and_drop/page.html, with page origin 329 content::RenderFrameHost* left_frame() {
233 // and frame contents being controlled by the parameters. 330 AssertTestPageIsLoaded();
234 bool NavigateToTestPage(const std::string& main_origin, 331 return GetFrameByName("left");
235 const std::string& left_frame, 332 }
236 const std::string& right_frame) {
237 GURL base_url = embedded_test_server()->GetURL(main_origin, kTestPagePath);
238 333
239 std::string left_arg; 334 content::RenderFrameHost* right_frame() {
240 if (!left_frame.empty()) { 335 AssertTestPageIsLoaded();
241 left_arg = net::EscapeQueryParamValue( 336 return GetFrameByName("right");
242 std::string("/cross-site/") + left_frame, true); 337 }
243 }
244 std::string right_arg;
245 if (!right_frame.empty()) {
246 right_arg = net::EscapeQueryParamValue(
247 std::string("/cross-site/") + right_frame, true);
248 }
249 std::string query = base::StringPrintf("left=%s&right=%s", left_arg.c_str(),
250 right_arg.c_str());
251 GURL::Replacements query_replacement;
252 query_replacement.SetQueryStr(query);
253 GURL target_url = base_url.ReplaceComponents(query_replacement);
254 338
255 return NavigateToURL(shell(), target_url); 339 // Navigation helpers.
340
341 bool NavigateToTestPage(const std::string& origin_of_main_frame) {
342 GURL url =
343 embedded_test_server()->GetURL(origin_of_main_frame, kTestPagePath);
344 ui_test_utils::NavigateToURL(browser(), url);
345 return web_contents()->GetLastCommittedURL() == url;
256 } 346 }
257 347
348 // Navigates the left frame to |filename| (found under
349 // chrome/test/data/drag_and_drop directory).
350 bool NavigateLeftFrame(const std::string& origin,
351 const std::string& filename) {
352 AssertTestPageIsLoaded();
353 return NavigateNamedFrame("left", origin, filename);
354 }
355
356 // Navigates the right frame to |filename| (found under
357 // chrome/test/data/drag_and_drop directory).
358 bool NavigateRightFrame(const std::string& origin,
359 const std::string& filename) {
360 AssertTestPageIsLoaded();
361 return NavigateNamedFrame("right", origin, filename);
362 }
363
364 // Drag-and-drop simulation using the mouse.
365
366 bool SimulateMouseDownAndDragStartInLeftFrame() {
367 AssertTestPageIsLoaded();
368 if (!SimulateMouseMove(kMiddleOfLeftFrame) || !SimulateMouseDown() ||
369 !SimulateMouseMove(kMiddleOfLeftFrame + gfx::Vector2d(5, 5)))
370 return false;
371
372 return true;
373 }
374
375 bool SimulateMouseUp() {
376 return ui_test_utils::SendMouseEventsSync(ui_controls::LEFT,
377 ui_controls::UP);
378 }
379
380 // Drag-and-drop simulation via DragAndDropSimulator.
381
258 bool SimulateDragEnterToRightFrame(const std::string& text) { 382 bool SimulateDragEnterToRightFrame(const std::string& text) {
259 AssertTestPageIsLoaded(); 383 AssertTestPageIsLoaded();
260 return drag_simulator_->SimulateDragEnter(kMiddleOfRightFrame, text); 384 return drag_simulator_->SimulateDragEnter(kMiddleOfRightFrame, text);
261 } 385 }
262 386
263 bool SimulateDropInRightFrame() { 387 bool SimulateDropInRightFrame() {
264 AssertTestPageIsLoaded(); 388 AssertTestPageIsLoaded();
265 return drag_simulator_->SimulateDrop(kMiddleOfRightFrame); 389 return drag_simulator_->SimulateDrop(kMiddleOfRightFrame);
266 } 390 }
267 391
268 RenderFrameHost* right_frame() { 392 content::WebContents* web_contents() {
269 AssertTestPageIsLoaded(); 393 return browser()->tab_strip_model()->GetActiveWebContents();
270 return GetFrameByName("right");
271 } 394 }
272 395
273 private: 396 private:
274 RenderFrameHost* GetFrameByName(const std::string& name_to_find) { 397 bool SimulateMouseDown() {
275 WebContentsImpl* web_contents = 398 return ui_test_utils::SendMouseEventsSync(ui_controls::LEFT,
276 static_cast<WebContentsImpl*>(shell()->web_contents()); 399 ui_controls::DOWN);
277 FrameTree* frame_tree = web_contents->GetFrameTree(); 400 }
278 return frame_tree->FindByName(name_to_find)->current_frame_host(); 401
402 bool SimulateMouseMove(const gfx::Point& location_inside_web_contents) {
403 gfx::Rect bounds = web_contents()->GetContainerBounds();
404 return ui_test_utils::SendMouseMoveSync(
405 gfx::Point(bounds.x() + location_inside_web_contents.x(),
406 bounds.y() + location_inside_web_contents.y()));
407 }
408
409 bool NavigateNamedFrame(const std::string& frame_name,
410 const std::string& origin,
411 const std::string& filename) {
412 content::RenderFrameHost* frame = GetFrameByName(frame_name);
413 if (!frame)
414 return false;
415
416 std::string script;
417 int response = 0;
418
419 // Navigate the frame and wait for the load event.
420 script = base::StringPrintf(
421 "location.href = '/cross-site/%s/drag_and_drop/%s';\n"
422 "setTimeout(function() { domAutomationController.send(42); }, 0);",
423 origin.c_str(), filename.c_str());
424 content::TestFrameNavigationObserver observer(frame);
425 if (!content::ExecuteScriptAndExtractInt(frame, script, &response))
426 return false;
427 if (response != 42)
428 return false;
429 observer.Wait();
430
431 // Wait until frame contents (e.g. images) have painted (which should happen
432 // in the animation frame that *starts* after the onload event - therefore
433 // we need to wait for 2 animation frames).
434 script = std::string(
435 "requestAnimationFrame(function() {\n"
436 " requestAnimationFrame(function() {\n"
437 " domAutomationController.send(43);\n"
438 " });\n"
439 "});\n");
440 if (!content::ExecuteScriptAndExtractInt(frame, script, &response))
441 return false;
442 if (response != 43)
443 return false;
444
445 return true;
446 }
447
448 content::RenderFrameHost* GetFrameByName(const std::string& name_to_find) {
Łukasz Anforowicz 2016/11/10 19:26:24 content::FrameTree::FindByName is not exposed via
449 content::RenderFrameHost* result = nullptr;
450 for (content::RenderFrameHost* rfh : web_contents()->GetAllFrames()) {
451 if (rfh->GetFrameName() == name_to_find) {
452 if (result) {
453 ADD_FAILURE() << "More than one frame named "
454 << "'" << name_to_find << "'";
455 return nullptr;
456 }
457 result = rfh;
458 }
459 }
460
461 EXPECT_TRUE(result) << "Couldn't find a frame named "
462 << "'" << name_to_find << "'";
463 return result;
279 } 464 }
280 465
281 void AssertTestPageIsLoaded() { 466 void AssertTestPageIsLoaded() {
282 ASSERT_EQ(kTestPagePath, 467 ASSERT_EQ(kTestPagePath, web_contents()->GetLastCommittedURL().path());
283 shell()->web_contents()->GetLastCommittedURL().path());
284 } 468 }
285 469
286 std::unique_ptr<DragAndDropSimulator> drag_simulator_; 470 std::unique_ptr<DragAndDropSimulator> drag_simulator_;
287 471
288 // Constants with coordinates within content/test/data/drag_and_drop/page.html 472 // Constants with coordinates within content/test/data/drag_and_drop/page.html
289 const gfx::Point kMiddleOfLeftFrame = gfx::Point(200, 200); 473 const gfx::Point kMiddleOfLeftFrame = gfx::Point(200, 200);
290 const gfx::Point kMiddleOfRightFrame = gfx::Point(400, 200); 474 const gfx::Point kMiddleOfRightFrame = gfx::Point(400, 200);
291 475
292 DISALLOW_COPY_AND_ASSIGN(DragAndDropBrowserTest); 476 DISALLOW_COPY_AND_ASSIGN(DragAndDropBrowserTest);
293 }; 477 };
294 478
295 IN_PROC_BROWSER_TEST_F(DragAndDropBrowserTest, DropTextFromOutside) { 479 IN_PROC_BROWSER_TEST_F(DragAndDropBrowserTest, DropTextFromOutside) {
296 ASSERT_TRUE(NavigateToTestPage("a.com", 480 ASSERT_TRUE(NavigateToTestPage("a.com"));
297 "", // Left frame is unused by this test. 481 ASSERT_TRUE(NavigateRightFrame("b.com", "drop_target.html"));
298 "c.com/drag_and_drop/drop_target.html"));
299 482
483 // Drag text from outside the browser into/over the right frame.
300 { 484 {
301 std::string dragover_event;
302 DOMDragEventWaiter dragover_waiter("dragover", right_frame()); 485 DOMDragEventWaiter dragover_waiter("dragover", right_frame());
303 ASSERT_TRUE(SimulateDragEnterToRightFrame("Dragged test text")); 486 ASSERT_TRUE(SimulateDragEnterToRightFrame("Dragged test text"));
487
488 std::string dragover_event;
304 ASSERT_TRUE(dragover_waiter.WaitForNextMatchingEvent(&dragover_event)); 489 ASSERT_TRUE(dragover_waiter.WaitForNextMatchingEvent(&dragover_event));
305 EXPECT_THAT(dragover_event, testing::HasSubstr("\"drop_effect\":\"none\"")); 490 EXPECT_THAT(dragover_event, testing::HasSubstr("\"drop_effect\":\"none\""));
306 EXPECT_THAT(dragover_event, 491 EXPECT_THAT(dragover_event,
307 testing::HasSubstr("\"effect_allowed\":\"all\"")); 492 testing::HasSubstr("\"effect_allowed\":\"all\""));
308 EXPECT_THAT(dragover_event, 493 EXPECT_THAT(dragover_event,
309 testing::HasSubstr("\"mime_types\":\"text/plain\"")); 494 testing::HasSubstr("\"mime_types\":\"text/plain\""));
310 } 495 }
311 496
497 // Drop into the right frame.
312 { 498 {
313 std::string drop_event;
314 DOMDragEventWaiter drop_waiter("drop", right_frame()); 499 DOMDragEventWaiter drop_waiter("drop", right_frame());
315 ASSERT_TRUE(SimulateDropInRightFrame()); 500 ASSERT_TRUE(SimulateDropInRightFrame());
501
502 std::string drop_event;
316 ASSERT_TRUE(drop_waiter.WaitForNextMatchingEvent(&drop_event)); 503 ASSERT_TRUE(drop_waiter.WaitForNextMatchingEvent(&drop_event));
317 EXPECT_THAT(drop_event, testing::HasSubstr("\"drop_effect\":\"none\"")); 504 EXPECT_THAT(drop_event, testing::HasSubstr("\"drop_effect\":\"none\""));
318 EXPECT_THAT(drop_event, testing::HasSubstr("\"effect_allowed\":\"all\"")); 505 EXPECT_THAT(drop_event, testing::HasSubstr("\"effect_allowed\":\"all\""));
319 EXPECT_THAT(drop_event, 506 EXPECT_THAT(drop_event,
320 testing::HasSubstr("\"mime_types\":\"text/plain\"")); 507 testing::HasSubstr("\"mime_types\":\"text/plain\""));
321 } 508 }
322 } 509 }
323 510
511 IN_PROC_BROWSER_TEST_F(DragAndDropBrowserTest, DragStartInFrame) {
512 std::string frame_site = "b.com";
513 ASSERT_TRUE(NavigateToTestPage("a.com"));
514 ASSERT_TRUE(NavigateLeftFrame(frame_site, "image_source.html"));
515
516 // Start the drag in the left frame.
517 DragStartWaiter drag_start_waiter(
518 web_contents(),
519 base::Bind(&DragAndDropBrowserTest::DragStartInFrame_Step2,
520 base::Unretained(this), frame_site));
521 DOMDragEventWaiter dragstart_event_waiter("dragstart", left_frame());
522 ASSERT_TRUE(SimulateMouseDownAndDragStartInLeftFrame());
523
524 // Verify Javascript event data.
525 std::string dragstart_event;
526 ASSERT_TRUE(
527 dragstart_event_waiter.WaitForNextMatchingEvent(&dragstart_event));
528 EXPECT_THAT(dragstart_event, testing::HasSubstr("\"drop_effect\":\"none\""));
529 // |effect_allowed| is intialized *inside* dragstart event handler - no
530 // point in verifying this value here (this would be tautological).
531 EXPECT_THAT(
532 dragstart_event,
533 testing::HasSubstr("\"mime_types\":\"Files,text/html,text/uri-list\""));
534
535 // Run the nested drag-and-drop loop
536 // (test will continue in DragStartInFrame_Step2).
537 drag_start_waiter.WaitUntilFullDragAndDropCompletes();
538 }
539
540 void DragAndDropBrowserTest::DragStartInFrame_Step2(
541 const std::string& frame_site,
542 const std::string& text,
543 const std::string& html,
544 int operation,
545 bool did_originate_from_renderer) {
546 EXPECT_EQ(
547 embedded_test_server()->GetURL(frame_site, "/image_decoding/droids.jpg"),
548 text);
549 EXPECT_THAT(html,
550 testing::MatchesRegex("<img .*src=\""
551 "http://.*:.*/image_decoding/droids.jpg"
552 "\">"));
553 EXPECT_TRUE(did_originate_from_renderer);
554
555 // dragstart event handler in image_source.html is asking for "copy" only.
556 EXPECT_EQ(ui::DragDropTypes::DRAG_COPY, operation);
557
558 // This will exit the nested drag-and-drag loop.
559 ASSERT_TRUE(SimulateMouseUp());
560 }
561
324 } // namespace chrome 562 } // namespace chrome
OLDNEW
« no previous file with comments | « no previous file | chrome/test/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698