1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "apps/shell_window.h" 6 #include "apps/shell_window_registry.h" 7 #include "base/strings/stringprintf.h" 8 #include "base/strings/utf_string_conversions.h" 9 #include "chrome/browser/apps/app_browsertest_util.h" 10 #include "chrome/browser/extensions/extension_test_message_listener.h" 11 #include "chrome/browser/profiles/profile.h" 12 #include "chrome/test/base/interactive_test_utils.h" 13 #include "chrome/test/base/test_launcher_utils.h" 14 #include "chrome/test/base/ui_test_utils.h" 15 #include "content/public/browser/notification_service.h" 16 #include "content/public/browser/render_process_host.h" 17 #include "content/public/browser/render_view_host.h" 18 #include "content/public/browser/render_widget_host_view.h" 19 #include "content/public/browser/web_contents.h" 20 #include "content/public/browser/web_contents_view.h" 21 #include "content/public/common/content_switches.h" 22 #include "content/public/test/browser_test_utils.h" 23 #include "net/test/embedded_test_server/embedded_test_server.h" 24 #include "ui/base/test/ui_controls.h" 25 #include "ui/events/keycodes/keyboard_codes.h" 26 27 using apps::ShellWindow; 28 29 class WebViewInteractiveTest 30 : public extensions::PlatformAppBrowserTest { 31 public: 32 WebViewInteractiveTest() 33 : corner_(gfx::Point()), 34 mouse_click_result_(false), 35 first_click_(true) {} 36 37 virtual void SetUp() OVERRIDE { 38 // We need real contexts, otherwise the embedder doesn't composite, but the 39 // guest does, and that isn't an expected configuration. 40 UseRealGLContexts(); 41 extensions::PlatformAppBrowserTest::SetUp(); 42 } 43 44 void MoveMouseInsideWindowWithListener(gfx::Point point, 45 const std::string& message) { 46 ExtensionTestMessageListener move_listener(message, false); 47 ASSERT_TRUE(ui_test_utils::SendMouseMoveSync( 48 gfx::Point(corner_.x() + point.x(), corner_.y() + point.y()))); 49 ASSERT_TRUE(move_listener.WaitUntilSatisfied()); 50 } 51 52 void SendMouseClickWithListener(ui_controls::MouseButton button, 53 const std::string& message) { 54 ExtensionTestMessageListener listener(message, false); 55 SendMouseClick(button); 56 ASSERT_TRUE(listener.WaitUntilSatisfied()); 57 } 58 59 void SendMouseClick(ui_controls::MouseButton button) { 60 SendMouseEvent(button, ui_controls::DOWN); 61 SendMouseEvent(button, ui_controls::UP); 62 } 63 64 void MoveMouseInsideWindow(const gfx::Point& point) { 65 ASSERT_TRUE(ui_test_utils::SendMouseMoveSync( 66 gfx::Point(corner_.x() + point.x(), corner_.y() + point.y()))); 67 } 68 69 gfx::NativeWindow GetPlatformAppWindow() { 70 const apps::ShellWindowRegistry::ShellWindowList& shell_windows = 71 apps::ShellWindowRegistry::Get( 72 browser()->profile())->shell_windows(); 73 return (*shell_windows.begin())->GetNativeWindow(); 74 } 75 76 void SendKeyPressToPlatformApp(ui::KeyboardCode key) { 77 ASSERT_EQ(1U, GetShellWindowCount()); 78 ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync( 79 GetPlatformAppWindow(), key, false, false, false, false)); 80 } 81 82 void SendCopyKeyPressToPlatformApp() { 83 ASSERT_EQ(1U, GetShellWindowCount()); 84 #if defined(OS_MACOSX) 85 // Send Cmd+C on MacOSX. 86 ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync( 87 GetPlatformAppWindow(), ui::VKEY_C, false, false, false, true)); 88 #else 89 // Send Ctrl+C on Windows and Linux/ChromeOS. 90 ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync( 91 GetPlatformAppWindow(), ui::VKEY_C, true, false, false, false)); 92 #endif 93 } 94 95 void SendStartOfLineKeyPressToPlatformApp() { 96 #if defined(OS_MACOSX) 97 // Send Cmd+Left on MacOSX. 98 ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync( 99 GetPlatformAppWindow(), ui::VKEY_LEFT, false, false, false, true)); 100 #else 101 // Send Ctrl+Left on Windows and Linux/ChromeOS. 102 ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync( 103 GetPlatformAppWindow(), ui::VKEY_LEFT, true, false, false, false)); 104 #endif 105 } 106 107 void SendBackShortcutToPlatformApp() { 108 #if defined(OS_MACOSX) 109 // Send Cmd+[ on MacOSX. 110 ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync( 111 GetPlatformAppWindow(), ui::VKEY_OEM_4, false, false, false, true)); 112 #else 113 // Send browser back key on Linux/Windows. 114 ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync( 115 GetPlatformAppWindow(), ui::VKEY_BROWSER_BACK, 116 false, false, false, false)); 117 #endif 118 } 119 120 void SendForwardShortcutToPlatformApp() { 121 #if defined(OS_MACOSX) 122 // Send Cmd+] on MacOSX. 123 ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync( 124 GetPlatformAppWindow(), ui::VKEY_OEM_6, false, false, false, true)); 125 #else 126 // Send browser back key on Linux/Windows. 127 ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync( 128 GetPlatformAppWindow(), ui::VKEY_BROWSER_FORWARD, 129 false, false, false, false)); 130 #endif 131 } 132 133 void SendMouseEvent(ui_controls::MouseButton button, 134 ui_controls::MouseButtonState state) { 135 if (first_click_) { 136 mouse_click_result_ = ui_test_utils::SendMouseEventsSync(button, 137 state); 138 first_click_ = false; 139 } else { 140 ASSERT_EQ(mouse_click_result_, ui_test_utils::SendMouseEventsSync( 141 button, state)); 142 } 143 } 144 145 enum TestServer { 146 NEEDS_TEST_SERVER, 147 NO_TEST_SERVER 148 }; 149 150 scoped_ptr<ExtensionTestMessageListener> RunAppHelper( 151 const std::string& test_name, 152 const std::string& app_location, 153 TestServer test_server, 154 content::WebContents** embedder_web_contents) { 155 // For serving guest pages. 156 if ((test_server == NEEDS_TEST_SERVER) && !StartEmbeddedTestServer()) { 157 LOG(ERROR) << "FAILED TO START TEST SERVER."; 158 return scoped_ptr<ExtensionTestMessageListener>(); 159 } 160 161 ExtensionTestMessageListener launched_listener("Launched", false); 162 LoadAndLaunchPlatformApp(app_location.c_str()); 163 if (!launched_listener.WaitUntilSatisfied()) { 164 LOG(ERROR) << "TEST DID NOT LAUNCH."; 165 return scoped_ptr<ExtensionTestMessageListener>(); 166 } 167 168 if (!ui_test_utils::ShowAndFocusNativeWindow(GetPlatformAppWindow())) { 169 LOG(ERROR) << "UNABLE TO FOCUS TEST WINDOW."; 170 return scoped_ptr<ExtensionTestMessageListener>(); 171 } 172 173 // Flush any pending events to make sure we start with a clean slate. 174 content::RunAllPendingInMessageLoop(); 175 176 *embedder_web_contents = GetFirstShellWindowWebContents(); 177 178 scoped_ptr<ExtensionTestMessageListener> done_listener( 179 new ExtensionTestMessageListener("TEST_PASSED", false)); 180 done_listener->AlsoListenForFailureMessage("TEST_FAILED"); 181 if (!content::ExecuteScript( 182 *embedder_web_contents, 183 base::StringPrintf("runTest('%s')", test_name.c_str()))) { 184 LOG(ERROR) << "UNABLE TO START TEST"; 185 return scoped_ptr<ExtensionTestMessageListener>(); 186 } 187 188 return done_listener.Pass(); 189 } 190 191 void TestHelper(const std::string& test_name, 192 const std::string& app_location, 193 TestServer test_server) { 194 content::WebContents* embedder_web_contents = NULL; 195 scoped_ptr<ExtensionTestMessageListener> done_listener( 196 RunAppHelper( 197 test_name, app_location, test_server, &embedder_web_contents)); 198 199 ASSERT_TRUE(done_listener); 200 ASSERT_TRUE(done_listener->WaitUntilSatisfied()); 201 } 202 203 void RunTest(const std::string& app_name) { 204 } 205 void SetupTest(const std::string& app_name, 206 const std::string& guest_url_spec) { 207 ASSERT_TRUE(StartEmbeddedTestServer()); 208 GURL::Replacements replace_host; 209 std::string host_str("localhost"); // Must stay in scope with replace_host. 210 replace_host.SetHostStr(host_str); 211 212 GURL guest_url = embedded_test_server()->GetURL(guest_url_spec); 213 guest_url = guest_url.ReplaceComponents(replace_host); 214 215 ui_test_utils::UrlLoadObserver guest_observer( 216 guest_url, content::NotificationService::AllSources()); 217 218 ExtensionTestMessageListener guest_connected_listener("connected", false); 219 LoadAndLaunchPlatformApp(app_name.c_str()); 220 221 guest_observer.Wait(); 222 223 // Wait until the guest process reports that it has established a message 224 // channel with the app. 225 ASSERT_TRUE(guest_connected_listener.WaitUntilSatisfied()); 226 content::Source<content::NavigationController> source = 227 guest_observer.source(); 228 EXPECT_TRUE(source->GetWebContents()->GetRenderProcessHost()->IsGuest()); 229 230 guest_web_contents_ = source->GetWebContents(); 231 embedder_web_contents_ = guest_web_contents_->GetEmbedderWebContents(); 232 233 gfx::Rect offset; 234 embedder_web_contents_->GetView()->GetContainerBounds(&offset); 235 corner_ = gfx::Point(offset.x(), offset.y()); 236 237 const testing::TestInfo* const test_info = 238 testing::UnitTest::GetInstance()->current_test_info(); 239 const char* prefix = "DragDropWithinWebView"; 240 if (!strncmp(test_info->name(), prefix, strlen(prefix))) { 241 // In the drag drop test we add 20px padding to the page body because on 242 // windows if we get too close to the edge of the window the resize cursor 243 // appears and we start dragging the window edge. 244 corner_.Offset(20, 20); 245 } 246 } 247 248 content::WebContents* guest_web_contents() { 249 return guest_web_contents_; 250 } 251 252 content::WebContents* embedder_web_contents() { 253 return embedder_web_contents_; 254 } 255 256 gfx::Point corner() { 257 return corner_; 258 } 259 260 void SimulateRWHMouseClick(content::RenderWidgetHost* rwh, int x, int y) { 261 blink::WebMouseEvent mouse_event; 262 mouse_event.button = blink::WebMouseEvent::ButtonLeft; 263 mouse_event.x = mouse_event.windowX = x; 264 mouse_event.y = mouse_event.windowY = y; 265 mouse_event.modifiers = 0; 266 267 mouse_event.type = blink::WebInputEvent::MouseDown; 268 rwh->ForwardMouseEvent(mouse_event); 269 mouse_event.type = blink::WebInputEvent::MouseUp; 270 rwh->ForwardMouseEvent(mouse_event); 271 } 272 273 // TODO(lazyboy): implement 274 class PopupCreatedObserver { 275 public: 276 PopupCreatedObserver() : created_(false), last_render_widget_host_(NULL) { 277 } 278 virtual ~PopupCreatedObserver() { 279 } 280 void Reset() { 281 created_ = false; 282 } 283 void Start() { 284 if (created_) 285 return; 286 message_loop_ = new content::MessageLoopRunner; 287 message_loop_->Run(); 288 } 289 content::RenderWidgetHost* last_render_widget_host() { 290 return last_render_widget_host_; 291 } 292 293 private: 294 scoped_refptr<content::MessageLoopRunner> message_loop_; 295 bool created_; 296 content::RenderWidgetHost* last_render_widget_host_; 297 }; 298 299 void WaitForTitle(const char* title) { 300 base::string16 expected_title(ASCIIToUTF16(title)); 301 base::string16 error_title(ASCIIToUTF16("FAILED")); 302 content::TitleWatcher title_watcher(guest_web_contents(), expected_title); 303 title_watcher.AlsoWaitForTitle(error_title); 304 ASSERT_EQ(expected_title, title_watcher.WaitAndGetTitle()); 305 } 306 307 void PopupTestHelper(const gfx::Point& padding) { 308 PopupCreatedObserver popup_created_observer; 309 popup_created_observer.Reset(); 310 311 content::SimulateKeyPress( 312 guest_web_contents(), 313 ui::VKEY_C, // C to autocomplete. 314 false, false, false, false); 315 316 WaitForTitle("PASSED1"); 317 318 popup_created_observer.Start(); 319 320 content::RenderWidgetHost* popup_rwh = NULL; 321 popup_rwh = popup_created_observer.last_render_widget_host(); 322 // Popup must be present. 323 ASSERT_TRUE(popup_rwh); 324 ASSERT_TRUE(!popup_rwh->IsRenderView()); 325 ASSERT_TRUE(popup_rwh->GetView()); 326 327 base::string16 expected_title = ASCIIToUTF16("PASSED2"); 328 base::string16 error_title = ASCIIToUTF16("FAILED"); 329 content::TitleWatcher title_watcher(guest_web_contents(), expected_title); 330 title_watcher.AlsoWaitForTitle(error_title); 331 EXPECT_TRUE(content::ExecuteScript(guest_web_contents(), 332 "changeTitle();")); 333 ASSERT_EQ(expected_title, title_watcher.WaitAndGetTitle()); 334 335 gfx::Rect popup_bounds = popup_rwh->GetView()->GetViewBounds(); 336 // (2, 2) is expected to lie on the first datalist element. 337 SimulateRWHMouseClick(popup_rwh, 2, 2); 338 339 content::RenderViewHost* embedder_rvh = 340 GetFirstShellWindowWebContents()->GetRenderViewHost(); 341 gfx::Rect embedder_bounds = embedder_rvh->GetView()->GetViewBounds(); 342 gfx::Vector2d diff = popup_bounds.origin() - embedder_bounds.origin(); 343 LOG(INFO) << "DIFF: x = " << diff.x() << ", y = " << diff.y(); 344 345 const int left_spacing = 40 + padding.x(); // div.style.paddingLeft = 40px. 346 // div.style.paddingTop = 50px + (input box height = 26px). 347 const int top_spacing = 50 + 26 + padding.y(); 348 349 // If the popup is placed within |threshold_px| of the expected position, 350 // then we consider the test as a pass. 351 const int threshold_px = 10; 352 353 EXPECT_LE(std::abs(diff.x() - left_spacing), threshold_px); 354 EXPECT_LE(std::abs(diff.y() - top_spacing), threshold_px); 355 356 WaitForTitle("PASSED3"); 357 } 358 359 void DragTestStep1() { 360 // Move mouse to start of text. 361 MoveMouseInsideWindow(gfx::Point(45, 8)); 362 MoveMouseInsideWindow(gfx::Point(45, 9)); 363 SendMouseEvent(ui_controls::LEFT, ui_controls::DOWN); 364 365 MoveMouseInsideWindow(gfx::Point(74, 12)); 366 MoveMouseInsideWindow(gfx::Point(78, 12)); 367 368 // Now wait a bit before moving mouse to initiate drag/drop. 369 base::MessageLoop::current()->PostDelayedTask( 370 FROM_HERE, 371 base::Bind(&WebViewInteractiveTest::DragTestStep2, 372 base::Unretained(this)), 373 base::TimeDelta::FromMilliseconds(200)); 374 } 375 376 void DragTestStep2() { 377 // Drag source over target. 378 MoveMouseInsideWindow(gfx::Point(76, 76)); 379 380 // Create a second mouse over the source to trigger the drag over event. 381 MoveMouseInsideWindow(gfx::Point(76, 77)); 382 383 // Release mouse to drop. 384 SendMouseEvent(ui_controls::LEFT, ui_controls::UP); 385 SendMouseClick(ui_controls::LEFT); 386 387 quit_closure_.Run(); 388 389 // Note that following ExtensionTestMessageListener and ExecuteScript* 390 // call must be after we quit |quit_closure_|. Otherwise the class 391 // here won't be able to receive messages sent by chrome.test.sendMessage. 392 // This is because of the nature of drag and drop code (esp. the 393 // MessageLoop) in it. 394 395 // Now check if we got a drop and read the drop data. 396 embedder_web_contents_ = GetFirstShellWindowWebContents(); 397 ExtensionTestMessageListener drop_listener("guest-got-drop", false); 398 EXPECT_TRUE(content::ExecuteScript(embedder_web_contents_, 399 "window.checkIfGuestGotDrop()")); 400 EXPECT_TRUE(drop_listener.WaitUntilSatisfied()); 401 402 std::string last_drop_data; 403 EXPECT_TRUE(content::ExecuteScriptAndExtractString( 404 embedder_web_contents_, 405 "window.domAutomationController.send(getLastDropData())", 406 &last_drop_data)); 407 408 last_drop_data_ = last_drop_data; 409 } 410 411 protected: 412 content::WebContents* guest_web_contents_; 413 content::WebContents* embedder_web_contents_; 414 gfx::Point corner_; 415 bool mouse_click_result_; 416 bool first_click_; 417 // Only used in drag/drop test. 418 base::Closure quit_closure_; 419 std::string last_drop_data_; 420 }; 421 422 // ui_test_utils::SendMouseMoveSync doesn't seem to work on OS_MACOSX, and 423 // likely won't work on many other platforms as well, so for now this test 424 // is for Windows and Linux only. As of Sept 17th, 2013 this test is disabled 425 // on Windows due to flakines, see http://crbug.com/293445. 426 427 #if defined(OS_LINUX) 428 429 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, PointerLock) { 430 SetupTest("web_view/pointer_lock", 431 "/extensions/platform_apps/web_view/pointer_lock/guest.html"); 432 433 // Move the mouse over the Lock Pointer button. 434 ASSERT_TRUE(ui_test_utils::SendMouseMoveSync( 435 gfx::Point(corner().x() + 75, corner().y() + 25))); 436 437 // Click the Lock Pointer button. The first two times the button is clicked 438 // the permission API will deny the request (intentional). 439 ExtensionTestMessageListener exception_listener("request exception", false); 440 SendMouseClickWithListener(ui_controls::LEFT, "lock error"); 441 ASSERT_TRUE(exception_listener.WaitUntilSatisfied()); 442 SendMouseClickWithListener(ui_controls::LEFT, "lock error"); 443 444 // Click the Lock Pointer button, locking the mouse to lockTarget1. 445 SendMouseClickWithListener(ui_controls::LEFT, "locked"); 446 447 // Attempt to move the mouse off of the lock target, and onto lockTarget2, 448 // (which would trigger a test failure). 449 ASSERT_TRUE(ui_test_utils::SendMouseMoveSync( 450 gfx::Point(corner().x() + 74, corner().y() + 74))); 451 MoveMouseInsideWindowWithListener(gfx::Point(75, 75), "mouse-move"); 452 453 #if (defined(OS_WIN) && defined(USE_AURA)) 454 // When the mouse is unlocked on win aura, sending a test mouse click clicks 455 // where the mouse moved to while locked. I was unable to figure out why, and 456 // since the issue only occurs with the test mouse events, just fix it with 457 // a simple workaround - moving the mouse back to where it should be. 458 // TODO(mthiesse): Fix Win Aura simulated mouse events while mouse locked. 459 MoveMouseInsideWindowWithListener(gfx::Point(75, 25), "mouse-move"); 460 #endif 461 462 ExtensionTestMessageListener unlocked_listener("unlocked", false); 463 // Send a key press to unlock the mouse. 464 SendKeyPressToPlatformApp(ui::VKEY_ESCAPE); 465 466 // Wait for page to receive (successful) mouse unlock response. 467 ASSERT_TRUE(unlocked_listener.WaitUntilSatisfied()); 468 469 // After the second lock, guest.js sends a message to main.js to remove the 470 // webview object. main.js then removes the div containing the webview, which 471 // should unlock, and leave the mouse over the mousemove-capture-container 472 // div. We then move the mouse over that div to ensure the mouse was properly 473 // unlocked and that the div receieves the message. 474 ExtensionTestMessageListener move_captured_listener("move-captured", false); 475 move_captured_listener.AlsoListenForFailureMessage("timeout"); 476 477 // Mouse should already be over lock button (since we just unlocked), so send 478 // click to re-lock the mouse. 479 SendMouseClickWithListener(ui_controls::LEFT, "deleted"); 480 481 // A mousemove event is triggered on the mousemove-capture-container element 482 // when we delete the webview container (since the mouse moves onto the 483 // element), but just in case, send an explicit mouse movement to be safe. 484 ASSERT_TRUE(ui_test_utils::SendMouseMoveSync( 485 gfx::Point(corner().x() + 50, corner().y() + 10))); 486 487 // Wait for page to receive second (successful) mouselock response. 488 bool success = move_captured_listener.WaitUntilSatisfied(); 489 if (!success) { 490 fprintf(stderr, "TIMEOUT - retrying\n"); 491 // About 1 in 40 tests fail to detect mouse moves at this point (why?). 492 // Sending a right click seems to fix this (why?). 493 ExtensionTestMessageListener move_listener2("move-captured", false); 494 SendMouseClick(ui_controls::RIGHT); 495 ASSERT_TRUE(ui_test_utils::SendMouseMoveSync( 496 gfx::Point(corner().x() + 51, corner().y() + 11))); 497 ASSERT_TRUE(move_listener2.WaitUntilSatisfied()); 498 } 499 } 500 501 #endif // (defined(OS_WIN) || defined(OS_LINUX)) 502 503 // Tests that setting focus on the <webview> sets focus on the guest. 504 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, Focus_FocusEvent) { 505 TestHelper("testFocusEvent", "web_view/focus", NO_TEST_SERVER); 506 } 507 508 // Tests that setting focus on the <webview> sets focus on the guest. 509 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, Focus_BlurEvent) { 510 TestHelper("testBlurEvent", "web_view/focus", NO_TEST_SERVER); 511 } 512 513 // Tests that guests receive edit commands and respond appropriately. 514 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, EditCommands) { 515 ExtensionTestMessageListener guest_connected_listener("connected", false); 516 LoadAndLaunchPlatformApp("web_view/edit_commands"); 517 // Wait until the guest process reports that it has established a message 518 // channel with the app. 519 ASSERT_TRUE(guest_connected_listener.WaitUntilSatisfied()); 520 521 ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow( 522 GetPlatformAppWindow())); 523 524 // Flush any pending events to make sure we start with a clean slate. 525 content::RunAllPendingInMessageLoop(); 526 527 ExtensionTestMessageListener copy_listener("copy", false); 528 SendCopyKeyPressToPlatformApp(); 529 530 // Wait for the guest to receive a 'copy' edit command. 531 ASSERT_TRUE(copy_listener.WaitUntilSatisfied()); 532 } 533 534 // Tests that guests receive edit commands and respond appropriately. 535 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, EditCommandsNoMenu) { 536 SetupTest("web_view/edit_commands_no_menu", 537 "/extensions/platform_apps/web_view/edit_commands_no_menu/" 538 "guest.html"); 539 540 ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow( 541 GetPlatformAppWindow())); 542 543 // Flush any pending events to make sure we start with a clean slate. 544 content::RunAllPendingInMessageLoop(); 545 546 ExtensionTestMessageListener start_of_line_listener("StartOfLine", false); 547 SendStartOfLineKeyPressToPlatformApp(); 548 // Wait for the guest to receive a 'copy' edit command. 549 ASSERT_TRUE(start_of_line_listener.WaitUntilSatisfied()); 550 } 551 552 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, 553 NewWindow_NewWindowNameTakesPrecedence) { 554 TestHelper("testNewWindowNameTakesPrecedence", 555 "web_view/newwindow", 556 NEEDS_TEST_SERVER); 557 } 558 559 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, 560 NewWindow_WebViewNameTakesPrecedence) { 561 TestHelper("testWebViewNameTakesPrecedence", 562 "web_view/newwindow", 563 NEEDS_TEST_SERVER); 564 } 565 566 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, NewWindow_NoName) { 567 TestHelper("testNoName", 568 "web_view/newwindow", 569 NEEDS_TEST_SERVER); 570 } 571 572 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, NewWindow_Redirect) { 573 TestHelper("testNewWindowRedirect", 574 "web_view/newwindow", 575 NEEDS_TEST_SERVER); 576 } 577 578 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, NewWindow_Close) { 579 TestHelper("testNewWindowClose", 580 "web_view/newwindow", 581 NEEDS_TEST_SERVER); 582 } 583 584 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, NewWindow_ExecuteScript) { 585 TestHelper("testNewWindowExecuteScript", 586 "web_view/newwindow", 587 NEEDS_TEST_SERVER); 588 } 589 590 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, 591 NewWindow_DeclarativeWebRequest) { 592 TestHelper("testNewWindowDeclarativeWebRequest", 593 "web_view/newwindow", 594 NEEDS_TEST_SERVER); 595 } 596 597 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, NewWindow_WebRequest) { 598 TestHelper("testNewWindowWebRequest", 599 "web_view/newwindow", 600 NEEDS_TEST_SERVER); 601 } 602 603 // A custom elements bug needs to be addressed to enable this test: 604 // See http://crbug.com/282477 for more information. 605 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, 606 DISABLED_NewWindow_WebRequestCloseWindow) { 607 TestHelper("testNewWindowWebRequestCloseWindow", 608 "web_view/newwindow", 609 NEEDS_TEST_SERVER); 610 } 611 612 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, 613 NewWindow_WebRequestRemoveElement) { 614 TestHelper("testNewWindowWebRequestRemoveElement", 615 "web_view/newwindow", 616 NEEDS_TEST_SERVER); 617 } 618 619 // Tests that Ctrl+Click/Cmd+Click on a link fires up the newwindow API. 620 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, NewWindow_OpenInNewTab) { 621 content::WebContents* embedder_web_contents = NULL; 622 623 ExtensionTestMessageListener loaded_listener("Loaded", false); 624 scoped_ptr<ExtensionTestMessageListener> done_listener( 625 RunAppHelper("testNewWindowOpenInNewTab", 626 "web_view/newwindow", 627 NEEDS_TEST_SERVER, 628 &embedder_web_contents)); 629 630 loaded_listener.WaitUntilSatisfied(); 631 #if defined(OS_MACOSX) 632 ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync( 633 GetPlatformAppWindow(), ui::VKEY_RETURN, 634 false, false, false, true /* cmd */)); 635 #else 636 ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync( 637 GetPlatformAppWindow(), ui::VKEY_RETURN, 638 true /* ctrl */, false, false, false)); 639 #endif 640 641 // Wait for the embedder to receive a 'newwindow' event. 642 ASSERT_TRUE(done_listener->WaitUntilSatisfied()); 643 } 644 645 646 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, ExecuteCode) { 647 ASSERT_TRUE(RunPlatformAppTestWithArg( 648 "platform_apps/web_view/common", "execute_code")) << message_; 649 } 650 651 // This test used the old Autofill UI, which has been removed. 652 // See crbug.com/259438 653 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, DISABLED_PopupPositioning) { 654 SetupTest( 655 "web_view/popup_positioning", 656 "/extensions/platform_apps/web_view/popup_positioning/guest.html"); 657 ASSERT_TRUE(guest_web_contents()); 658 659 PopupTestHelper(gfx::Point()); 660 661 // moveTo a random location and run the steps again. 662 EXPECT_TRUE(content::ExecuteScript(embedder_web_contents(), 663 "window.moveTo(16, 20);")); 664 PopupTestHelper(gfx::Point()); 665 } 666 667 // Tests that moving browser plugin (without resize/UpdateRects) correctly 668 // repositions popup. 669 // Started flakily failing after a Blink roll: http://crbug.com/245332 670 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, DISABLED_PopupPositioningMoved) { 671 SetupTest( 672 "web_view/popup_positioning_moved", 673 "/extensions/platform_apps/web_view/popup_positioning_moved" 674 "/guest.html"); 675 ASSERT_TRUE(guest_web_contents()); 676 677 PopupTestHelper(gfx::Point(20, 0)); 678 } 679 680 // Drag and drop inside a webview is currently only enabled for linux and mac, 681 // but the tests don't work on anything except chromeos for now. This is because 682 // of simulating mouse drag code's dependency on platforms. 683 #if defined(OS_CHROMEOS) 684 // This test is flaky. See crbug.com/309032 685 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, DISABLED_DragDropWithinWebView) { 686 ExtensionTestMessageListener guest_connected_listener("connected", false); 687 LoadAndLaunchPlatformApp("web_view/dnd_within_webview"); 688 ASSERT_TRUE(guest_connected_listener.WaitUntilSatisfied()); 689 690 ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(GetPlatformAppWindow())); 691 692 gfx::Rect offset; 693 embedder_web_contents_ = GetFirstShellWindowWebContents(); 694 embedder_web_contents_->GetView()->GetContainerBounds(&offset); 695 corner_ = gfx::Point(offset.x(), offset.y()); 696 697 // In the drag drop test we add 20px padding to the page body because on 698 // windows if we get too close to the edge of the window the resize cursor 699 // appears and we start dragging the window edge. 700 corner_.Offset(20, 20); 701 702 // Flush any pending events to make sure we start with a clean slate. 703 content::RunAllPendingInMessageLoop(); 704 for (;;) { 705 base::RunLoop run_loop; 706 quit_closure_ = run_loop.QuitClosure(); 707 base::MessageLoop::current()->PostTask( 708 FROM_HERE, 709 base::Bind(&WebViewInteractiveTest::DragTestStep1, 710 base::Unretained(this))); 711 run_loop.Run(); 712 713 if (last_drop_data_ == "Drop me") 714 break; 715 716 LOG(INFO) << "Drag was cancelled in interactive_test, restarting drag"; 717 718 // Reset state for next try. 719 ExtensionTestMessageListener reset_listener("resetStateReply", false); 720 EXPECT_TRUE(content::ExecuteScript(embedder_web_contents_, 721 "window.resetState()")); 722 ASSERT_TRUE(reset_listener.WaitUntilSatisfied()); 723 } 724 ASSERT_EQ("Drop me", last_drop_data_); 725 } 726 #endif // (defined(OS_CHROMEOS)) 727 728 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, Navigation) { 729 TestHelper("testNavigation", "web_view/navigation", NO_TEST_SERVER); 730 } 731 732 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, Navigation_BackForwardKeys) { 733 ExtensionTestMessageListener launched_listener("Launched", false); 734 LoadAndLaunchPlatformApp("web_view/navigation"); 735 ASSERT_TRUE(launched_listener.WaitUntilSatisfied()); 736 737 ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow( 738 GetPlatformAppWindow())); 739 // Flush any pending events to make sure we start with a clean slate. 740 content::RunAllPendingInMessageLoop(); 741 742 content::WebContents* embedder_web_contents = 743 GetFirstShellWindowWebContents(); 744 ASSERT_TRUE(embedder_web_contents); 745 746 ExtensionTestMessageListener done_listener( 747 "TEST_PASSED", false); 748 done_listener.AlsoListenForFailureMessage("TEST_FAILED"); 749 ExtensionTestMessageListener ready_back_key_listener( 750 "ReadyForBackKey", false); 751 ExtensionTestMessageListener ready_forward_key_listener( 752 "ReadyForForwardKey", false); 753 754 EXPECT_TRUE(content::ExecuteScript( 755 embedder_web_contents, 756 "runTest('testBackForwardKeys')")); 757 758 ASSERT_TRUE(ready_back_key_listener.WaitUntilSatisfied()); 759 SendBackShortcutToPlatformApp(); 760 761 ASSERT_TRUE(ready_forward_key_listener.WaitUntilSatisfied()); 762 SendForwardShortcutToPlatformApp(); 763 764 ASSERT_TRUE(done_listener.WaitUntilSatisfied()); 765 } 766 767 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, 768 PointerLock_PointerLockLostWithFocus) { 769 TestHelper("testPointerLockLostWithFocus", 770 "web_view/pointerlock", 771 NO_TEST_SERVER); 772 } 773