Chromium Code Reviews| Index: chrome/browser/renderer_host/site_per_process_text_input_browsertest.cc |
| diff --git a/chrome/browser/renderer_host/site_per_process_text_input_browsertest.cc b/chrome/browser/renderer_host/site_per_process_text_input_browsertest.cc |
| index a06446b7ac41606c3d191efc851e72b01f240e52..4701b2e743d8f37dd9fee6a39de5d45b958b3ad4 100644 |
| --- a/chrome/browser/renderer_host/site_per_process_text_input_browsertest.cc |
| +++ b/chrome/browser/renderer_host/site_per_process_text_input_browsertest.cc |
| @@ -24,6 +24,7 @@ |
| #include "content/public/test/text_input_test_utils.h" |
| #include "net/dns/mock_host_resolver.h" |
| #include "net/test/embedded_test_server/embedded_test_server.h" |
| +#include "ui/base/clipboard/clipboard.h" |
| #include "ui/base/ime/composition_underline.h" |
| #include "ui/base/ime/text_edit_commands.h" |
| #include "ui/base/ime/text_input_client.h" |
| @@ -274,25 +275,44 @@ class ViewTextSelectionObserver : public TextInputManagerObserverBase { |
| class TextSelectionObserver : public TextInputManagerObserverBase { |
| public: |
| explicit TextSelectionObserver(content::WebContents* web_contents) |
| - : TextInputManagerObserverBase(web_contents) { |
| + : TextInputManagerObserverBase(web_contents), callback_called_(false) { |
|
nasko
2017/05/04 16:10:24
Has this CL been run through "git cl format"?
Peter Varga
2017/05/04 16:33:45
Yes it has been. Actually the script put this two
|
| tester()->SetOnTextSelectionChangedCallback(base::Bind( |
| &TextSelectionObserver::VerifyChange, base::Unretained(this))); |
| } |
| - void WaitForSelectedText(const std::string& text) { |
| - selected_text_ = text; |
| - Wait(); |
| + void WaitForSelectedText(const std::string& text, |
| + bool user_initiated = true) { |
| + expected_text_ = text; |
| + expected_user_initiated_ = user_initiated; |
| + if (callback_called_ && last_selected_text_ == expected_text_ && |
| + last_user_initiated_ == expected_user_initiated_) { |
| + OnSuccess(); |
| + } else { |
| + Wait(); |
| + } |
| } |
| private: |
| void VerifyChange() { |
| - if (base::UTF16ToUTF8(tester()->GetUpdatedView()->GetSelectedText()) == |
| - selected_text_) { |
| + callback_called_ = true; |
| + |
| + last_selected_text_ = |
| + base::UTF16ToUTF8(tester()->GetUpdatedView()->GetSelectedText()); |
| + EXPECT_TRUE(tester()->GetTextSelectionUserInitiatedForView( |
| + tester()->GetUpdatedView(), &last_user_initiated_)); |
| + |
| + if (last_selected_text_ == expected_text_ && |
| + last_user_initiated_ == expected_user_initiated_) { |
| OnSuccess(); |
| } |
| } |
| - std::string selected_text_; |
| + bool callback_called_; |
| + |
| + std::string last_selected_text_; |
| + std::string expected_text_; |
| + bool last_user_initiated_; |
| + bool expected_user_initiated_; |
| DISALLOW_COPY_AND_ASSIGN(TextSelectionObserver); |
| }; |
| @@ -420,6 +440,30 @@ class SitePerProcessTextInputManagerTest : public InProcessBrowserTest { |
| return current; |
| } |
| + // Simulates a click on the middle of the first DOM element |
| + // with the given |selector|. |
| + void ClickFirstElementWithSelector(const std::string& selector) { |
| + int x; |
| + ASSERT_TRUE(content::ExecuteScriptAndExtractInt( |
| + active_contents(), |
| + "var bounds = document.querySelector('" + selector + |
| + "').getBoundingClientRect();" |
| + "domAutomationController.send(" |
| + " Math.floor(bounds.left + bounds.width / 2));", |
| + &x)); |
| + int y; |
| + ASSERT_TRUE(content::ExecuteScriptAndExtractInt( |
| + active_contents(), |
| + "var bounds = document.querySelector('" + selector + |
| + "').getBoundingClientRect();" |
| + "domAutomationController.send(" |
| + " Math.floor(bounds.top + bounds.height / 2));", |
| + &y)); |
| + content::SimulateMouseClickAt(active_contents(), 0, |
| + blink::WebMouseEvent::Button::kLeft, |
| + gfx::Point(x, y)); |
| + } |
| + |
| private: |
| DISALLOW_COPY_AND_ASSIGN(SitePerProcessTextInputManagerTest); |
| }; |
| @@ -980,6 +1024,80 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessTextInputManagerTest, |
| } |
| } |
| +// This test verifies that the TextInputManager notifies about a |
| +// text selection change event for both user and non-user (eg. JavaScript) |
| +// initiated cases. It is also tested whether TextSelection::user_initiated |
| +// is properly set. The content of the selection clipboard is also tested on |
| +// platforms where it is supported. |
| +// See: https://crbug.com/671986 |
| +IN_PROC_BROWSER_TEST_F(SitePerProcessTextInputManagerTest, |
| + NonUserInitiatedTextSelection) { |
| +#if defined(USE_AURA) && defined(OS_LINUX) && !defined(OS_CHROMEOS) |
| + ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread(); |
| + EXPECT_TRUE(!!clipboard); |
| + clipboard->Clear(ui::CLIPBOARD_TYPE_SELECTION); |
| +#endif |
| + |
| + CreateIframePage("a()"); |
|
EhsanK
2017/05/04 00:16:31
I think the test belongs to somewhere else but I l
Peter Varga
2017/05/04 07:30:39
I agree with that this file is probably not the be
nasko
2017/05/04 16:10:24
Why not extend the test to cover actual OOPIFs? Th
Peter Varga
2017/05/04 16:33:45
Because I'm not sure how to test OOPIF. Any hint/s
EhsanK
2017/05/08 16:56:25
Some suggestions:
You could start by reusing some
Peter Varga
2017/05/09 06:42:29
Thank you for the suggestions. I did something sim
EhsanK
2017/05/09 15:16:16
Acknowledged.
|
| + |
| + content::RenderFrameHost* frame = GetFrame(IndexVector{}); |
| + AddInputFieldToFrame(frame, "text", "Chromium", true); |
| + |
| + // Trigger text selection from JavaScript |
| + { |
| + TextSelectionObserver observer(active_contents()); |
| + EXPECT_TRUE( |
| + ExecuteScript(frame, "document.querySelector('input').select();")); |
| + observer.WaitForSelectedText("Chromium", false); |
| + } |
| + |
| +#if defined(USE_AURA) && defined(OS_LINUX) && !defined(OS_CHROMEOS) |
| + // Non-user initiated text selection should not update the selection |
| + // clipboard. See: https://crbug.com/12392 |
| + base::string16 result_text; |
| + clipboard->ReadText(ui::CLIPBOARD_TYPE_SELECTION, &result_text); |
| + EXPECT_TRUE(result_text.empty()); |
| +#endif |
| + |
| + // Clear text selecton from JavaScript |
| + { |
| + TextSelectionObserver observer(active_contents()); |
| + EXPECT_TRUE(ExecuteScript(frame, "document.getSelection().empty();")); |
| + observer.WaitForSelectedText("", false); |
| + } |
| + |
| + // Trigger text selection by user input |
| + { |
| + TextSelectionObserver observer(active_contents()); |
| + // Click on element to have keyboard focus |
| + ASSERT_NO_FATAL_FAILURE(ClickFirstElementWithSelector("input")); |
| + // Press ctrl+a to select text in the input field |
| + SimulateKeyPress(active_contents(), ui::DomKey::FromCharacter('A'), |
| + ui::DomCode::US_A, ui::VKEY_A, true, false, false, false); |
| + observer.WaitForSelectedText("Chromium", true); |
| + } |
| + |
| +#if defined(USE_AURA) && defined(OS_LINUX) && !defined(OS_CHROMEOS) |
| + // User initiated text selection should update the selection clipboard |
| + clipboard->ReadText(ui::CLIPBOARD_TYPE_SELECTION, &result_text); |
| + EXPECT_EQ(base::ASCIIToUTF16("Chromium"), result_text); |
| +#endif |
| + |
| + // Clear text selection by user input |
| + { |
| + TextSelectionObserver observer(active_contents()); |
| + // Click on element to clear text selection |
| + ASSERT_NO_FATAL_FAILURE(ClickFirstElementWithSelector("input")); |
| + observer.WaitForSelectedText("", true); |
| + } |
| + |
| +#if defined(USE_AURA) && defined(OS_LINUX) && !defined(OS_CHROMEOS) |
| + // Empty selection should not clear the selection clipboard |
| + clipboard->ReadText(ui::CLIPBOARD_TYPE_SELECTION, &result_text); |
| + EXPECT_EQ(base::ASCIIToUTF16("Chromium"), result_text); |
| +#endif |
| +} |
| + |
| // TODO(ekaramad): The following tests are specifically written for Aura and are |
| // based on InputMethodObserver. Write similar tests for Mac/Android/Mus |
| // (crbug.com/602723). |