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). |