Home | History | Annotate | Download | only in apps
      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