OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stddef.h> | 5 #include <stddef.h> |
6 | 6 |
| 7 #include <limits> |
| 8 |
7 #include "base/location.h" | 9 #include "base/location.h" |
8 #include "base/macros.h" | 10 #include "base/macros.h" |
9 #include "base/single_thread_task_runner.h" | 11 #include "base/single_thread_task_runner.h" |
10 #include "base/strings/stringprintf.h" | 12 #include "base/strings/stringprintf.h" |
11 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
12 #include "base/test/test_timeouts.h" | 14 #include "base/test/test_timeouts.h" |
13 #include "base/threading/thread_task_runner_handle.h" | 15 #include "base/threading/thread_task_runner_handle.h" |
14 #include "build/build_config.h" | 16 #include "build/build_config.h" |
15 #include "chrome/app/chrome_command_ids.h" | 17 #include "chrome/app/chrome_command_ids.h" |
16 #include "chrome/browser/apps/app_browsertest_util.h" | 18 #include "chrome/browser/apps/app_browsertest_util.h" |
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
553 switches::kEnableFeatures, | 555 switches::kEnableFeatures, |
554 ::features::kGuestViewCrossProcessFrames.name); | 556 ::features::kGuestViewCrossProcessFrames.name); |
555 } else { | 557 } else { |
556 command_line->AppendSwitchASCII( | 558 command_line->AppendSwitchASCII( |
557 switches::kDisableFeatures, | 559 switches::kDisableFeatures, |
558 ::features::kGuestViewCrossProcessFrames.name); | 560 ::features::kGuestViewCrossProcessFrames.name); |
559 } | 561 } |
560 } | 562 } |
561 }; | 563 }; |
562 | 564 |
| 565 class WebViewImeInteractiveTest : public WebViewInteractiveTest { |
| 566 protected: |
| 567 // This class observes all the composition range updates associated with the |
| 568 // TextInputManager of the provided WebContents. The WebContents should be an |
| 569 // outer most WebContents. |
| 570 class CompositionRangeUpdateObserver { |
| 571 public: |
| 572 explicit CompositionRangeUpdateObserver(content::WebContents* web_contents) |
| 573 : tester_(web_contents) { |
| 574 tester_.SetOnImeCompositionRangeChangedCallback( |
| 575 base::Bind(&CompositionRangeUpdateObserver::OnCompositionRangeUpdated, |
| 576 base::Unretained(this))); |
| 577 } |
| 578 ~CompositionRangeUpdateObserver() {} |
| 579 |
| 580 // Wait until a composition range update with a range length equal to |
| 581 // |length| is received. |
| 582 void WaitForCompositionRangeLength(uint32_t length) { |
| 583 if (last_composition_range_length_.has_value() && |
| 584 last_composition_range_length_.value() == length) |
| 585 return; |
| 586 expected_length_ = length; |
| 587 run_loop_.reset(new base::RunLoop()); |
| 588 run_loop_->Run(); |
| 589 } |
| 590 |
| 591 private: |
| 592 void OnCompositionRangeUpdated() { |
| 593 uint32_t length = std::numeric_limits<uint32_t>::max(); |
| 594 if (tester_.GetLastCompositionRangeLength(&length)) { |
| 595 last_composition_range_length_ = length; |
| 596 } |
| 597 if (last_composition_range_length_.value() == expected_length_) |
| 598 run_loop_->Quit(); |
| 599 } |
| 600 |
| 601 content::TextInputManagerTester tester_; |
| 602 std::unique_ptr<base::RunLoop> run_loop_; |
| 603 base::Optional<uint32_t> last_composition_range_length_; |
| 604 uint32_t expected_length_ = 0; |
| 605 |
| 606 DISALLOW_COPY_AND_ASSIGN(CompositionRangeUpdateObserver); |
| 607 }; |
| 608 }; |
| 609 |
563 class WebViewDragDropInteractiveTest : public WebViewInteractiveTest {}; | 610 class WebViewDragDropInteractiveTest : public WebViewInteractiveTest {}; |
564 class WebViewNewWindowInteractiveTest : public WebViewInteractiveTest {}; | 611 class WebViewNewWindowInteractiveTest : public WebViewInteractiveTest {}; |
565 class WebViewFocusInteractiveTest : public WebViewInteractiveTest {}; | 612 class WebViewFocusInteractiveTest : public WebViewInteractiveTest {}; |
566 class WebViewPointerLockInteractiveTest : public WebViewInteractiveTest {}; | 613 class WebViewPointerLockInteractiveTest : public WebViewInteractiveTest {}; |
567 class WebViewImeInteractiveTest : public WebViewInteractiveTest {}; | |
568 | 614 |
569 // The tests below aren't needed in --use-cross-process-frames-for-guests. | 615 // The tests below aren't needed in --use-cross-process-frames-for-guests. |
570 class WebViewContextMenuInteractiveTest : public WebViewInteractiveTestBase {}; | 616 class WebViewContextMenuInteractiveTest : public WebViewInteractiveTestBase {}; |
571 | 617 |
572 // The following class of tests do not work for OOPIF <webview>. | 618 // The following class of tests do not work for OOPIF <webview>. |
573 // TODO(ekaramad): Make this tests work with OOPIF and replace the test classes | 619 // TODO(ekaramad): Make this tests work with OOPIF and replace the test classes |
574 // with WebViewInteractiveTest (see crbug.com/582562). | 620 // with WebViewInteractiveTest (see crbug.com/582562). |
575 class WebViewPopupInteractiveTest : public WebViewInteractiveTestBase {}; | 621 class WebViewPopupInteractiveTest : public WebViewInteractiveTestBase {}; |
576 | 622 |
577 INSTANTIATE_TEST_CASE_P(WebViewInteractiveTests, | 623 INSTANTIATE_TEST_CASE_P(WebViewInteractiveTests, |
(...skipping 1063 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1641 | 1687 |
1642 // Click the <input> element inside the <webview>. In its focus handle, the | 1688 // Click the <input> element inside the <webview>. In its focus handle, the |
1643 // <input> inside the <webview> initializes its value to "A B X D". | 1689 // <input> inside the <webview> initializes its value to "A B X D". |
1644 ExtensionTestMessageListener focus_listener("WebViewImeTest.InputFocused", | 1690 ExtensionTestMessageListener focus_listener("WebViewImeTest.InputFocused", |
1645 false); | 1691 false); |
1646 content::WebContents* target_web_contents = | 1692 content::WebContents* target_web_contents = |
1647 GetParam() | 1693 GetParam() |
1648 ? guest_web_contents | 1694 ? guest_web_contents |
1649 : guest_view::GuestViewBase::FromWebContents(guest_web_contents) | 1695 : guest_view::GuestViewBase::FromWebContents(guest_web_contents) |
1650 ->embedder_web_contents(); | 1696 ->embedder_web_contents(); |
| 1697 |
| 1698 // The guest page has a large input box and (50, 50) lies inside the box. |
1651 content::SimulateMouseClickAt(target_web_contents, 0, | 1699 content::SimulateMouseClickAt(target_web_contents, 0, |
1652 blink::WebMouseEvent::Button::kLeft, | 1700 blink::WebMouseEvent::Button::kLeft, |
1653 gfx::Point(50, 50)); | 1701 gfx::Point(50, 50)); |
1654 focus_listener.WaitUntilSatisfied(); | 1702 focus_listener.WaitUntilSatisfied(); |
1655 | 1703 |
1656 // Verify the text inside the <input> is "A B X D". | 1704 // Verify the text inside the <input> is "A B X D". |
1657 std::string value; | 1705 std::string value; |
1658 ASSERT_TRUE(ExecuteScriptAndExtractString(guest_web_contents, | 1706 ASSERT_TRUE(ExecuteScriptAndExtractString(guest_web_contents, |
1659 "window.domAutomationController." | 1707 "window.domAutomationController." |
1660 "send(document.querySelector('" | 1708 "send(document.querySelector('" |
(...skipping 16 matching lines...) Expand all Loading... |
1677 // Get the input value from the guest. | 1725 // Get the input value from the guest. |
1678 value.clear(); | 1726 value.clear(); |
1679 ASSERT_TRUE(ExecuteScriptAndExtractString(guest_web_contents, | 1727 ASSERT_TRUE(ExecuteScriptAndExtractString(guest_web_contents, |
1680 "window.domAutomationController." | 1728 "window.domAutomationController." |
1681 "send(document.querySelector('" | 1729 "send(document.querySelector('" |
1682 "input').value)", | 1730 "input').value)", |
1683 &value)); | 1731 &value)); |
1684 EXPECT_EQ("A B C D", value); | 1732 EXPECT_EQ("A B C D", value); |
1685 } | 1733 } |
1686 #endif // OS_MACOSX | 1734 #endif // OS_MACOSX |
| 1735 |
| 1736 // This test verifies that focusing an input inside a <webview> will put the |
| 1737 // guest process's render widget into a monitoring mode for composition range |
| 1738 // changes. |
| 1739 IN_PROC_BROWSER_TEST_P(WebViewImeInteractiveTest, CompositionRangeUpdates) { |
| 1740 ASSERT_TRUE(StartEmbeddedTestServer()); // For serving guest pages. |
| 1741 LoadAndLaunchPlatformApp("web_view/ime", "WebViewImeTest.Launched"); |
| 1742 ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(GetPlatformAppWindow())); |
| 1743 |
| 1744 // Flush any pending events to make sure we start with a clean slate. |
| 1745 content::RunAllPendingInMessageLoop(); |
| 1746 |
| 1747 content::WebContents* guest_web_contents = |
| 1748 GetGuestViewManager()->GetLastGuestCreated(); |
| 1749 |
| 1750 // Click the <input> element inside the <webview>. In its focus handle, the |
| 1751 // <input> inside the <webview> initializes its value to "A B X D". |
| 1752 ExtensionTestMessageListener focus_listener("WebViewImeTest.InputFocused", |
| 1753 false); |
| 1754 content::WebContents* embedder_web_contents = |
| 1755 guest_view::GuestViewBase::FromWebContents(guest_web_contents) |
| 1756 ->embedder_web_contents(); |
| 1757 |
| 1758 // Event routing in OOPIF and non-OOPIF <webview> is different. With OOPIF, |
| 1759 // input is directly routed to the guest process as opposed to the non OOPIF |
| 1760 // mode where input is always sent to the embedder process first (then hops |
| 1761 // back to the browser and then to the guest). |
| 1762 content::WebContents* target_web_contents = |
| 1763 GetParam() ? guest_web_contents : embedder_web_contents; |
| 1764 |
| 1765 // The guest page has a large input box and (50, 50) lies inside the box. |
| 1766 content::SimulateMouseClickAt(target_web_contents, 0, |
| 1767 blink::WebMouseEvent::Button::kLeft, |
| 1768 gfx::Point(50, 50)); |
| 1769 focus_listener.WaitUntilSatisfied(); |
| 1770 |
| 1771 // Clear the string as it already contains some text. Then verify the text in |
| 1772 // the <input> is empty. |
| 1773 std::string value; |
| 1774 ASSERT_TRUE(ExecuteScriptAndExtractString( |
| 1775 guest_web_contents, |
| 1776 "var input = document.querySelector('input');" |
| 1777 "input.value = '';" |
| 1778 "window.domAutomationController.send(" |
| 1779 " document.querySelector('input').value)", |
| 1780 &value)); |
| 1781 EXPECT_EQ("", value); |
| 1782 |
| 1783 // Now set some composition text which should lead to an update in composition |
| 1784 // range information. |
| 1785 CompositionRangeUpdateObserver observer(embedder_web_contents); |
| 1786 content::SendImeSetCompositionTextToWidget( |
| 1787 target_web_contents->GetRenderWidgetHostView()->GetRenderWidgetHost(), |
| 1788 base::UTF8ToUTF16("ABC"), std::vector<ui::CompositionUnderline>(), |
| 1789 gfx::Range::InvalidRange(), 0, 3); |
| 1790 observer.WaitForCompositionRangeLength(3U); |
| 1791 } |
OLD | NEW |