Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4235)

Unified Diff: chrome/browser/renderer_host/site_per_process_text_input_browsertest.cc

Issue 2856093003: Update TextSelection for non-user initiated events (Closed)
Patch Set: Update TextSelection for non-user initiated events Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « AUTHORS ('k') | content/browser/frame_host/render_frame_host_impl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..0a46c318a08cfdd360aeacf576c4c5a917a64914 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,11 +24,13 @@
#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"
#include "ui/base/ime/text_input_mode.h"
#include "ui/base/ime/text_input_type.h"
+#include "ui/base/test/ui_controls.h"
#include "url/gurl.h"
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
@@ -274,25 +276,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) {
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 +441,58 @@ class SitePerProcessTextInputManagerTest : public InProcessBrowserTest {
return current;
}
+ // Simulates a click on the middle of the first DOM element
+ // with the given |selector| in the given frame |rfh|. The |frame_index|
+ // parameter is used to find the child frame in the main frame and
+ // use its offset to calculate the click position.
+ void ClickFirstElementWithSelector(content::RenderFrameHost* rfh,
+ int frame_index,
+ const std::string& selector) {
+ int frame_x = 0;
+ int frame_y = 0;
+
+ if (rfh != active_contents()->GetMainFrame()) {
+ ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
+ active_contents()->GetMainFrame(),
+ "var frames = document.querySelectorAll('iframe');"
+ "var frame = frames[" +
+ std::to_string(frame_index) +
+ "];"
+ "domAutomationController.send(Math.floor(frame.offsetLeft));",
+ &frame_x));
+ ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
+ active_contents()->GetMainFrame(),
+ "var frames = document.querySelectorAll('iframe');"
+ "var frame = frames[" +
+ std::to_string(frame_index) +
+ "];"
+ "domAutomationController.send(Math.floor(frame.offsetTop));",
+ &frame_y));
+ }
+
+ int x;
+ ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
+ rfh,
+ "var bounds = document.querySelector('" + selector +
+ "').getBoundingClientRect();"
+ "domAutomationController.send("
+ " Math.floor(bounds.left + bounds.width / 2));",
+ &x));
+ int y;
+ ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
+ rfh,
+ "var bounds = document.querySelector('" + selector +
+ "').getBoundingClientRect();"
+ "domAutomationController.send("
+ " Math.floor(bounds.top + bounds.height / 2));",
+ &y));
+
+ auto content_bounds = active_contents()->GetContainerBounds();
+ ui_controls::SendMouseMove(x + frame_x + content_bounds.x(),
+ y + frame_y + content_bounds.y());
+ ui_controls::SendMouseClick(ui_controls::LEFT);
+ }
+
private:
DISALLOW_COPY_AND_ASSIGN(SitePerProcessTextInputManagerTest);
};
@@ -980,6 +1053,82 @@ 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);
Lei Zhang 2017/05/10 21:06:03 ASSERT_TRUE() because if this fails, the test exec
Peter Varga 2017/05/10 21:12:36 I copied this from another clipboard test. I will
+ clipboard->Clear(ui::CLIPBOARD_TYPE_SELECTION);
+#endif
+
+ CreateIframePage("a(b, c)");
+ std::vector<std::string> values{"node_a", "node_b", "node_c"};
+ std::vector<content::RenderFrameHost*> frames{GetFrame(IndexVector{}),
+ GetFrame(IndexVector{0}),
+ GetFrame(IndexVector{1})};
+
+ for (size_t i = 0; i < frames.size(); ++i)
+ AddInputFieldToFrame(frames[i], "text", values[i], true);
+
+ // Test text selection from JavaScript across frames (non-user initiated).
+ for (size_t i = 0; i < frames.size(); ++i) {
+ // Trigger text selection.
+ TextSelectionObserver trigger_observer(active_contents());
+ EXPECT_TRUE(
+ ExecuteScript(frames[i], "document.querySelector('input').select();"));
+ trigger_observer.WaitForSelectedText(values[i], 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 selection.
+ TextSelectionObserver clear_observer(active_contents());
+ EXPECT_TRUE(ExecuteScript(frames[i], "document.getSelection().empty();"));
+ clear_observer.WaitForSelectedText("", false);
+ }
+
+ // Test text selection by user input across frames (user initiated).
+ for (size_t i = 0; i < frames.size(); ++i) {
+ // Click on element to have keyboard focus.
+ TextInputManagerChangeObserver input_observer(active_contents());
+ // Index of the main frame is 0. Thus align child frame index to it (i-1).
+ ASSERT_NO_FATAL_FAILURE(
+ ClickFirstElementWithSelector(frames[i], i - 1, "input"));
+ input_observer.Wait();
+
+ // Press ctrl+a to select text in the input field.
+ TextSelectionObserver trigger_observer(active_contents());
+ SimulateKeyPress(active_contents(), ui::DomKey::FromCharacter('A'),
+ ui::DomCode::US_A, ui::VKEY_A, true, false, false, false);
+ trigger_observer.WaitForSelectedText(values[i], true);
+
+#if defined(USE_AURA) && defined(OS_LINUX) && !defined(OS_CHROMEOS)
+ // User initiated text selection should update the selection clipboard.
+ base::string16 result_text;
+ clipboard->ReadText(ui::CLIPBOARD_TYPE_SELECTION, &result_text);
+ EXPECT_EQ(base::ASCIIToUTF16(values[i]), result_text);
+#endif
+
+ // Click on element to clear text selection.
+ TextSelectionObserver clear_observer(active_contents());
+ // Index of the main frame is 0. Thus align child frame index to it (i-1).
+ ASSERT_NO_FATAL_FAILURE(
+ ClickFirstElementWithSelector(frames[i], i - 1, "input"));
+ clear_observer.WaitForSelectedText("", true);
+ }
+}
+
// 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).
« no previous file with comments | « AUTHORS ('k') | content/browser/frame_host/render_frame_host_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698