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