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" |
11 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 11 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
12 #include "chrome/test/base/in_process_browser_test.h" | 12 #include "chrome/test/base/in_process_browser_test.h" |
13 #include "chrome/test/base/interactive_test_utils.h" | 13 #include "chrome/test/base/interactive_test_utils.h" |
14 #include "chrome/test/base/ui_test_utils.h" | 14 #include "chrome/test/base/ui_test_utils.h" |
15 #include "content/public/browser/content_browser_client.h" | 15 #include "content/public/browser/content_browser_client.h" |
16 #include "content/public/browser/render_frame_host.h" | 16 #include "content/public/browser/render_frame_host.h" |
17 #include "content/public/browser/render_process_host.h" | 17 #include "content/public/browser/render_process_host.h" |
18 #include "content/public/browser/render_widget_host_view.h" | 18 #include "content/public/browser/render_widget_host_view.h" |
19 #include "content/public/browser/web_contents.h" | 19 #include "content/public/browser/web_contents.h" |
20 #include "content/public/common/content_client.h" | 20 #include "content/public/common/content_client.h" |
21 #include "content/public/test/browser_test_utils.h" | 21 #include "content/public/test/browser_test_utils.h" |
22 #include "content/public/test/content_browser_test_utils.h" | 22 #include "content/public/test/content_browser_test_utils.h" |
23 #include "content/public/test/test_utils.h" | 23 #include "content/public/test/test_utils.h" |
24 #include "content/public/test/text_input_test_utils.h" | 24 #include "content/public/test/text_input_test_utils.h" |
25 #include "net/dns/mock_host_resolver.h" | 25 #include "net/dns/mock_host_resolver.h" |
26 #include "net/test/embedded_test_server/embedded_test_server.h" | 26 #include "net/test/embedded_test_server/embedded_test_server.h" |
27 #include "ui/base/clipboard/clipboard.h" | |
27 #include "ui/base/ime/composition_underline.h" | 28 #include "ui/base/ime/composition_underline.h" |
28 #include "ui/base/ime/text_edit_commands.h" | 29 #include "ui/base/ime/text_edit_commands.h" |
29 #include "ui/base/ime/text_input_client.h" | 30 #include "ui/base/ime/text_input_client.h" |
30 #include "ui/base/ime/text_input_mode.h" | 31 #include "ui/base/ime/text_input_mode.h" |
31 #include "ui/base/ime/text_input_type.h" | 32 #include "ui/base/ime/text_input_type.h" |
32 #include "url/gurl.h" | 33 #include "url/gurl.h" |
33 | 34 |
34 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) | 35 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) |
35 #include "ui/base/ime/linux/text_edit_command_auralinux.h" | 36 #include "ui/base/ime/linux/text_edit_command_auralinux.h" |
36 #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" |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
267 const content::RenderWidgetHostView* const expected_view_; | 268 const content::RenderWidgetHostView* const expected_view_; |
268 const size_t expected_length_; | 269 const size_t expected_length_; |
269 | 270 |
270 DISALLOW_COPY_AND_ASSIGN(ViewTextSelectionObserver); | 271 DISALLOW_COPY_AND_ASSIGN(ViewTextSelectionObserver); |
271 }; | 272 }; |
272 | 273 |
273 // This class observes all the text selection updates within a WebContents. | 274 // This class observes all the text selection updates within a WebContents. |
274 class TextSelectionObserver : public TextInputManagerObserverBase { | 275 class TextSelectionObserver : public TextInputManagerObserverBase { |
275 public: | 276 public: |
276 explicit TextSelectionObserver(content::WebContents* web_contents) | 277 explicit TextSelectionObserver(content::WebContents* web_contents) |
277 : TextInputManagerObserverBase(web_contents) { | 278 : 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
| |
278 tester()->SetOnTextSelectionChangedCallback(base::Bind( | 279 tester()->SetOnTextSelectionChangedCallback(base::Bind( |
279 &TextSelectionObserver::VerifyChange, base::Unretained(this))); | 280 &TextSelectionObserver::VerifyChange, base::Unretained(this))); |
280 } | 281 } |
281 | 282 |
282 void WaitForSelectedText(const std::string& text) { | 283 void WaitForSelectedText(const std::string& text, |
283 selected_text_ = text; | 284 bool user_initiated = true) { |
284 Wait(); | 285 expected_text_ = text; |
286 expected_user_initiated_ = user_initiated; | |
287 if (callback_called_ && last_selected_text_ == expected_text_ && | |
288 last_user_initiated_ == expected_user_initiated_) { | |
289 OnSuccess(); | |
290 } else { | |
291 Wait(); | |
292 } | |
285 } | 293 } |
286 | 294 |
287 private: | 295 private: |
288 void VerifyChange() { | 296 void VerifyChange() { |
289 if (base::UTF16ToUTF8(tester()->GetUpdatedView()->GetSelectedText()) == | 297 callback_called_ = true; |
290 selected_text_) { | 298 |
299 last_selected_text_ = | |
300 base::UTF16ToUTF8(tester()->GetUpdatedView()->GetSelectedText()); | |
301 EXPECT_TRUE(tester()->GetTextSelectionUserInitiatedForView( | |
302 tester()->GetUpdatedView(), &last_user_initiated_)); | |
303 | |
304 if (last_selected_text_ == expected_text_ && | |
305 last_user_initiated_ == expected_user_initiated_) { | |
291 OnSuccess(); | 306 OnSuccess(); |
292 } | 307 } |
293 } | 308 } |
294 | 309 |
295 std::string selected_text_; | 310 bool callback_called_; |
311 | |
312 std::string last_selected_text_; | |
313 std::string expected_text_; | |
314 bool last_user_initiated_; | |
315 bool expected_user_initiated_; | |
296 | 316 |
297 DISALLOW_COPY_AND_ASSIGN(TextSelectionObserver); | 317 DISALLOW_COPY_AND_ASSIGN(TextSelectionObserver); |
298 }; | 318 }; |
299 | 319 |
300 // This class monitors all the changes in TextInputState and keeps a record of | 320 // This class monitors all the changes in TextInputState and keeps a record of |
301 // the active views. There is no waiting and the recording process is | 321 // the active views. There is no waiting and the recording process is |
302 // continuous. | 322 // continuous. |
303 class RecordActiveViewsObserver { | 323 class RecordActiveViewsObserver { |
304 public: | 324 public: |
305 explicit RecordActiveViewsObserver(content::WebContents* web_contents) | 325 explicit RecordActiveViewsObserver(content::WebContents* web_contents) |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
413 // Iteratively uses ChildFrameAt(frame, i) to get the i-th child frame | 433 // Iteratively uses ChildFrameAt(frame, i) to get the i-th child frame |
414 // inside frame. For example, for 'a(b(c, d(e)))', [0] returns b, and | 434 // inside frame. For example, for 'a(b(c, d(e)))', [0] returns b, and |
415 // [0, 1, 0] returns e; | 435 // [0, 1, 0] returns e; |
416 content::RenderFrameHost* GetFrame(const IndexVector& indices) { | 436 content::RenderFrameHost* GetFrame(const IndexVector& indices) { |
417 content::RenderFrameHost* current = active_contents()->GetMainFrame(); | 437 content::RenderFrameHost* current = active_contents()->GetMainFrame(); |
418 for (size_t index : indices) | 438 for (size_t index : indices) |
419 current = ChildFrameAt(current, index); | 439 current = ChildFrameAt(current, index); |
420 return current; | 440 return current; |
421 } | 441 } |
422 | 442 |
443 // Simulates a click on the middle of the first DOM element | |
444 // with the given |selector|. | |
445 void ClickFirstElementWithSelector(const std::string& selector) { | |
446 int x; | |
447 ASSERT_TRUE(content::ExecuteScriptAndExtractInt( | |
448 active_contents(), | |
449 "var bounds = document.querySelector('" + selector + | |
450 "').getBoundingClientRect();" | |
451 "domAutomationController.send(" | |
452 " Math.floor(bounds.left + bounds.width / 2));", | |
453 &x)); | |
454 int y; | |
455 ASSERT_TRUE(content::ExecuteScriptAndExtractInt( | |
456 active_contents(), | |
457 "var bounds = document.querySelector('" + selector + | |
458 "').getBoundingClientRect();" | |
459 "domAutomationController.send(" | |
460 " Math.floor(bounds.top + bounds.height / 2));", | |
461 &y)); | |
462 content::SimulateMouseClickAt(active_contents(), 0, | |
463 blink::WebMouseEvent::Button::kLeft, | |
464 gfx::Point(x, y)); | |
465 } | |
466 | |
423 private: | 467 private: |
424 DISALLOW_COPY_AND_ASSIGN(SitePerProcessTextInputManagerTest); | 468 DISALLOW_COPY_AND_ASSIGN(SitePerProcessTextInputManagerTest); |
425 }; | 469 }; |
426 | 470 |
427 // The following test loads a page with multiple nested <iframe> elements which | 471 // The following test loads a page with multiple nested <iframe> elements which |
428 // are in or out of process with the main frame. Then an <input> field with | 472 // are in or out of process with the main frame. Then an <input> field with |
429 // unique value is added to every single frame on the frame tree. The test then | 473 // unique value is added to every single frame on the frame tree. The test then |
430 // creates a sequence of tab presses and verifies that after each key press, the | 474 // creates a sequence of tab presses and verifies that after each key press, the |
431 // TextInputState.value reflects that of the focused input, i.e., the | 475 // TextInputState.value reflects that of the focused input, i.e., the |
432 // TextInputManager is correctly tracking TextInputState across frames. | 476 // TextInputManager is correctly tracking TextInputState across frames. |
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
973 }; | 1017 }; |
974 | 1018 |
975 for (auto* frame : frames) { | 1019 for (auto* frame : frames) { |
976 focus_frame_and_input(frame); | 1020 focus_frame_and_input(frame); |
977 EXPECT_TRUE(active_contents()->IsFocusedElementEditable()); | 1021 EXPECT_TRUE(active_contents()->IsFocusedElementEditable()); |
978 active_contents()->ClearFocusedElement(); | 1022 active_contents()->ClearFocusedElement(); |
979 EXPECT_FALSE(active_contents()->IsFocusedElementEditable()); | 1023 EXPECT_FALSE(active_contents()->IsFocusedElementEditable()); |
980 } | 1024 } |
981 } | 1025 } |
982 | 1026 |
1027 // This test verifies that the TextInputManager notifies about a | |
1028 // text selection change event for both user and non-user (eg. JavaScript) | |
1029 // initiated cases. It is also tested whether TextSelection::user_initiated | |
1030 // is properly set. The content of the selection clipboard is also tested on | |
1031 // platforms where it is supported. | |
1032 // See: https://crbug.com/671986 | |
1033 IN_PROC_BROWSER_TEST_F(SitePerProcessTextInputManagerTest, | |
1034 NonUserInitiatedTextSelection) { | |
1035 #if defined(USE_AURA) && defined(OS_LINUX) && !defined(OS_CHROMEOS) | |
1036 ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread(); | |
1037 EXPECT_TRUE(!!clipboard); | |
1038 clipboard->Clear(ui::CLIPBOARD_TYPE_SELECTION); | |
1039 #endif | |
1040 | |
1041 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.
| |
1042 | |
1043 content::RenderFrameHost* frame = GetFrame(IndexVector{}); | |
1044 AddInputFieldToFrame(frame, "text", "Chromium", true); | |
1045 | |
1046 // Trigger text selection from JavaScript | |
1047 { | |
1048 TextSelectionObserver observer(active_contents()); | |
1049 EXPECT_TRUE( | |
1050 ExecuteScript(frame, "document.querySelector('input').select();")); | |
1051 observer.WaitForSelectedText("Chromium", false); | |
1052 } | |
1053 | |
1054 #if defined(USE_AURA) && defined(OS_LINUX) && !defined(OS_CHROMEOS) | |
1055 // Non-user initiated text selection should not update the selection | |
1056 // clipboard. See: https://crbug.com/12392 | |
1057 base::string16 result_text; | |
1058 clipboard->ReadText(ui::CLIPBOARD_TYPE_SELECTION, &result_text); | |
1059 EXPECT_TRUE(result_text.empty()); | |
1060 #endif | |
1061 | |
1062 // Clear text selecton from JavaScript | |
1063 { | |
1064 TextSelectionObserver observer(active_contents()); | |
1065 EXPECT_TRUE(ExecuteScript(frame, "document.getSelection().empty();")); | |
1066 observer.WaitForSelectedText("", false); | |
1067 } | |
1068 | |
1069 // Trigger text selection by user input | |
1070 { | |
1071 TextSelectionObserver observer(active_contents()); | |
1072 // Click on element to have keyboard focus | |
1073 ASSERT_NO_FATAL_FAILURE(ClickFirstElementWithSelector("input")); | |
1074 // Press ctrl+a to select text in the input field | |
1075 SimulateKeyPress(active_contents(), ui::DomKey::FromCharacter('A'), | |
1076 ui::DomCode::US_A, ui::VKEY_A, true, false, false, false); | |
1077 observer.WaitForSelectedText("Chromium", true); | |
1078 } | |
1079 | |
1080 #if defined(USE_AURA) && defined(OS_LINUX) && !defined(OS_CHROMEOS) | |
1081 // User initiated text selection should update the selection clipboard | |
1082 clipboard->ReadText(ui::CLIPBOARD_TYPE_SELECTION, &result_text); | |
1083 EXPECT_EQ(base::ASCIIToUTF16("Chromium"), result_text); | |
1084 #endif | |
1085 | |
1086 // Clear text selection by user input | |
1087 { | |
1088 TextSelectionObserver observer(active_contents()); | |
1089 // Click on element to clear text selection | |
1090 ASSERT_NO_FATAL_FAILURE(ClickFirstElementWithSelector("input")); | |
1091 observer.WaitForSelectedText("", true); | |
1092 } | |
1093 | |
1094 #if defined(USE_AURA) && defined(OS_LINUX) && !defined(OS_CHROMEOS) | |
1095 // Empty selection should not clear the selection clipboard | |
1096 clipboard->ReadText(ui::CLIPBOARD_TYPE_SELECTION, &result_text); | |
1097 EXPECT_EQ(base::ASCIIToUTF16("Chromium"), result_text); | |
1098 #endif | |
1099 } | |
1100 | |
983 // TODO(ekaramad): The following tests are specifically written for Aura and are | 1101 // TODO(ekaramad): The following tests are specifically written for Aura and are |
984 // based on InputMethodObserver. Write similar tests for Mac/Android/Mus | 1102 // based on InputMethodObserver. Write similar tests for Mac/Android/Mus |
985 // (crbug.com/602723). | 1103 // (crbug.com/602723). |
986 #if defined(USE_AURA) | 1104 #if defined(USE_AURA) |
987 // ----------------------------------------------------------------------------- | 1105 // ----------------------------------------------------------------------------- |
988 // Input Method Observer Tests | 1106 // Input Method Observer Tests |
989 // | 1107 // |
990 // The following tests will make use of the InputMethodObserver to verify that | 1108 // The following tests will make use of the InputMethodObserver to verify that |
991 // OOPIF pages interact properly with the InputMethod through the tab's view. | 1109 // OOPIF pages interact properly with the InputMethod through the tab's view. |
992 | 1110 |
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1367 | 1485 |
1368 // Closing this WebContents while we still hold on to our TestBrowserClient. | 1486 // Closing this WebContents while we still hold on to our TestBrowserClient. |
1369 EXPECT_TRUE(browser()->tab_strip_model()->CloseWebContentsAt( | 1487 EXPECT_TRUE(browser()->tab_strip_model()->CloseWebContentsAt( |
1370 1, TabStripModel::CLOSE_USER_GESTURE)); | 1488 1, TabStripModel::CLOSE_USER_GESTURE)); |
1371 | 1489 |
1372 // For the cleanup of the original WebContents in tab index 0. | 1490 // For the cleanup of the original WebContents in tab index 0. |
1373 content::SetBrowserClientForTesting(old_browser_client); | 1491 content::SetBrowserClientForTesting(old_browser_client); |
1374 } | 1492 } |
1375 #endif // defined(MAC_OSX) | 1493 #endif // defined(MAC_OSX) |
1376 #endif // !defined(OS_ANDROID) | 1494 #endif // !defined(OS_ANDROID) |
OLD | NEW |