Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 <vector> | 5 #include <vector> |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
| 9 #include "chrome/browser/chrome_content_browser_client.h" | 9 #include "chrome/browser/chrome_content_browser_client.h" |
| 10 #include "chrome/browser/ui/browser.h" | 10 #include "chrome/browser/ui/browser.h" |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 30 #include "ui/base/ime/text_input_client.h" | 30 #include "ui/base/ime/text_input_client.h" |
| 31 #include "ui/base/ime/text_input_mode.h" | 31 #include "ui/base/ime/text_input_mode.h" |
| 32 #include "ui/base/ime/text_input_type.h" | 32 #include "ui/base/ime/text_input_type.h" |
| 33 #include "url/gurl.h" | 33 #include "url/gurl.h" |
| 34 | 34 |
| 35 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) | 35 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) |
| 36 #include "ui/base/ime/linux/text_edit_command_auralinux.h" | 36 #include "ui/base/ime/linux/text_edit_command_auralinux.h" |
| 37 #include "ui/base/ime/linux/text_edit_key_bindings_delegate_auralinux.h" | 37 #include "ui/base/ime/linux/text_edit_key_bindings_delegate_auralinux.h" |
| 38 #endif | 38 #endif |
| 39 | 39 |
| 40 // TODO(ekaramad): The following tests should be active on all platforms. After | |
| 41 // fixing https://crbug.com/578168, this test file should be built for android | |
| 42 // as well and most of the following tests should be enabled for all platforms | |
| 43 //(https://crbug.com/602723). | |
| 44 | |
| 45 /////////////////////////////////////////////////////////////////////////////// | 40 /////////////////////////////////////////////////////////////////////////////// |
| 46 // TextInputManager and IME Tests | 41 // TextInputManager and IME Tests |
| 47 // | 42 // |
| 48 // The following tests verify the correctness of TextInputState tracking on the | 43 // The following tests verify the correctness of TextInputState tracking on the |
| 49 // browser side. They also make sure the IME logic works correctly. The baseline | 44 // browser side. They also make sure the IME logic works correctly. The baseline |
| 50 // for comparison is the default functionality in the non-OOPIF case (i.e., the | 45 // for comparison is the default functionality in the non-OOPIF case (i.e., the |
| 51 // legacy implementation in RWHV's other than RWHVCF). | 46 // legacy implementation in RWHV's other than RWHVCF). |
| 52 // These tests live outside content/ because they rely on being part of the | 47 // These tests live outside content/ because they rely on being part of the |
| 53 // interactive UI test framework (to avoid flakiness). | 48 // interactive UI test framework (to avoid flakiness). |
| 54 | 49 |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 327 } | 322 } |
| 328 | 323 |
| 329 protected: | 324 protected: |
| 330 content::WebContents* active_contents() { | 325 content::WebContents* active_contents() { |
| 331 return browser()->tab_strip_model()->GetActiveWebContents(); | 326 return browser()->tab_strip_model()->GetActiveWebContents(); |
| 332 } | 327 } |
| 333 | 328 |
| 334 // static | 329 // static |
| 335 // Adds an <input> field to a given frame by executing javascript code. | 330 // Adds an <input> field to a given frame by executing javascript code. |
| 336 // The input can be added as the first element or the last element of | 331 // The input can be added as the first element or the last element of |
| 337 // |document.body|. The text range defined by |selection_range| will be | 332 // |document.body|. |
| 338 // marked. | |
| 339 static void AddInputFieldToFrame(content::RenderFrameHost* rfh, | 333 static void AddInputFieldToFrame(content::RenderFrameHost* rfh, |
| 340 const std::string& type, | 334 const std::string& type, |
| 341 const std::string& value, | 335 const std::string& value, |
| 342 bool append_as_first_child) { | 336 bool append_as_first_child) { |
| 343 std::string script = base::StringPrintf( | 337 std::string script = base::StringPrintf( |
| 344 "var input = document.createElement('input');" | 338 "var input = document.createElement('input');" |
| 345 "input.setAttribute('type', '%s');" | 339 "input.setAttribute('type', '%s');" |
| 346 "input.setAttribute('value', '%s');" | 340 "input.setAttribute('value', '%s');" |
| 347 "document.body.%s;", | 341 "document.body.%s;", |
| 348 type.c_str(), value.c_str(), | 342 type.c_str(), value.c_str(), |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 570 SimulateKeyPress(active_contents(), ui::DomKey::TAB, ui::DomCode::TAB, | 564 SimulateKeyPress(active_contents(), ui::DomKey::TAB, ui::DomCode::TAB, |
| 571 ui::VKEY_TAB, false, false, false, false); | 565 ui::VKEY_TAB, false, false, false, false); |
| 572 set_state_observer.Wait(); | 566 set_state_observer.Wait(); |
| 573 | 567 |
| 574 TextInputManagerTypeObserver reset_state_observer(active_contents(), | 568 TextInputManagerTypeObserver reset_state_observer(active_contents(), |
| 575 ui::TEXT_INPUT_TYPE_NONE); | 569 ui::TEXT_INPUT_TYPE_NONE); |
| 576 ui_test_utils::NavigateToURL(browser(), GURL("about:blank")); | 570 ui_test_utils::NavigateToURL(browser(), GURL("about:blank")); |
| 577 reset_state_observer.Wait(); | 571 reset_state_observer.Wait(); |
| 578 } | 572 } |
| 579 | 573 |
| 574 // The following test verifies that when the active widget changes value, it is | |
| 575 // always from nullptr to non-null or vice versa. | |
| 576 IN_PROC_BROWSER_TEST_F(SitePerProcessTextInputManagerTest, | |
| 577 ResetTextInputStateOnActiveWidgetChange) { | |
| 578 CreateIframePage("a(b,c(a,b),d)"); | |
| 579 std::vector<content::RenderFrameHost*> frames{ | |
| 580 GetFrame(IndexVector{}), GetFrame(IndexVector{0}), | |
| 581 GetFrame(IndexVector{1}), GetFrame(IndexVector{1, 0}), | |
| 582 GetFrame(IndexVector{1, 1}), GetFrame(IndexVector{2})}; | |
| 583 std::vector<content::RenderWidgetHostView*> views; | |
| 584 for (auto frame : frames) | |
| 585 views.push_back(frame->GetView()); | |
| 586 std::vector<std::string> values{"a", "ab", "ac", "aca", "acb", "acd"}; | |
| 587 for (size_t i = 0; i < frames.size(); ++i) | |
| 588 AddInputFieldToFrame(frames[i], "text", values[i], true); | |
| 589 | |
| 590 content::WebContents* web_contents = active_contents(); | |
| 591 | |
| 592 auto send_tab_and_wait_for_value = | |
| 593 [&web_contents](const std::string& expected_value) { | |
| 594 TextInputManagerValueObserver observer(web_contents, expected_value); | |
| 595 SimulateKeyPress(web_contents, ui::DomKey::TAB, ui::DomCode::TAB, | |
| 596 ui::VKEY_TAB, false, false, false, false); | |
| 597 observer.Wait(); | |
| 598 }; | |
| 599 | |
| 600 // Record all active view changes. | |
| 601 RecordActiveViewsObserver recorder(web_contents); | |
| 602 for (auto value : values) | |
| 603 send_tab_and_wait_for_value(value); | |
| 604 | |
| 605 // We have covered a total of 6 views, so there should at least be 11 entries | |
| 606 // recorded (at least one null between two views). | |
| 607 size_t record_count = recorder.active_views()->size(); | |
| 608 EXPECT_GT(record_count, 10U); | |
| 609 | |
| 610 // Verify we do not have subsequent nullptr or non-nullptrs. | |
| 611 for (size_t i = 0; i < record_count - 1U; ++i) { | |
| 612 const content::RenderWidgetHostView* current = | |
| 613 recorder.active_views()->at(i); | |
| 614 const content::RenderWidgetHostView* next = | |
| 615 recorder.active_views()->at(i + 1U); | |
| 616 EXPECT_TRUE((current != nullptr && next == nullptr) || | |
| 617 (current == nullptr && next != nullptr)); | |
| 618 } | |
| 619 } | |
| 620 | |
| 621 #if !defined(OS_ANDROID) | |
|
kenrb
2016/11/02 17:22:48
You removed the comment with the bug reference for
EhsanK
2016/11/02 20:45:52
I added it back to where !defined(OS_ANDROID) will
| |
| 580 // This test creates a page with multiple child frames and adds an <input> to | 622 // This test creates a page with multiple child frames and adds an <input> to |
| 581 // each frame. Then, sequentially, each <input> is focused by sending a tab key. | 623 // each frame. Then, sequentially, each <input> is focused by sending a tab key. |
| 582 // Then, after |TextInputState.type| for a view is changed to text, the test | 624 // Then, after |TextInputState.type| for a view is changed to text, the test |
| 583 // sends a set composition IPC to the active widget and waits until the widget | 625 // sends a set composition IPC to the active widget and waits until the widget |
| 584 // updates its composition range. | 626 // updates its composition range. |
| 585 IN_PROC_BROWSER_TEST_F(SitePerProcessTextInputManagerTest, | 627 IN_PROC_BROWSER_TEST_F(SitePerProcessTextInputManagerTest, |
| 586 TrackCompositionRangeForAllFrames) { | 628 TrackCompositionRangeForAllFrames) { |
| 587 CreateIframePage("a(b,c(a,b),d)"); | 629 CreateIframePage("a(b,c(a,b),d)"); |
| 588 std::vector<content::RenderFrameHost*> frames{ | 630 std::vector<content::RenderFrameHost*> frames{ |
| 589 GetFrame(IndexVector{}), GetFrame(IndexVector{0}), | 631 GetFrame(IndexVector{}), GetFrame(IndexVector{0}), |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 695 for (size_t i = 0; i < views.size(); ++i) { | 737 for (size_t i = 0; i < views.size(); ++i) { |
| 696 // First focus the <input>. | 738 // First focus the <input>. |
| 697 send_tab_and_wait_for_value(values[i]); | 739 send_tab_and_wait_for_value(values[i]); |
| 698 | 740 |
| 699 // Send a sequence of |count| 'E' keys and wait until the view receives a | 741 // Send a sequence of |count| 'E' keys and wait until the view receives a |
| 700 // selection change update for a text of the corresponding size, |count|. | 742 // selection change update for a text of the corresponding size, |count|. |
| 701 send_keys_select_all_wait_for_selection_change(views[i], count++); | 743 send_keys_select_all_wait_for_selection_change(views[i], count++); |
| 702 } | 744 } |
| 703 } | 745 } |
| 704 | 746 |
| 705 // The following test verifies that when the active widget changes value, it is | |
| 706 // always from nullptr to non-null or vice versa. | |
| 707 IN_PROC_BROWSER_TEST_F(SitePerProcessTextInputManagerTest, | |
| 708 ResetTextInputStateOnActiveWidgetChange) { | |
| 709 CreateIframePage("a(b,c(a,b),d)"); | |
| 710 std::vector<content::RenderFrameHost*> frames{ | |
| 711 GetFrame(IndexVector{}), GetFrame(IndexVector{0}), | |
| 712 GetFrame(IndexVector{1}), GetFrame(IndexVector{1, 0}), | |
| 713 GetFrame(IndexVector{1, 1}), GetFrame(IndexVector{2})}; | |
| 714 std::vector<content::RenderWidgetHostView*> views; | |
| 715 for (auto frame : frames) | |
| 716 views.push_back(frame->GetView()); | |
| 717 std::vector<std::string> values{"a", "ab", "ac", "aca", "acb", "acd"}; | |
| 718 for (size_t i = 0; i < frames.size(); ++i) | |
| 719 AddInputFieldToFrame(frames[i], "text", values[i], true); | |
| 720 | |
| 721 content::WebContents* web_contents = active_contents(); | |
| 722 | |
| 723 auto send_tab_and_wait_for_value = | |
| 724 [&web_contents](const std::string& expected_value) { | |
| 725 TextInputManagerValueObserver observer(web_contents, expected_value); | |
| 726 SimulateKeyPress(web_contents, ui::DomKey::TAB, ui::DomCode::TAB, | |
| 727 ui::VKEY_TAB, false, false, false, false); | |
| 728 observer.Wait(); | |
| 729 }; | |
| 730 | |
| 731 // Record all active view changes. | |
| 732 RecordActiveViewsObserver recorder(web_contents); | |
| 733 for (auto value : values) | |
| 734 send_tab_and_wait_for_value(value); | |
| 735 | |
| 736 // We have covered a total of 6 views, so there should at least be 11 entries | |
| 737 // recorded (at least one null between two views). | |
| 738 size_t record_count = recorder.active_views()->size(); | |
| 739 EXPECT_GT(record_count, 10U); | |
| 740 | |
| 741 // Verify we do not have subsequent nullptr or non-nullptrs. | |
| 742 for (size_t i = 0; i < record_count - 1U; ++i) { | |
| 743 const content::RenderWidgetHostView* current = | |
| 744 recorder.active_views()->at(i); | |
| 745 const content::RenderWidgetHostView* next = | |
| 746 recorder.active_views()->at(i + 1U); | |
| 747 EXPECT_TRUE((current != nullptr && next == nullptr) || | |
| 748 (current == nullptr && next != nullptr)); | |
| 749 } | |
| 750 } | |
| 751 | |
| 752 // TODO(ekaramad): The following tests are specifically written for Aura and are | 747 // TODO(ekaramad): The following tests are specifically written for Aura and are |
| 753 // based on InputMethodObserver. Write similar tests for Mac/Android/Mus | 748 // based on InputMethodObserver. Write similar tests for Mac/Android/Mus |
| 754 // (crbug.com/602723). | 749 // (crbug.com/602723). |
| 755 | 750 |
| 756 #if defined(USE_AURA) | 751 #if defined(USE_AURA) |
| 757 // ----------------------------------------------------------------------------- | 752 // ----------------------------------------------------------------------------- |
| 758 // Input Method Observer Tests | 753 // Input Method Observer Tests |
| 759 // | 754 // |
| 760 // The following tests will make use of the InputMethodObserver to verify that | 755 // The following tests will make use of the InputMethodObserver to verify that |
| 761 // OOPIF pages interact properly with the InputMethod through the tab's view. | 756 // OOPIF pages interact properly with the InputMethod through the tab's view. |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 946 true, true, true, false)); | 941 true, true, true, false)); |
| 947 ui::SetTextEditKeyBindingsDelegate(old_delegate); | 942 ui::SetTextEditKeyBindingsDelegate(old_delegate); |
| 948 | 943 |
| 949 // Verify that the input field in the subframe is erased. | 944 // Verify that the input field in the subframe is erased. |
| 950 EXPECT_TRUE(ExecuteScriptAndExtractString( | 945 EXPECT_TRUE(ExecuteScriptAndExtractString( |
| 951 child, "window.domAutomationController.send(getInputFieldText());", | 946 child, "window.domAutomationController.send(getInputFieldText());", |
| 952 &result)); | 947 &result)); |
| 953 EXPECT_EQ("", result); | 948 EXPECT_EQ("", result); |
| 954 } | 949 } |
| 955 #endif | 950 #endif |
| 956 | 951 #endif // OS_ANDROID |
| 957 // Ideally, the following code + test should be live in | |
| 958 // 'site_per_process_mac_browsertest.mm'. However, the test | |
| 959 // 'LookUpStringForRangeRoutesToFocusedWidget' relies on an override in | |
| 960 // ContentBrowserClient to register its filters in time. In content shell, we | |
| 961 // cannot have two instances of ShellContentBrowserClient (due to a DCHECK in | |
| 962 // the ctor). Therefore, we put the test here to use ChromeContentBrowserClient | |
| 963 // which does not have the same singleton constraint. | |
| 964 #if defined(OS_MACOSX) | |
| 965 // An observer of number of open windows. | |
| 966 class WindowCountObserver { | |
| 967 public: | |
| 968 explicit WindowCountObserver(size_t lower_limit) : limit_(lower_limit) {} | |
| 969 ~WindowCountObserver() {} | |
| 970 | |
| 971 // Keep polling the count of open windows until the number exceeds |limit_|. | |
| 972 void WaitForLimitOrMore() { | |
| 973 size_t current_count = content::GetOpenNSWindowsCount(); | |
| 974 if (current_count >= limit_) | |
| 975 return; | |
| 976 | |
| 977 message_loop_runner_ = new content::MessageLoopRunner(); | |
| 978 message_loop_runner_->Run(); | |
| 979 content::BrowserThread::PostTask( | |
| 980 content::BrowserThread::UI, FROM_HERE, | |
| 981 base::Bind(&WindowCountObserver::CheckWindowCount, | |
| 982 base::Unretained(this))); | |
| 983 } | |
| 984 | |
| 985 private: | |
| 986 void CheckWindowCount() { | |
| 987 size_t current_count = content::GetOpenNSWindowsCount(); | |
| 988 if (current_count >= limit_) { | |
| 989 message_loop_runner_->Quit(); | |
| 990 return; | |
| 991 } | |
| 992 content::BrowserThread::PostTask( | |
| 993 content::BrowserThread::UI, FROM_HERE, | |
| 994 base::Bind(&WindowCountObserver::CheckWindowCount, | |
| 995 base::Unretained(this))); | |
| 996 } | |
| 997 | |
| 998 size_t limit_; | |
| 999 scoped_refptr<content::MessageLoopRunner> message_loop_runner_; | |
| 1000 | |
| 1001 DISALLOW_COPY_AND_ASSIGN(WindowCountObserver); | |
| 1002 }; | |
| 1003 | |
| 1004 // The original TextInputClientMessageFilter is added during the initialization | |
| 1005 // phase of RenderProcessHost. The only chance we have to add the test filter | |
| 1006 // (so that it can receive the TextInputClientMac incoming IPC messages) is | |
| 1007 // during the call to RenderProcessWillLaunch() on ContentBrowserClient. This | |
| 1008 // class provides that for testing. | |
| 1009 class TestBrowserClient : public ChromeContentBrowserClient { | |
| 1010 public: | |
| 1011 TestBrowserClient() {} | |
| 1012 ~TestBrowserClient() override {} | |
| 1013 | |
| 1014 // ContentBrowserClient overrides. | |
| 1015 void RenderProcessWillLaunch( | |
| 1016 content::RenderProcessHost* process_host) override { | |
| 1017 ChromeContentBrowserClient::RenderProcessWillLaunch(process_host); | |
| 1018 filters_.push_back( | |
| 1019 new content::TestTextInputClientMessageFilter(process_host)); | |
| 1020 } | |
| 1021 | |
| 1022 // Retrieves the registered filter for the given RenderProcessHost. It will | |
| 1023 // return false if the RenderProcessHost was initialized while a different | |
| 1024 // instance of ContentBrowserClient was in action. | |
| 1025 scoped_refptr<content::TestTextInputClientMessageFilter> | |
| 1026 GetTextInputClientMessageFilterForProcess( | |
| 1027 content::RenderProcessHost* process_host) const { | |
| 1028 for (auto filter : filters_) { | |
| 1029 if (filter->process() == process_host) | |
| 1030 return filter; | |
| 1031 } | |
| 1032 return nullptr; | |
| 1033 } | |
| 1034 | |
| 1035 private: | |
| 1036 std::vector<scoped_refptr<content::TestTextInputClientMessageFilter>> | |
| 1037 filters_; | |
| 1038 | |
| 1039 DISALLOW_COPY_AND_ASSIGN(TestBrowserClient); | |
| 1040 }; | |
| 1041 | |
| 1042 // This test verifies that requests for dictionary lookup based on selection | |
| 1043 // range are routed to the focused RenderWidgetHost. | |
| 1044 IN_PROC_BROWSER_TEST_F(SitePerProcessTextInputManagerTest, | |
| 1045 LookUpStringForRangeRoutesToFocusedWidget) { | |
|
kenrb
2016/11/02 17:22:48
Why is this test being removed?
EhsanK
2016/11/02 20:45:52
I lost this part in the rebase (the conflict was i
| |
| 1046 // TestBrowserClient needs to replace the ChromeContenBrowserClient after most | |
| 1047 // things are initialized but before the WebContents is created. Here we make | |
| 1048 // that happen by creating a new WebContents in a new tab. But before the test | |
| 1049 // exits, we must destroy the contents and replace the old | |
| 1050 // ContentBrowserClient because the original WebContents and the new one have | |
| 1051 // been initialized with the original ContentBrowserClient and the new | |
| 1052 // TestBrowserClient, respectively. | |
| 1053 TestBrowserClient browser_client; | |
| 1054 content::ContentBrowserClient* old_browser_client = | |
| 1055 content::SetBrowserClientForTesting(&browser_client); | |
| 1056 | |
| 1057 content::WebContents* new_contents = | |
| 1058 content::WebContents::Create(content::WebContents::CreateParams( | |
| 1059 active_contents()->GetBrowserContext(), nullptr)); | |
| 1060 browser()->tab_strip_model()->InsertWebContentsAt(1, new_contents, | |
| 1061 TabStripModel::ADD_ACTIVE); | |
| 1062 EXPECT_EQ(active_contents(), new_contents); | |
| 1063 | |
| 1064 // Starting the test body. | |
| 1065 CreateIframePage("a(b)"); | |
| 1066 std::vector<content::RenderFrameHost*> frames{GetFrame(IndexVector{}), | |
| 1067 GetFrame(IndexVector{0})}; | |
| 1068 std::vector<content::RenderWidgetHostView*> views; | |
| 1069 for (auto frame : frames) | |
| 1070 views.push_back(frame->GetView()); | |
| 1071 std::vector<std::string> values{"main frame", "child frame"}; | |
| 1072 | |
| 1073 // Adding some field with text to each frame so that we can later query for | |
| 1074 // dictionary lookup. | |
| 1075 for (size_t i = 0; i < frames.size(); ++i) | |
| 1076 AddInputFieldToFrame(frames[i], "text", values[i], true); | |
| 1077 | |
| 1078 std::string result; | |
| 1079 // Recording window count now so that our WindowCountObserver will detect the | |
| 1080 // popup window. | |
| 1081 size_t current_window_count = content::GetOpenNSWindowsCount(); | |
| 1082 | |
| 1083 // Ensure we have both focus and selected text inside the main frame. | |
| 1084 EXPECT_TRUE( | |
| 1085 ExecuteScript(frames[0], "document.querySelector('input').focus();")); | |
| 1086 | |
| 1087 // Request for the dictionary lookup and intercept the word on its way back. | |
| 1088 // The request is always on the tab's view which is a RenderWidgetHostViewMac. | |
| 1089 content::AskForLookUpDictionaryForRange(views[0], gfx::Range(0, 4)); | |
| 1090 | |
| 1091 // Wait until the result comes back. | |
| 1092 auto root_filter = browser_client.GetTextInputClientMessageFilterForProcess( | |
| 1093 frames[0]->GetProcess()); | |
| 1094 EXPECT_TRUE(root_filter); | |
| 1095 root_filter->WaitForStringFromRange(); | |
| 1096 | |
| 1097 EXPECT_EQ("main", root_filter->string_from_range()); | |
| 1098 | |
| 1099 // Wait for the popup to appear to make sure TextInputClientMac has consumed | |
| 1100 // the reply handler for the previous request. | |
| 1101 WindowCountObserver(current_window_count).WaitForLimitOrMore(); | |
| 1102 | |
| 1103 // Ensure we have both focus and selected text inside the child frame. | |
| 1104 EXPECT_TRUE( | |
| 1105 ExecuteScript(frames[1], "document.querySelector('input').focus();")); | |
| 1106 | |
| 1107 // Record window count again for the popup observer. | |
| 1108 current_window_count = content::GetOpenNSWindowsCount(); | |
| 1109 | |
| 1110 // Make another request. | |
| 1111 content::AskForLookUpDictionaryForRange(views[0], gfx::Range(0, 5)); | |
| 1112 | |
| 1113 // Wait until the result comes back. | |
| 1114 auto child_filter = browser_client.GetTextInputClientMessageFilterForProcess( | |
| 1115 frames[1]->GetProcess()); | |
| 1116 child_filter->WaitForStringFromRange(); | |
| 1117 | |
| 1118 EXPECT_EQ("child", child_filter->string_from_range()); | |
| 1119 | |
| 1120 // Wait for the popup to appear to make sure TextInputClientMac has consumed | |
| 1121 // the reply handler for the previous request. | |
| 1122 WindowCountObserver(current_window_count).WaitForLimitOrMore(); | |
| 1123 // Test ends here. The rest is cleanup. | |
| 1124 | |
| 1125 // Closing this WebContents while we still hold on to our TestBrowserClient. | |
| 1126 EXPECT_TRUE(browser()->tab_strip_model()->CloseWebContentsAt( | |
| 1127 1, TabStripModel::CLOSE_USER_GESTURE)); | |
| 1128 | |
| 1129 // For the cleanup of the original WebContents in tab index 0. | |
| 1130 content::SetBrowserClientForTesting(old_browser_client); | |
| 1131 } | |
| 1132 #endif | |
| OLD | NEW |