OLD | NEW |
| (Empty) |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "base/message_loop.h" | |
6 #include "chrome/browser/browser.h" | |
7 #include "chrome/browser/find_notification_details.h" | |
8 #include "chrome/browser/renderer_host/render_view_host.h" | |
9 #include "chrome/browser/tab_contents/tab_contents.h" | |
10 #include "chrome/browser/tab_contents/web_contents.h" | |
11 #include "chrome/browser/tab_contents/tab_contents_view.h" | |
12 #include "chrome/browser/views/find_bar_win.h" | |
13 #include "chrome/common/notification_service.h" | |
14 #include "chrome/test/in_process_browser_test.h" | |
15 #include "chrome/test/ui_test_utils.h" | |
16 | |
17 const std::wstring kFramePage = L"files/find_in_page/frames.html"; | |
18 const std::wstring kFrameData = L"files/find_in_page/framedata_general.html"; | |
19 const std::wstring kUserSelectPage = L"files/find_in_page/user-select.html"; | |
20 const std::wstring kCrashPage = L"files/find_in_page/crash_1341577.html"; | |
21 const std::wstring kTooFewMatchesPage = L"files/find_in_page/bug_1155639.html"; | |
22 const std::wstring kEndState = L"files/find_in_page/end_state.html"; | |
23 | |
24 class FindInPageNotificationObserver : public NotificationObserver { | |
25 public: | |
26 explicit FindInPageNotificationObserver(TabContents* parent_tab) | |
27 : parent_tab_(parent_tab), | |
28 active_match_ordinal_(-1), | |
29 number_of_matches_(0) { | |
30 registrar_.Add(this, NotificationType::FIND_RESULT_AVAILABLE, | |
31 Source<TabContents>(parent_tab_)); | |
32 ui_test_utils::RunMessageLoop(); | |
33 } | |
34 | |
35 int active_match_ordinal() const { return active_match_ordinal_; } | |
36 | |
37 int number_of_matches() const { return number_of_matches_; } | |
38 | |
39 virtual void Observe(NotificationType type, const NotificationSource& source, | |
40 const NotificationDetails& details) { | |
41 if (type == NotificationType::FIND_RESULT_AVAILABLE) { | |
42 Details<FindNotificationDetails> find_details(details); | |
43 if (find_details->request_id() == kFindInPageRequestId) { | |
44 // We get multiple responses and one of those will contain the ordinal. | |
45 // This message comes to us before the final update is sent. | |
46 if (find_details->active_match_ordinal() > -1) | |
47 active_match_ordinal_ = find_details->active_match_ordinal(); | |
48 if (find_details->final_update()) { | |
49 number_of_matches_ = find_details->number_of_matches(); | |
50 MessageLoopForUI::current()->Quit(); | |
51 } else { | |
52 DLOG(INFO) << "Ignoring, since we only care about the final message"; | |
53 } | |
54 } | |
55 } else { | |
56 NOTREACHED(); | |
57 } | |
58 } | |
59 | |
60 // The Find mechanism is over asynchronous IPC, so a search is kicked off and | |
61 // we wait for notification to find out what the results are. As the user is | |
62 // typing, new search requests can be issued and the Request ID helps us make | |
63 // sense of whether this is the current request or an old one. The unit tests, | |
64 // however, which uses this constant issues only one search at a time, so we | |
65 // don't need a rolling id to identify each search. But, we still need to | |
66 // specify one, so we just use a fixed one - its value does not matter. | |
67 static const int kFindInPageRequestId; | |
68 | |
69 private: | |
70 NotificationRegistrar registrar_; | |
71 TabContents* parent_tab_; | |
72 // We will at some point (before final update) be notified of the ordinal and | |
73 // we need to preserve it so we can send it later. | |
74 int active_match_ordinal_; | |
75 int number_of_matches_; | |
76 }; | |
77 | |
78 typedef enum FindInPageDirection { BACK = 0, FWD = 1 }; | |
79 typedef enum FindInPageCase { IGNORE_CASE = 0, CASE_SENSITIVE = 1 }; | |
80 | |
81 class FindInPageControllerTest : public InProcessBrowserTest { | |
82 public: | |
83 FindInPageControllerTest() { | |
84 EnableDOMAutomation(); | |
85 } | |
86 | |
87 protected: | |
88 int FindInPage(const std::wstring& search_string, | |
89 FindInPageDirection forward, | |
90 FindInPageCase match_case, | |
91 bool find_next) { | |
92 WebContents* web_contents = | |
93 browser()->GetSelectedTabContents()->AsWebContents(); | |
94 if (web_contents) { | |
95 web_contents->set_current_find_request_id( | |
96 FindInPageNotificationObserver::kFindInPageRequestId); | |
97 web_contents->render_view_host()->StartFinding( | |
98 FindInPageNotificationObserver::kFindInPageRequestId, | |
99 search_string, forward == FWD, match_case == CASE_SENSITIVE, | |
100 find_next); | |
101 return FindInPageNotificationObserver(web_contents).number_of_matches(); | |
102 } | |
103 return 0; | |
104 } | |
105 }; | |
106 | |
107 // This test loads a page with frames and starts FindInPage requests. | |
108 IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindInPageFrames) { | |
109 HTTPTestServer* server = StartHTTPServer(); | |
110 | |
111 // First we navigate to our frames page. | |
112 GURL url = server->TestServerPageW(kFramePage); | |
113 ui_test_utils::NavigateToURL(browser(), url); | |
114 | |
115 // Try incremental search (mimicking user typing in). | |
116 EXPECT_EQ(18, FindInPage(L"g", FWD, IGNORE_CASE, false)); | |
117 EXPECT_EQ(11, FindInPage(L"go", FWD, IGNORE_CASE, false)); | |
118 EXPECT_EQ(04, FindInPage(L"goo", FWD, IGNORE_CASE, false)); | |
119 EXPECT_EQ(03, FindInPage(L"goog", FWD, IGNORE_CASE, false)); | |
120 EXPECT_EQ(02, FindInPage(L"googl", FWD, IGNORE_CASE, false)); | |
121 EXPECT_EQ(01, FindInPage(L"google", FWD, IGNORE_CASE, false)); | |
122 EXPECT_EQ(00, FindInPage(L"google!", FWD, IGNORE_CASE, false)); | |
123 | |
124 // Negative test (no matches should be found). | |
125 EXPECT_EQ(0, FindInPage(L"Non-existing string", FWD, IGNORE_CASE, false)); | |
126 | |
127 // 'horse' only exists in the three right frames. | |
128 EXPECT_EQ(3, FindInPage(L"horse", FWD, IGNORE_CASE, false)); | |
129 | |
130 // 'cat' only exists in the first frame. | |
131 EXPECT_EQ(1, FindInPage(L"cat", FWD, IGNORE_CASE, false)); | |
132 | |
133 // Try searching again, should still come up with 1 match. | |
134 EXPECT_EQ(1, FindInPage(L"cat", FWD, IGNORE_CASE, false)); | |
135 | |
136 // Try searching backwards, ignoring case, should still come up with 1 match. | |
137 EXPECT_EQ(1, FindInPage(L"CAT", BACK, IGNORE_CASE, false)); | |
138 | |
139 // Try case sensitive, should NOT find it. | |
140 EXPECT_EQ(0, FindInPage(L"CAT", FWD, CASE_SENSITIVE, false)); | |
141 | |
142 // Try again case sensitive, but this time with right case. | |
143 EXPECT_EQ(1, FindInPage(L"dog", FWD, CASE_SENSITIVE, false)); | |
144 | |
145 // Try non-Latin characters ('Hreggvidur' with 'eth' for 'd' in left frame). | |
146 EXPECT_EQ(1, FindInPage(L"Hreggvi\u00F0ur", FWD, IGNORE_CASE, false)); | |
147 EXPECT_EQ(1, FindInPage(L"Hreggvi\u00F0ur", FWD, CASE_SENSITIVE, false)); | |
148 EXPECT_EQ(0, FindInPage(L"hreggvi\u00F0ur", FWD, CASE_SENSITIVE, false)); | |
149 } | |
150 | |
151 std::string FocusedOnPage(WebContents* web_contents) { | |
152 ui_test_utils::JavaScriptRunner js_runner( | |
153 web_contents, | |
154 L"", | |
155 L"window.domAutomationController.send(getFocusedElement());"); | |
156 return js_runner.Run(); | |
157 } | |
158 | |
159 // This tests the FindInPage end-state, in other words: what is focused when you | |
160 // close the Find box (ie. if you find within a link the link should be | |
161 // focused). | |
162 // TODO(jcampan): This test needs to be enabled once Jay fixes the issues with | |
163 // running two InProc browser tests that both start a web server (crashes). | |
164 IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, DISABLED_FindInPageEndState) { | |
165 HTTPTestServer* server = StartHTTPServer(); | |
166 | |
167 // First we navigate to our special focus tracking page. | |
168 GURL url = server->TestServerPageW(kEndState); | |
169 ui_test_utils::NavigateToURL(browser(), url); | |
170 | |
171 WebContents* web_contents = | |
172 browser()->GetSelectedTabContents()->AsWebContents(); | |
173 ASSERT_TRUE(NULL != web_contents); | |
174 | |
175 // Verify that nothing has focus. | |
176 ASSERT_STREQ("{nothing focused}", FocusedOnPage(web_contents).c_str()); | |
177 | |
178 // Search for a text that exists within a link on the page. | |
179 EXPECT_EQ(1, FindInPage(L"nk", FWD, IGNORE_CASE, false)); | |
180 | |
181 // End the find session, which should set focus to the link. | |
182 web_contents->StopFinding(false); | |
183 | |
184 // Verify that the link is focused. | |
185 EXPECT_STREQ("link1", FocusedOnPage(web_contents).c_str()); | |
186 | |
187 // Search for a text that exists within a link on the page. | |
188 EXPECT_EQ(1, FindInPage(L"Google", FWD, IGNORE_CASE, false)); | |
189 | |
190 // Move the selection to link 1, after searching. | |
191 ui_test_utils::JavaScriptRunner js_runner( | |
192 web_contents, | |
193 L"", | |
194 L"window.domAutomationController.send(selectLink1());"); | |
195 js_runner.Run(); | |
196 | |
197 // End the find session. | |
198 web_contents->StopFinding(false); | |
199 | |
200 // Verify that link2 is not focused. | |
201 EXPECT_STREQ("", FocusedOnPage(web_contents).c_str()); | |
202 } | |
OLD | NEW |