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/app_window.h"
      6 #include "apps/app_window_registry.h"
      7 #include "base/strings/stringprintf.h"
      8 #include "base/strings/utf_string_conversions.h"
      9 #include "chrome/app/chrome_command_ids.h"
     10 #include "chrome/browser/apps/app_browsertest_util.h"
     11 #include "chrome/browser/chrome_content_browser_client.h"
     12 #include "chrome/browser/extensions/extension_test_message_listener.h"
     13 #include "chrome/browser/guest_view/guest_view_base.h"
     14 #include "chrome/browser/guest_view/guest_view_manager.h"
     15 #include "chrome/browser/guest_view/guest_view_manager_factory.h"
     16 #include "chrome/browser/profiles/profile.h"
     17 #include "chrome/browser/renderer_context_menu/render_view_context_menu_browsertest_util.h"
     18 #include "chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h"
     19 #include "chrome/test/base/interactive_test_utils.h"
     20 #include "chrome/test/base/test_launcher_utils.h"
     21 #include "chrome/test/base/ui_test_utils.h"
     22 #include "content/public/browser/notification_service.h"
     23 #include "content/public/browser/render_process_host.h"
     24 #include "content/public/browser/render_view_host.h"
     25 #include "content/public/browser/render_widget_host_iterator.h"
     26 #include "content/public/browser/render_widget_host_view.h"
     27 #include "content/public/browser/web_contents.h"
     28 #include "content/public/common/content_switches.h"
     29 #include "content/public/test/browser_test_utils.h"
     30 #include "net/test/embedded_test_server/embedded_test_server.h"
     31 #include "ui/base/ime/composition_text.h"
     32 #include "ui/base/ime/text_input_client.h"
     33 #include "ui/base/test/ui_controls.h"
     34 #include "ui/events/keycodes/keyboard_codes.h"
     35 
     36 using apps::AppWindow;
     37 
     38 class TestGuestViewManager : public GuestViewManager {
     39  public:
     40   explicit TestGuestViewManager(content::BrowserContext* context) :
     41       GuestViewManager(context),
     42       web_contents_(NULL) {}
     43 
     44   content::WebContents* WaitForGuestCreated() {
     45     if (web_contents_)
     46       return web_contents_;
     47 
     48     message_loop_runner_ = new content::MessageLoopRunner;
     49     message_loop_runner_->Run();
     50     return web_contents_;
     51   }
     52 
     53  private:
     54   // GuestViewManager override:
     55   virtual void AddGuest(int guest_instance_id,
     56                         content::WebContents* guest_web_contents) OVERRIDE{
     57     GuestViewManager::AddGuest(guest_instance_id, guest_web_contents);
     58     web_contents_ = guest_web_contents;
     59 
     60     if (message_loop_runner_)
     61       message_loop_runner_->Quit();
     62   }
     63 
     64   content::WebContents* web_contents_;
     65   scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
     66 };
     67 
     68 // Test factory for creating test instances of GuestViewManager.
     69 class TestGuestViewManagerFactory : public GuestViewManagerFactory {
     70  public:
     71   TestGuestViewManagerFactory() :
     72       test_guest_view_manager_(NULL) {}
     73 
     74   virtual ~TestGuestViewManagerFactory() {}
     75 
     76   virtual GuestViewManager* CreateGuestViewManager(
     77       content::BrowserContext* context) OVERRIDE {
     78     return GetManager(context);
     79   }
     80 
     81   TestGuestViewManager* GetManager(content::BrowserContext* context) {
     82     if (!test_guest_view_manager_) {
     83       test_guest_view_manager_ = new TestGuestViewManager(context);
     84     }
     85     return test_guest_view_manager_;
     86   }
     87 
     88  private:
     89   TestGuestViewManager* test_guest_view_manager_;
     90 
     91   DISALLOW_COPY_AND_ASSIGN(TestGuestViewManagerFactory);
     92 };
     93 
     94 class WebViewInteractiveTest
     95     : public extensions::PlatformAppBrowserTest {
     96  public:
     97   WebViewInteractiveTest()
     98       : guest_web_contents_(NULL),
     99         embedder_web_contents_(NULL),
    100         corner_(gfx::Point()),
    101         mouse_click_result_(false),
    102         first_click_(true) {
    103     GuestViewManager::set_factory_for_testing(&factory_);
    104   }
    105 
    106   TestGuestViewManager* GetGuestViewManager() {
    107     return factory_.GetManager(browser()->profile());
    108   }
    109 
    110   void MoveMouseInsideWindowWithListener(gfx::Point point,
    111                                          const std::string& message) {
    112     ExtensionTestMessageListener move_listener(message, false);
    113     ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(
    114         gfx::Point(corner_.x() + point.x(), corner_.y() + point.y())));
    115     ASSERT_TRUE(move_listener.WaitUntilSatisfied());
    116   }
    117 
    118   void SendMouseClickWithListener(ui_controls::MouseButton button,
    119                                   const std::string& message) {
    120     ExtensionTestMessageListener listener(message, false);
    121     SendMouseClick(button);
    122     ASSERT_TRUE(listener.WaitUntilSatisfied());
    123   }
    124 
    125   void SendMouseClick(ui_controls::MouseButton button) {
    126     SendMouseEvent(button, ui_controls::DOWN);
    127     SendMouseEvent(button, ui_controls::UP);
    128   }
    129 
    130   void MoveMouseInsideWindow(const gfx::Point& point) {
    131     ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(
    132         gfx::Point(corner_.x() + point.x(), corner_.y() + point.y())));
    133   }
    134 
    135   gfx::NativeWindow GetPlatformAppWindow() {
    136     const apps::AppWindowRegistry::AppWindowList& app_windows =
    137         apps::AppWindowRegistry::Get(browser()->profile())->app_windows();
    138     return (*app_windows.begin())->GetNativeWindow();
    139   }
    140 
    141   void SendKeyPressToPlatformApp(ui::KeyboardCode key) {
    142     ASSERT_EQ(1U, GetAppWindowCount());
    143     ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
    144         GetPlatformAppWindow(), key, false, false, false, false));
    145   }
    146 
    147   void SendCopyKeyPressToPlatformApp() {
    148     ASSERT_EQ(1U, GetAppWindowCount());
    149 #if defined(OS_MACOSX)
    150     // Send Cmd+C on MacOSX.
    151     ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
    152         GetPlatformAppWindow(), ui::VKEY_C, false, false, false, true));
    153 #else
    154     // Send Ctrl+C on Windows and Linux/ChromeOS.
    155     ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
    156         GetPlatformAppWindow(), ui::VKEY_C, true, false, false, false));
    157 #endif
    158   }
    159 
    160   void SendStartOfLineKeyPressToPlatformApp() {
    161 #if defined(OS_MACOSX)
    162     // Send Cmd+Left on MacOSX.
    163     ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
    164         GetPlatformAppWindow(), ui::VKEY_LEFT, false, false, false, true));
    165 #else
    166     // Send Ctrl+Left on Windows and Linux/ChromeOS.
    167     ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
    168         GetPlatformAppWindow(), ui::VKEY_LEFT, true, false, false, false));
    169 #endif
    170   }
    171 
    172   void SendBackShortcutToPlatformApp() {
    173 #if defined(OS_MACOSX)
    174     // Send Cmd+[ on MacOSX.
    175     ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
    176         GetPlatformAppWindow(), ui::VKEY_OEM_4, false, false, false, true));
    177 #else
    178     // Send browser back key on Linux/Windows.
    179     ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
    180         GetPlatformAppWindow(), ui::VKEY_BROWSER_BACK,
    181         false, false, false, false));
    182 #endif
    183   }
    184 
    185   void SendForwardShortcutToPlatformApp() {
    186 #if defined(OS_MACOSX)
    187     // Send Cmd+] on MacOSX.
    188     ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
    189         GetPlatformAppWindow(), ui::VKEY_OEM_6, false, false, false, true));
    190 #else
    191     // Send browser back key on Linux/Windows.
    192     ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
    193         GetPlatformAppWindow(), ui::VKEY_BROWSER_FORWARD,
    194         false, false, false, false));
    195 #endif
    196   }
    197 
    198   void SendMouseEvent(ui_controls::MouseButton button,
    199                       ui_controls::MouseButtonState state) {
    200     if (first_click_) {
    201       mouse_click_result_ = ui_test_utils::SendMouseEventsSync(button,
    202                                                                 state);
    203       first_click_ = false;
    204     } else {
    205       ASSERT_EQ(mouse_click_result_, ui_test_utils::SendMouseEventsSync(
    206           button, state));
    207     }
    208   }
    209 
    210   enum TestServer {
    211     NEEDS_TEST_SERVER,
    212     NO_TEST_SERVER
    213   };
    214 
    215   scoped_ptr<ExtensionTestMessageListener> RunAppHelper(
    216       const std::string& test_name,
    217       const std::string& app_location,
    218       TestServer test_server,
    219       content::WebContents** embedder_web_contents) {
    220     // For serving guest pages.
    221     if ((test_server == NEEDS_TEST_SERVER) && !StartEmbeddedTestServer()) {
    222       LOG(ERROR) << "FAILED TO START TEST SERVER.";
    223       return scoped_ptr<ExtensionTestMessageListener>();
    224     }
    225 
    226     LoadAndLaunchPlatformApp(app_location.c_str(), "Launched");
    227     if (!ui_test_utils::ShowAndFocusNativeWindow(GetPlatformAppWindow())) {
    228       LOG(ERROR) << "UNABLE TO FOCUS TEST WINDOW.";
    229       return scoped_ptr<ExtensionTestMessageListener>();
    230     }
    231 
    232     // Flush any pending events to make sure we start with a clean slate.
    233     content::RunAllPendingInMessageLoop();
    234 
    235     *embedder_web_contents = GetFirstAppWindowWebContents();
    236 
    237     scoped_ptr<ExtensionTestMessageListener> done_listener(
    238         new ExtensionTestMessageListener("TEST_PASSED", false));
    239     done_listener->set_failure_message("TEST_FAILED");
    240     if (!content::ExecuteScript(
    241             *embedder_web_contents,
    242             base::StringPrintf("runTest('%s')", test_name.c_str()))) {
    243       LOG(ERROR) << "UNABLE TO START TEST";
    244       return scoped_ptr<ExtensionTestMessageListener>();
    245     }
    246 
    247     return done_listener.Pass();
    248   }
    249 
    250   void TestHelper(const std::string& test_name,
    251                   const std::string& app_location,
    252                   TestServer test_server) {
    253     content::WebContents* embedder_web_contents = NULL;
    254     scoped_ptr<ExtensionTestMessageListener> done_listener(
    255         RunAppHelper(
    256             test_name, app_location, test_server, &embedder_web_contents));
    257 
    258     ASSERT_TRUE(done_listener);
    259     ASSERT_TRUE(done_listener->WaitUntilSatisfied());
    260 
    261     guest_web_contents_ = GetGuestViewManager()->WaitForGuestCreated();
    262   }
    263 
    264   void RunTest(const std::string& app_name) {
    265   }
    266   void SetupTest(const std::string& app_name,
    267                  const std::string& guest_url_spec) {
    268     ASSERT_TRUE(StartEmbeddedTestServer());
    269     GURL::Replacements replace_host;
    270     std::string host_str("localhost");  // Must stay in scope with replace_host.
    271     replace_host.SetHostStr(host_str);
    272 
    273     GURL guest_url = embedded_test_server()->GetURL(guest_url_spec);
    274     guest_url = guest_url.ReplaceComponents(replace_host);
    275 
    276     ui_test_utils::UrlLoadObserver guest_observer(
    277         guest_url, content::NotificationService::AllSources());
    278 
    279     LoadAndLaunchPlatformApp(app_name.c_str(), "connected");
    280 
    281     guest_observer.Wait();
    282     content::Source<content::NavigationController> source =
    283         guest_observer.source();
    284     EXPECT_TRUE(source->GetWebContents()->GetRenderProcessHost()->
    285         IsIsolatedGuest());
    286 
    287     guest_web_contents_ = source->GetWebContents();
    288     embedder_web_contents_ =
    289         GuestViewBase::FromWebContents(guest_web_contents_)->
    290             embedder_web_contents();
    291 
    292     gfx::Rect offset = embedder_web_contents_->GetContainerBounds();
    293     corner_ = gfx::Point(offset.x(), offset.y());
    294 
    295     const testing::TestInfo* const test_info =
    296             testing::UnitTest::GetInstance()->current_test_info();
    297     const char* prefix = "DragDropWithinWebView";
    298     if (!strncmp(test_info->name(), prefix, strlen(prefix))) {
    299       // In the drag drop test we add 20px padding to the page body because on
    300       // windows if we get too close to the edge of the window the resize cursor
    301       // appears and we start dragging the window edge.
    302       corner_.Offset(20, 20);
    303     }
    304   }
    305 
    306   content::WebContents* guest_web_contents() {
    307     return guest_web_contents_;
    308   }
    309 
    310   content::WebContents* embedder_web_contents() {
    311     return embedder_web_contents_;
    312   }
    313 
    314   gfx::Point corner() {
    315     return corner_;
    316   }
    317 
    318   void SimulateRWHMouseClick(content::RenderWidgetHost* rwh,
    319                              blink::WebMouseEvent::Button button,
    320                              int x,
    321                              int y) {
    322     blink::WebMouseEvent mouse_event;
    323     mouse_event.button = button;
    324     mouse_event.x = mouse_event.windowX = x;
    325     mouse_event.y = mouse_event.windowY = y;
    326     mouse_event.modifiers = 0;
    327 
    328     mouse_event.type = blink::WebInputEvent::MouseDown;
    329     rwh->ForwardMouseEvent(mouse_event);
    330     mouse_event.type = blink::WebInputEvent::MouseUp;
    331     rwh->ForwardMouseEvent(mouse_event);
    332   }
    333 
    334   class PopupCreatedObserver {
    335    public:
    336     explicit PopupCreatedObserver()
    337         : initial_widget_count_(0),
    338           last_render_widget_host_(NULL),
    339           seen_new_widget_(false) {}
    340 
    341     ~PopupCreatedObserver() {}
    342 
    343     void Wait() {
    344       size_t current_widget_count = CountWidgets();
    345       if (!seen_new_widget_ &&
    346           current_widget_count == initial_widget_count_ + 1) {
    347         seen_new_widget_ = true;
    348       }
    349 
    350       // If we haven't seen any new widget or we get 0 size widget, we need to
    351       // schedule waiting.
    352       bool needs_to_schedule_wait = true;
    353 
    354       if (seen_new_widget_) {
    355         gfx::Rect popup_bounds =
    356             last_render_widget_host_->GetView()->GetViewBounds();
    357         if (!popup_bounds.size().IsEmpty())
    358           needs_to_schedule_wait = false;
    359       }
    360 
    361       if (needs_to_schedule_wait) {
    362         ScheduleWait();
    363       } else {
    364         // We are done.
    365         if (message_loop_)
    366           message_loop_->Quit();
    367       }
    368 
    369       if (!message_loop_) {
    370         message_loop_ = new content::MessageLoopRunner;
    371         message_loop_->Run();
    372       }
    373     }
    374 
    375     void Init() { initial_widget_count_ = CountWidgets(); }
    376 
    377     // Returns the last widget created.
    378     content::RenderWidgetHost* last_render_widget_host() {
    379       return last_render_widget_host_;
    380     }
    381 
    382    private:
    383     void ScheduleWait() {
    384       base::MessageLoop::current()->PostDelayedTask(
    385           FROM_HERE,
    386           base::Bind(&PopupCreatedObserver::Wait, base::Unretained(this)),
    387           base::TimeDelta::FromMilliseconds(200));
    388     }
    389 
    390     size_t CountWidgets() {
    391       scoped_ptr<content::RenderWidgetHostIterator> widgets(
    392           content::RenderWidgetHost::GetRenderWidgetHosts());
    393       size_t num_widgets = 0;
    394       while (content::RenderWidgetHost* widget = widgets->GetNextHost()) {
    395         if (widget->IsRenderView())
    396           continue;
    397         ++num_widgets;
    398         last_render_widget_host_ = widget;
    399       }
    400       return num_widgets;
    401     }
    402 
    403     size_t initial_widget_count_;
    404     content::RenderWidgetHost* last_render_widget_host_;
    405     scoped_refptr<content::MessageLoopRunner> message_loop_;
    406     bool seen_new_widget_;
    407 
    408     DISALLOW_COPY_AND_ASSIGN(PopupCreatedObserver);
    409   };
    410 
    411   void WaitForTitle(const char* title) {
    412     base::string16 expected_title(base::ASCIIToUTF16(title));
    413     base::string16 error_title(base::ASCIIToUTF16("FAILED"));
    414     content::TitleWatcher title_watcher(guest_web_contents(), expected_title);
    415     title_watcher.AlsoWaitForTitle(error_title);
    416     ASSERT_EQ(expected_title, title_watcher.WaitAndGetTitle());
    417   }
    418 
    419   void PopupTestHelper(const gfx::Point& padding) {
    420     PopupCreatedObserver popup_observer;
    421     popup_observer.Init();
    422     // Press alt+DOWN to open popup.
    423     bool alt = true;
    424     content::SimulateKeyPress(
    425         guest_web_contents(), ui::VKEY_DOWN, false, false, alt, false);
    426     popup_observer.Wait();
    427 
    428     content::RenderWidgetHost* popup_rwh =
    429         popup_observer.last_render_widget_host();
    430     gfx::Rect popup_bounds = popup_rwh->GetView()->GetViewBounds();
    431 
    432     content::RenderViewHost* embedder_rvh =
    433         GetFirstAppWindowWebContents()->GetRenderViewHost();
    434     gfx::Rect embedder_bounds = embedder_rvh->GetView()->GetViewBounds();
    435     gfx::Vector2d diff = popup_bounds.origin() - embedder_bounds.origin();
    436     LOG(INFO) << "DIFF: x = " << diff.x() << ", y = " << diff.y();
    437 
    438     const int left_spacing = 40 + padding.x();  // div.style.paddingLeft = 40px.
    439     // div.style.paddingTop = 50px + (input box height = 26px).
    440     const int top_spacing = 50 + 26 + padding.y();
    441 
    442     // If the popup is placed within |threshold_px| of the expected position,
    443     // then we consider the test as a pass.
    444     const int threshold_px = 10;
    445 
    446     EXPECT_LE(std::abs(diff.x() - left_spacing), threshold_px);
    447     EXPECT_LE(std::abs(diff.y() - top_spacing), threshold_px);
    448 
    449     // Close the popup.
    450     content::SimulateKeyPress(
    451         guest_web_contents(), ui::VKEY_ESCAPE, false, false, false, false);
    452   }
    453 
    454   void DragTestStep1() {
    455     // Move mouse to start of text.
    456     MoveMouseInsideWindow(gfx::Point(45, 8));
    457     MoveMouseInsideWindow(gfx::Point(45, 9));
    458     SendMouseEvent(ui_controls::LEFT, ui_controls::DOWN);
    459 
    460     MoveMouseInsideWindow(gfx::Point(74, 12));
    461     MoveMouseInsideWindow(gfx::Point(78, 12));
    462 
    463     // Now wait a bit before moving mouse to initiate drag/drop.
    464     base::MessageLoop::current()->PostDelayedTask(
    465         FROM_HERE,
    466         base::Bind(&WebViewInteractiveTest::DragTestStep2,
    467                    base::Unretained(this)),
    468         base::TimeDelta::FromMilliseconds(200));
    469   }
    470 
    471   void DragTestStep2() {
    472     // Drag source over target.
    473     MoveMouseInsideWindow(gfx::Point(76, 76));
    474 
    475     // Create a second mouse over the source to trigger the drag over event.
    476     MoveMouseInsideWindow(gfx::Point(76, 77));
    477 
    478     // Release mouse to drop.
    479     SendMouseEvent(ui_controls::LEFT, ui_controls::UP);
    480     SendMouseClick(ui_controls::LEFT);
    481 
    482     quit_closure_.Run();
    483 
    484     // Note that following ExtensionTestMessageListener and ExecuteScript*
    485     // call must be after we quit |quit_closure_|. Otherwise the class
    486     // here won't be able to receive messages sent by chrome.test.sendMessage.
    487     // This is because of the nature of drag and drop code (esp. the
    488     // MessageLoop) in it.
    489 
    490     // Now check if we got a drop and read the drop data.
    491     embedder_web_contents_ = GetFirstAppWindowWebContents();
    492     ExtensionTestMessageListener drop_listener("guest-got-drop", false);
    493     EXPECT_TRUE(content::ExecuteScript(embedder_web_contents_,
    494                                        "window.checkIfGuestGotDrop()"));
    495     EXPECT_TRUE(drop_listener.WaitUntilSatisfied());
    496 
    497     std::string last_drop_data;
    498     EXPECT_TRUE(content::ExecuteScriptAndExtractString(
    499                     embedder_web_contents_,
    500                     "window.domAutomationController.send(getLastDropData())",
    501                     &last_drop_data));
    502 
    503     last_drop_data_ = last_drop_data;
    504   }
    505 
    506  protected:
    507   TestGuestViewManagerFactory factory_;
    508   content::WebContents* guest_web_contents_;
    509   content::WebContents* embedder_web_contents_;
    510   gfx::Point corner_;
    511   bool mouse_click_result_;
    512   bool first_click_;
    513   // Only used in drag/drop test.
    514   base::Closure quit_closure_;
    515   std::string last_drop_data_;
    516 };
    517 
    518 // ui_test_utils::SendMouseMoveSync doesn't seem to work on OS_MACOSX, and
    519 // likely won't work on many other platforms as well, so for now this test
    520 // is for Windows and Linux only. As of Sept 17th, 2013 this test is disabled
    521 // on Windows due to flakines, see http://crbug.com/293445.
    522 
    523 // Disabled on Linux Aura because pointer lock does not work on Linux Aura.
    524 // crbug.com/341876
    525 
    526 #if defined(OS_LINUX) && !defined(USE_AURA)
    527 
    528 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, PointerLock) {
    529   SetupTest("web_view/pointer_lock",
    530             "/extensions/platform_apps/web_view/pointer_lock/guest.html");
    531 
    532   // Move the mouse over the Lock Pointer button.
    533   ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(
    534       gfx::Point(corner().x() + 75, corner().y() + 25)));
    535 
    536   // Click the Lock Pointer button. The first two times the button is clicked
    537   // the permission API will deny the request (intentional).
    538   ExtensionTestMessageListener exception_listener("request exception", false);
    539   SendMouseClickWithListener(ui_controls::LEFT, "lock error");
    540   ASSERT_TRUE(exception_listener.WaitUntilSatisfied());
    541   SendMouseClickWithListener(ui_controls::LEFT, "lock error");
    542 
    543   // Click the Lock Pointer button, locking the mouse to lockTarget1.
    544   SendMouseClickWithListener(ui_controls::LEFT, "locked");
    545 
    546   // Attempt to move the mouse off of the lock target, and onto lockTarget2,
    547   // (which would trigger a test failure).
    548   ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(
    549       gfx::Point(corner().x() + 74, corner().y() + 74)));
    550   MoveMouseInsideWindowWithListener(gfx::Point(75, 75), "mouse-move");
    551 
    552 #if defined(OS_WIN)
    553   // When the mouse is unlocked on win aura, sending a test mouse click clicks
    554   // where the mouse moved to while locked. I was unable to figure out why, and
    555   // since the issue only occurs with the test mouse events, just fix it with
    556   // a simple workaround - moving the mouse back to where it should be.
    557   // TODO(mthiesse): Fix Win Aura simulated mouse events while mouse locked.
    558   MoveMouseInsideWindowWithListener(gfx::Point(75, 25), "mouse-move");
    559 #endif
    560 
    561   ExtensionTestMessageListener unlocked_listener("unlocked", false);
    562   // Send a key press to unlock the mouse.
    563   SendKeyPressToPlatformApp(ui::VKEY_ESCAPE);
    564 
    565   // Wait for page to receive (successful) mouse unlock response.
    566   ASSERT_TRUE(unlocked_listener.WaitUntilSatisfied());
    567 
    568   // After the second lock, guest.js sends a message to main.js to remove the
    569   // webview object. main.js then removes the div containing the webview, which
    570   // should unlock, and leave the mouse over the mousemove-capture-container
    571   // div. We then move the mouse over that div to ensure the mouse was properly
    572   // unlocked and that the div receieves the message.
    573   ExtensionTestMessageListener move_captured_listener("move-captured", false);
    574   move_captured_listener.set_failure_message("timeout");
    575 
    576   // Mouse should already be over lock button (since we just unlocked), so send
    577   // click to re-lock the mouse.
    578   SendMouseClickWithListener(ui_controls::LEFT, "deleted");
    579 
    580   // A mousemove event is triggered on the mousemove-capture-container element
    581   // when we delete the webview container (since the mouse moves onto the
    582   // element), but just in case, send an explicit mouse movement to be safe.
    583   ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(
    584       gfx::Point(corner().x() + 50, corner().y() + 10)));
    585 
    586   // Wait for page to receive second (successful) mouselock response.
    587   bool success = move_captured_listener.WaitUntilSatisfied();
    588   if (!success) {
    589     fprintf(stderr, "TIMEOUT - retrying\n");
    590     // About 1 in 40 tests fail to detect mouse moves at this point (why?).
    591     // Sending a right click seems to fix this (why?).
    592     ExtensionTestMessageListener move_listener2("move-captured", false);
    593     SendMouseClick(ui_controls::RIGHT);
    594     ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(
    595         gfx::Point(corner().x() + 51, corner().y() + 11)));
    596     ASSERT_TRUE(move_listener2.WaitUntilSatisfied());
    597   }
    598 }
    599 
    600 #endif  // defined(OS_LINUX) && !defined(USE_AURA)
    601 
    602 // Tests that if a <webview> is focused before navigation then the guest starts
    603 // off focused.
    604 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, Focus_FocusBeforeNavigation) {
    605   TestHelper("testFocusBeforeNavigation", "web_view/focus", NO_TEST_SERVER);
    606 }
    607 
    608 // Tests that setting focus on the <webview> sets focus on the guest.
    609 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, Focus_FocusEvent) {
    610   TestHelper("testFocusEvent", "web_view/focus", NO_TEST_SERVER);
    611 }
    612 
    613 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, Focus_FocusTracksEmbedder) {
    614   content::WebContents* embedder_web_contents = NULL;
    615 
    616   scoped_ptr<ExtensionTestMessageListener> done_listener(
    617       RunAppHelper("testFocusTracksEmbedder", "web_view/focus", NO_TEST_SERVER,
    618                    &embedder_web_contents));
    619   done_listener->WaitUntilSatisfied();
    620 
    621   ExtensionTestMessageListener next_step_listener("TEST_STEP_PASSED", false);
    622   next_step_listener.set_failure_message("TEST_STEP_FAILED");
    623   EXPECT_TRUE(content::ExecuteScript(
    624                   embedder_web_contents,
    625                   "window.runCommand('testFocusTracksEmbedderRunNextStep');"));
    626 
    627   // Blur the embedder.
    628   embedder_web_contents->GetRenderViewHost()->Blur();
    629   // Ensure that the guest is also blurred.
    630   ASSERT_TRUE(next_step_listener.WaitUntilSatisfied());
    631 }
    632 
    633 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, Focus_AdvanceFocus) {
    634   content::WebContents* embedder_web_contents = NULL;
    635 
    636   {
    637     scoped_ptr<ExtensionTestMessageListener> done_listener(
    638         RunAppHelper("testAdvanceFocus", "web_view/focus", NO_TEST_SERVER,
    639                      &embedder_web_contents));
    640     done_listener->WaitUntilSatisfied();
    641   }
    642 
    643   {
    644     ExtensionTestMessageListener listener("button1-focused", false);
    645     listener.set_failure_message("TEST_FAILED");
    646     SimulateRWHMouseClick(embedder_web_contents->GetRenderViewHost(),
    647                           blink::WebMouseEvent::ButtonLeft, 200, 20);
    648     content::SimulateKeyPress(embedder_web_contents, ui::VKEY_TAB,
    649         false, false, false, false);
    650     ASSERT_TRUE(listener.WaitUntilSatisfied());
    651   }
    652 
    653   {
    654     // Wait for button1 to be focused again, this means we were asked to
    655     // move the focus to the next focusable element.
    656     ExtensionTestMessageListener listener("button1-advance-focus", false);
    657     listener.set_failure_message("TEST_FAILED");
    658     // TODO(fsamuel): A third Tab key press should not be necessary.
    659     // The <webview> will take keyboard focus but it will not focus an initial
    660     // element. The initial element is dependent upon tab direction which blink
    661     // does not propagate to the plugin.
    662     // See http://crbug.com/147644.
    663     content::SimulateKeyPress(embedder_web_contents, ui::VKEY_TAB,
    664         false, false, false, false);
    665     content::SimulateKeyPress(embedder_web_contents, ui::VKEY_TAB,
    666         false, false, false, false);
    667     content::SimulateKeyPress(embedder_web_contents, ui::VKEY_TAB,
    668         false, false, false, false);
    669     ASSERT_TRUE(listener.WaitUntilSatisfied());
    670   }
    671 }
    672 
    673 // Tests that blurring <webview> also blurs the guest.
    674 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, Focus_BlurEvent) {
    675   TestHelper("testBlurEvent", "web_view/focus", NO_TEST_SERVER);
    676 }
    677 
    678 // Tests that guests receive edit commands and respond appropriately.
    679 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, EditCommands) {
    680   LoadAndLaunchPlatformApp("web_view/edit_commands", "connected");
    681 
    682   ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
    683       GetPlatformAppWindow()));
    684 
    685   // Flush any pending events to make sure we start with a clean slate.
    686   content::RunAllPendingInMessageLoop();
    687 
    688   ExtensionTestMessageListener copy_listener("copy", false);
    689   SendCopyKeyPressToPlatformApp();
    690 
    691   // Wait for the guest to receive a 'copy' edit command.
    692   ASSERT_TRUE(copy_listener.WaitUntilSatisfied());
    693 }
    694 
    695 // Tests that guests receive edit commands and respond appropriately.
    696 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, EditCommandsNoMenu) {
    697   SetupTest("web_view/edit_commands_no_menu",
    698       "/extensions/platform_apps/web_view/edit_commands_no_menu/"
    699       "guest.html");
    700 
    701   ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
    702       GetPlatformAppWindow()));
    703 
    704   // Flush any pending events to make sure we start with a clean slate.
    705   content::RunAllPendingInMessageLoop();
    706 
    707   ExtensionTestMessageListener start_of_line_listener("StartOfLine", false);
    708   SendStartOfLineKeyPressToPlatformApp();
    709   // Wait for the guest to receive a 'copy' edit command.
    710   ASSERT_TRUE(start_of_line_listener.WaitUntilSatisfied());
    711 }
    712 
    713 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,
    714                        NewWindow_NewWindowNameTakesPrecedence) {
    715   TestHelper("testNewWindowNameTakesPrecedence",
    716              "web_view/newwindow",
    717              NEEDS_TEST_SERVER);
    718 }
    719 
    720 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,
    721                        NewWindow_WebViewNameTakesPrecedence) {
    722   TestHelper("testWebViewNameTakesPrecedence",
    723              "web_view/newwindow",
    724              NEEDS_TEST_SERVER);
    725 }
    726 
    727 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, NewWindow_NoName) {
    728   TestHelper("testNoName",
    729              "web_view/newwindow",
    730              NEEDS_TEST_SERVER);
    731 }
    732 
    733 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, NewWindow_Redirect) {
    734   TestHelper("testNewWindowRedirect",
    735              "web_view/newwindow",
    736              NEEDS_TEST_SERVER);
    737 }
    738 
    739 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, NewWindow_Close) {
    740   TestHelper("testNewWindowClose",
    741              "web_view/newwindow",
    742              NEEDS_TEST_SERVER);
    743 }
    744 
    745 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, NewWindow_ExecuteScript) {
    746   TestHelper("testNewWindowExecuteScript",
    747              "web_view/newwindow",
    748              NEEDS_TEST_SERVER);
    749 }
    750 
    751 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,
    752                        NewWindow_DeclarativeWebRequest) {
    753   TestHelper("testNewWindowDeclarativeWebRequest",
    754              "web_view/newwindow",
    755              NEEDS_TEST_SERVER);
    756 }
    757 
    758 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, NewWindow_WebRequest) {
    759   TestHelper("testNewWindowWebRequest",
    760              "web_view/newwindow",
    761              NEEDS_TEST_SERVER);
    762 }
    763 
    764 // A custom elements bug needs to be addressed to enable this test:
    765 // See http://crbug.com/282477 for more information.
    766 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,
    767                        DISABLED_NewWindow_WebRequestCloseWindow) {
    768   TestHelper("testNewWindowWebRequestCloseWindow",
    769              "web_view/newwindow",
    770              NEEDS_TEST_SERVER);
    771 }
    772 
    773 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,
    774                        NewWindow_WebRequestRemoveElement) {
    775   TestHelper("testNewWindowWebRequestRemoveElement",
    776              "web_view/newwindow",
    777              NEEDS_TEST_SERVER);
    778 }
    779 
    780 // Tests that Ctrl+Click/Cmd+Click on a link fires up the newwindow API.
    781 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, NewWindow_OpenInNewTab) {
    782   content::WebContents* embedder_web_contents = NULL;
    783 
    784   ExtensionTestMessageListener loaded_listener("Loaded", false);
    785   scoped_ptr<ExtensionTestMessageListener> done_listener(
    786     RunAppHelper("testNewWindowOpenInNewTab",
    787                  "web_view/newwindow",
    788                  NEEDS_TEST_SERVER,
    789                  &embedder_web_contents));
    790 
    791   loaded_listener.WaitUntilSatisfied();
    792 #if defined(OS_MACOSX)
    793   ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
    794       GetPlatformAppWindow(), ui::VKEY_RETURN,
    795       false, false, false, true /* cmd */));
    796 #else
    797   ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
    798       GetPlatformAppWindow(), ui::VKEY_RETURN,
    799       true /* ctrl */, false, false, false));
    800 #endif
    801 
    802   // Wait for the embedder to receive a 'newwindow' event.
    803   ASSERT_TRUE(done_listener->WaitUntilSatisfied());
    804 }
    805 
    806 
    807 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, ExecuteCode) {
    808   ASSERT_TRUE(RunPlatformAppTestWithArg(
    809       "platform_apps/web_view/common", "execute_code")) << message_;
    810 }
    811 
    812 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, PopupPositioningBasic) {
    813   TestHelper("testBasic", "web_view/popup_positioning", NO_TEST_SERVER);
    814   ASSERT_TRUE(guest_web_contents());
    815   PopupTestHelper(gfx::Point());
    816 
    817   // TODO(lazyboy): Move the embedder window to a random location and
    818   // make sure we keep rendering popups correct in webview.
    819 }
    820 
    821 // Tests that moving browser plugin (without resize/UpdateRects) correctly
    822 // repositions popup.
    823 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, PopupPositioningMoved) {
    824   TestHelper("testMoved", "web_view/popup_positioning", NO_TEST_SERVER);
    825   ASSERT_TRUE(guest_web_contents());
    826   PopupTestHelper(gfx::Point(20, 0));
    827 }
    828 
    829 // Drag and drop inside a webview is currently only enabled for linux and mac,
    830 // but the tests don't work on anything except chromeos for now. This is because
    831 // of simulating mouse drag code's dependency on platforms.
    832 #if defined(OS_CHROMEOS)
    833 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, DragDropWithinWebView) {
    834   LoadAndLaunchPlatformApp("web_view/dnd_within_webview", "connected");
    835   ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(GetPlatformAppWindow()));
    836 
    837   embedder_web_contents_ = GetFirstAppWindowWebContents();
    838   gfx::Rect offset = embedder_web_contents_->GetContainerBounds();
    839   corner_ = gfx::Point(offset.x(), offset.y());
    840 
    841   // In the drag drop test we add 20px padding to the page body because on
    842   // windows if we get too close to the edge of the window the resize cursor
    843   // appears and we start dragging the window edge.
    844   corner_.Offset(20, 20);
    845 
    846   // Flush any pending events to make sure we start with a clean slate.
    847   content::RunAllPendingInMessageLoop();
    848   for (;;) {
    849     base::RunLoop run_loop;
    850     quit_closure_ = run_loop.QuitClosure();
    851     base::MessageLoop::current()->PostTask(
    852         FROM_HERE,
    853         base::Bind(&WebViewInteractiveTest::DragTestStep1,
    854                    base::Unretained(this)));
    855     run_loop.Run();
    856 
    857     if (last_drop_data_ == "Drop me")
    858       break;
    859 
    860     LOG(INFO) << "Drag was cancelled in interactive_test, restarting drag";
    861 
    862     // Reset state for next try.
    863     ExtensionTestMessageListener reset_listener("resetStateReply", false);
    864     EXPECT_TRUE(content::ExecuteScript(embedder_web_contents_,
    865                                        "window.resetState()"));
    866     ASSERT_TRUE(reset_listener.WaitUntilSatisfied());
    867   }
    868   ASSERT_EQ("Drop me", last_drop_data_);
    869 }
    870 #endif  // (defined(OS_CHROMEOS))
    871 
    872 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, Navigation) {
    873   TestHelper("testNavigation", "web_view/navigation", NO_TEST_SERVER);
    874 }
    875 
    876 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, Navigation_BackForwardKeys) {
    877   LoadAndLaunchPlatformApp("web_view/navigation", "Launched");
    878   ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
    879       GetPlatformAppWindow()));
    880   // Flush any pending events to make sure we start with a clean slate.
    881   content::RunAllPendingInMessageLoop();
    882 
    883   content::WebContents* embedder_web_contents = GetFirstAppWindowWebContents();
    884   ASSERT_TRUE(embedder_web_contents);
    885 
    886   ExtensionTestMessageListener done_listener(
    887       "TEST_PASSED", false);
    888   done_listener.set_failure_message("TEST_FAILED");
    889   ExtensionTestMessageListener ready_back_key_listener(
    890       "ReadyForBackKey", false);
    891   ExtensionTestMessageListener ready_forward_key_listener(
    892       "ReadyForForwardKey", false);
    893 
    894   EXPECT_TRUE(content::ExecuteScript(
    895                   embedder_web_contents,
    896                   "runTest('testBackForwardKeys')"));
    897 
    898   ASSERT_TRUE(ready_back_key_listener.WaitUntilSatisfied());
    899   SendBackShortcutToPlatformApp();
    900 
    901   ASSERT_TRUE(ready_forward_key_listener.WaitUntilSatisfied());
    902   SendForwardShortcutToPlatformApp();
    903 
    904   ASSERT_TRUE(done_listener.WaitUntilSatisfied());
    905 }
    906 
    907 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,
    908                        PointerLock_PointerLockLostWithFocus) {
    909   TestHelper("testPointerLockLostWithFocus",
    910              "web_view/pointerlock",
    911              NO_TEST_SERVER);
    912 }
    913 
    914 // This test exercies the following scenario:
    915 // 1. An <input> in guest has focus.
    916 // 2. User takes focus to embedder by clicking e.g. an <input> in embedder.
    917 // 3. User brings back the focus directly to the <input> in #1.
    918 //
    919 // Now we need to make sure TextInputTypeChanged fires properly for the guest's
    920 // view upon step #3. We simply read the input type's state after #3 to
    921 // make sure it's not TEXT_INPUT_TYPE_NONE.
    922 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, Focus_FocusRestored) {
    923   TestHelper("testFocusRestored", "web_view/focus", NO_TEST_SERVER);
    924   content::WebContents* embedder_web_contents = GetFirstAppWindowWebContents();
    925   ASSERT_TRUE(embedder_web_contents);
    926   ASSERT_TRUE(guest_web_contents());
    927 
    928   // 1) We click on the guest so that we get a focus event.
    929   ExtensionTestMessageListener next_step_listener("TEST_STEP_PASSED", false);
    930   next_step_listener.set_failure_message("TEST_STEP_FAILED");
    931   {
    932     content::SimulateMouseClickAt(guest_web_contents(),
    933                                   0,
    934                                   blink::WebMouseEvent::ButtonLeft,
    935                                   gfx::Point(10, 10));
    936     EXPECT_TRUE(content::ExecuteScript(
    937                     embedder_web_contents,
    938                     "window.runCommand('testFocusRestoredRunNextStep', 1);"));
    939   }
    940   // Wait for the next step to complete.
    941   ASSERT_TRUE(next_step_listener.WaitUntilSatisfied());
    942 
    943   // 2) We click on the embedder so the guest's focus goes away and it observes
    944   // a blur event.
    945   next_step_listener.Reset();
    946   {
    947     content::SimulateMouseClickAt(embedder_web_contents,
    948                                   0,
    949                                   blink::WebMouseEvent::ButtonLeft,
    950                                   gfx::Point(200, 20));
    951     EXPECT_TRUE(content::ExecuteScript(
    952                     embedder_web_contents,
    953                     "window.runCommand('testFocusRestoredRunNextStep', 2);"));
    954   }
    955   // Wait for the next step to complete.
    956   ASSERT_TRUE(next_step_listener.WaitUntilSatisfied());
    957 
    958   // 3) We click on the guest again to bring back focus directly to the previous
    959   // input element, then we ensure text_input_type is properly set.
    960   next_step_listener.Reset();
    961   {
    962     content::SimulateMouseClickAt(guest_web_contents(),
    963                                   0,
    964                                   blink::WebMouseEvent::ButtonLeft,
    965                                   gfx::Point(10, 10));
    966     EXPECT_TRUE(content::ExecuteScript(
    967                     embedder_web_contents,
    968                     "window.runCommand('testFocusRestoredRunNextStep', 3)"));
    969   }
    970   // Wait for the next step to complete.
    971   ASSERT_TRUE(next_step_listener.WaitUntilSatisfied());
    972 
    973   // |text_input_client| is not available for mac and android.
    974 #if !defined(OS_MACOSX) && !defined(OS_ANDROID)
    975   ui::TextInputClient* text_input_client =
    976       embedder_web_contents->GetRenderViewHost()->GetView()
    977           ->GetTextInputClient();
    978   ASSERT_TRUE(text_input_client);
    979   ASSERT_TRUE(text_input_client->GetTextInputType() !=
    980               ui::TEXT_INPUT_TYPE_NONE);
    981 #endif
    982 }
    983 
    984 // ui::TextInputClient is NULL for mac and android.
    985 #if !defined(OS_MACOSX) && !defined(OS_ANDROID)
    986 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, Focus_InputMethod) {
    987   content::WebContents* embedder_web_contents = NULL;
    988   scoped_ptr<ExtensionTestMessageListener> done_listener(
    989       RunAppHelper("testInputMethod", "web_view/focus", NO_TEST_SERVER,
    990                    &embedder_web_contents));
    991   ASSERT_TRUE(done_listener->WaitUntilSatisfied());
    992 
    993   ui::TextInputClient* text_input_client =
    994       embedder_web_contents->GetRenderViewHost()->GetView()
    995           ->GetTextInputClient();
    996   ASSERT_TRUE(text_input_client);
    997 
    998   ExtensionTestMessageListener next_step_listener("TEST_STEP_PASSED", false);
    999   next_step_listener.set_failure_message("TEST_STEP_FAILED");
   1000 
   1001   // An input element inside the <webview> gets focus and is given some
   1002   // user input via IME.
   1003   {
   1004     ui::CompositionText composition;
   1005     composition.text = base::UTF8ToUTF16("InputTest123");
   1006     text_input_client->SetCompositionText(composition);
   1007     EXPECT_TRUE(content::ExecuteScript(
   1008                     embedder_web_contents,
   1009                     "window.runCommand('testInputMethodRunNextStep', 1);"));
   1010 
   1011     // Wait for the next step to complete.
   1012     ASSERT_TRUE(next_step_listener.WaitUntilSatisfied());
   1013   }
   1014 
   1015   // A composition is committed via IME.
   1016   {
   1017     next_step_listener.Reset();
   1018 
   1019     ui::CompositionText composition;
   1020     composition.text = base::UTF8ToUTF16("InputTest456");
   1021     text_input_client->SetCompositionText(composition);
   1022     text_input_client->ConfirmCompositionText();
   1023     EXPECT_TRUE(content::ExecuteScript(
   1024                   embedder_web_contents,
   1025                   "window.runCommand('testInputMethodRunNextStep', 2);"));
   1026 
   1027     // Wait for the next step to complete.
   1028     EXPECT_TRUE(next_step_listener.WaitUntilSatisfied());
   1029   }
   1030 
   1031   // Moving focus causes IME cancel, and the composition will be committed
   1032   // in first <input> in the <webview>, not in the second <input>.
   1033   {
   1034     next_step_listener.Reset();
   1035     ui::CompositionText composition;
   1036     composition.text = base::UTF8ToUTF16("InputTest789");
   1037     text_input_client->SetCompositionText(composition);
   1038     EXPECT_TRUE(content::ExecuteScript(
   1039                     embedder_web_contents,
   1040                     "window.runCommand('testInputMethodRunNextStep', 3);"));
   1041 
   1042     // Wait for the next step to complete.
   1043     EXPECT_TRUE(next_step_listener.WaitUntilSatisfied());
   1044   }
   1045 
   1046   // Tests ExtendSelectionAndDelete message works in <webview>.
   1047   {
   1048     next_step_listener.Reset();
   1049 
   1050     // At this point we have set focus on first <input> in the <webview>,
   1051     // and the value it contains is 'InputTestABC' with caret set after 'T'.
   1052     // Now we delete 'Test' in 'InputTestABC', as the caret is after 'T':
   1053     // delete before 1 character ('T') and after 3 characters ('est').
   1054     text_input_client->ExtendSelectionAndDelete(1, 3);
   1055     EXPECT_TRUE(content::ExecuteScript(
   1056                     embedder_web_contents,
   1057                     "window.runCommand('testInputMethodRunNextStep', 4);"));
   1058 
   1059     // Wait for the next step to complete.
   1060     EXPECT_TRUE(next_step_listener.WaitUntilSatisfied());
   1061   }
   1062 }
   1063 #endif
   1064 
   1065 #if defined(OS_MACOSX)
   1066 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, TextSelection) {
   1067   SetupTest("web_view/text_selection",
   1068             "/extensions/platform_apps/web_view/text_selection/guest.html");
   1069   ASSERT_TRUE(guest_web_contents());
   1070   ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
   1071       GetPlatformAppWindow()));
   1072 
   1073   // Wait until guest sees a context menu, select an arbitrary item (copy).
   1074   ExtensionTestMessageListener ctx_listener("MSG_CONTEXTMENU", false);
   1075   ContextMenuNotificationObserver menu_observer(IDC_CONTENT_CONTEXT_COPY);
   1076   SimulateRWHMouseClick(guest_web_contents()->GetRenderViewHost(),
   1077                         blink::WebMouseEvent::ButtonRight, 20, 20);
   1078   ASSERT_TRUE(ctx_listener.WaitUntilSatisfied());
   1079 
   1080   // Now verify that the selection text propagates properly to RWHV.
   1081   content::RenderWidgetHostView* guest_rwhv =
   1082       guest_web_contents()->GetRenderWidgetHostView();
   1083   ASSERT_TRUE(guest_rwhv);
   1084   std::string selected_text = base::UTF16ToUTF8(guest_rwhv->GetSelectedText());
   1085   ASSERT_TRUE(selected_text.size() >= 10u);
   1086   ASSERT_EQ("AAAAAAAAAA", selected_text.substr(0, 10));
   1087 }
   1088 #endif
   1089