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

Side by Side Diff: content/browser/find_request_manager_browsertest.cc

Issue 1959183002: Multi-Process Find-in-Page. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 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 unified diff | Download patch
OLDNEW
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 "base/command_line.h" 5 #include "base/command_line.h"
6 #include "base/strings/utf_string_conversions.h" 6 #include "base/strings/utf_string_conversions.h"
7 #include "content/browser/web_contents/web_contents_impl.h" 7 #include "content/browser/web_contents/web_contents_impl.h"
8 #include "content/public/browser/notification_types.h" 8 #include "content/public/browser/notification_types.h"
9 #include "content/public/common/content_switches.h" 9 #include "content/public/common/content_switches.h"
10 #include "content/public/test/content_browser_test.h" 10 #include "content/public/test/content_browser_test.h"
11 #include "content/public/test/content_browser_test_utils.h" 11 #include "content/public/test/content_browser_test_utils.h"
12 #include "content/public/test/test_navigation_observer.h" 12 #include "content/public/test/test_navigation_observer.h"
13 #include "content/public/test/test_utils.h" 13 #include "content/public/test/test_utils.h"
14 #include "content/shell/browser/shell.h" 14 #include "content/shell/browser/shell.h"
15 #include "content/test/content_browser_test_utils_internal.h"
15 #include "net/dns/mock_host_resolver.h" 16 #include "net/dns/mock_host_resolver.h"
16 #include "third_party/WebKit/public/web/WebFindOptions.h" 17 #include "third_party/WebKit/public/web/WebFindOptions.h"
17 18
18 namespace content { 19 namespace content {
19 20
20 namespace { 21 namespace {
21 22
22 const int kInvalidId = -1; 23 const int kInvalidId = -1;
23 24
24 // The results of a find request. 25 // The results of a find request.
(...skipping 20 matching lines...) Expand all
45 waiting_request_id_ = request_id; 46 waiting_request_id_ = request_id;
46 find_message_loop_runner_ = new content::MessageLoopRunner; 47 find_message_loop_runner_ = new content::MessageLoopRunner;
47 find_message_loop_runner_->Run(); 48 find_message_loop_runner_->Run();
48 } 49 }
49 50
50 // Returns the current find results. 51 // Returns the current find results.
51 FindResults GetFindResults() { 52 FindResults GetFindResults() {
52 return current_results_; 53 return current_results_;
53 } 54 }
54 55
56 #if defined(OS_ANDROID)
57 // Waits for the next find reply. This is useful for waiting for a single
58 // match to be activated, which results in a single find reply (without a
59 // unique request ID).
60 void WaitForNextReply() {
61 waiting_request_id_ = 0;
62 find_message_loop_runner_ = new content::MessageLoopRunner;
63 find_message_loop_runner_->Run();
64 }
65
66 // Waits for all of the find match rects to be received.
67 void WaitForMatchRects() {
68 match_rects_message_loop_runner_ = new content::MessageLoopRunner;
69 match_rects_message_loop_runner_->Run();
70 }
71
72 const std::vector<gfx::RectF>& find_match_rects() const {
73 return find_match_rects_;
74 }
75
76 const gfx::RectF& active_match_rect() const {
77 return active_match_rect_;
78 }
79 #endif
80
55 private: 81 private:
56 // WebContentsDelegate override. 82 // WebContentsDelegate override.
57 void FindReply(WebContents* web_contents, 83 void FindReply(WebContents* web_contents,
58 int request_id, 84 int request_id,
59 int number_of_matches, 85 int number_of_matches,
60 const gfx::Rect& selection_rect, 86 const gfx::Rect& selection_rect,
61 int active_match_ordinal, 87 int active_match_ordinal,
62 bool final_update) override { 88 bool final_update) override {
63 // Update the current results. 89 // Update the current results.
64 if (request_id > current_results_.request_id) 90 if (request_id > current_results_.request_id)
65 current_results_.request_id = request_id; 91 current_results_.request_id = request_id;
66 if (number_of_matches != -1) 92 if (number_of_matches != -1)
67 current_results_.number_of_matches = number_of_matches; 93 current_results_.number_of_matches = number_of_matches;
68 if (active_match_ordinal != -1) 94 if (active_match_ordinal != -1)
69 current_results_.active_match_ordinal = active_match_ordinal; 95 current_results_.active_match_ordinal = active_match_ordinal;
70 96
71 if (final_update) 97 if (final_update)
72 last_finished_request_id_ = request_id; 98 last_finished_request_id_ = request_id;
73 99
74 // If we are waiting for a final reply and this is it, stop waiting. 100 // If we are waiting for a final reply and this is it, stop waiting.
75 if (find_message_loop_runner_.get() && 101 if (find_message_loop_runner_.get() &&
76 last_finished_request_id_ >= waiting_request_id_) { 102 last_finished_request_id_ >= waiting_request_id_) {
77 find_message_loop_runner_->Quit(); 103 find_message_loop_runner_->Quit();
78 } 104 }
79 } 105 }
80 106
107 #if defined(OS_ANDROID)
108 void FindMatchRectsReply(WebContents* web_contents,
109 int version,
110 const std::vector<gfx::RectF>& rects,
111 const gfx::RectF& active_rect) override {
112 // Update the current rects.
113 find_match_rects_ = rects;
114 active_match_rect_ = active_rect;
115
116 // If we are waiting for match rects, stop waiting.
117 if (match_rects_message_loop_runner_.get())
118 match_rects_message_loop_runner_->Quit();
119 }
120
121 std::vector<gfx::RectF> find_match_rects_;
122
123 gfx::RectF active_match_rect_;
124 #endif
125
81 // The latest known results from the current find request. 126 // The latest known results from the current find request.
82 FindResults current_results_; 127 FindResults current_results_;
83 128
84 // The ID of the last find request to finish (all replies received). 129 // The ID of the last find request to finish (all replies received).
85 int last_finished_request_id_; 130 int last_finished_request_id_;
86 131
87 // If waiting using |find_message_loop_runner_|, this is the ID of the find 132 // If waiting using |find_message_loop_runner_|, this is the ID of the find
88 // request being waited for. 133 // request being waited for.
89 int waiting_request_id_; 134 int waiting_request_id_;
90 135
91 scoped_refptr<content::MessageLoopRunner> find_message_loop_runner_; 136 scoped_refptr<content::MessageLoopRunner> find_message_loop_runner_;
137 scoped_refptr<content::MessageLoopRunner> match_rects_message_loop_runner_;
92 138
93 DISALLOW_COPY_AND_ASSIGN(TestWebContentsDelegate); 139 DISALLOW_COPY_AND_ASSIGN(TestWebContentsDelegate);
94 }; 140 };
95 141
96 class FindRequestManagerTest : public ContentBrowserTest { 142 class FindRequestManagerTest : public ContentBrowserTest,
143 public testing::WithParamInterface<bool> {
97 public: 144 public:
98 FindRequestManagerTest() 145 FindRequestManagerTest()
99 : normal_delegate_(nullptr), 146 : normal_delegate_(nullptr),
100 last_request_id_(0) {} 147 last_request_id_(0) {}
101 ~FindRequestManagerTest() override {} 148 ~FindRequestManagerTest() override {}
102 149
103 void SetUpOnMainThread() override { 150 void SetUpOnMainThread() override {
104 host_resolver()->AddRule("*", "127.0.0.1"); 151 host_resolver()->AddRule("*", "127.0.0.1");
105 ASSERT_TRUE(embedded_test_server()->Start()); 152 ASSERT_TRUE(embedded_test_server()->Start());
106 153
107 // Swap the WebContents's delegate for our test delegate. 154 // Swap the WebContents's delegate for our test delegate.
108 normal_delegate_ = contents()->GetDelegate(); 155 normal_delegate_ = contents()->GetDelegate();
109 contents()->SetDelegate(&test_delegate_); 156 contents()->SetDelegate(&test_delegate_);
110 } 157 }
111 158
112 void TearDownOnMainThread() override { 159 void TearDownOnMainThread() override {
113 // Swap the WebContents's delegate back to its usual delegate. 160 // Swap the WebContents's delegate back to its usual delegate.
114 contents()->SetDelegate(normal_delegate_); 161 contents()->SetDelegate(normal_delegate_);
115 } 162 }
116 163
164 #if !defined(OS_ANDROID)
117 void SetUpCommandLine(base::CommandLine* command_line) override { 165 void SetUpCommandLine(base::CommandLine* command_line) override {
118 IsolateAllSitesForTesting(command_line); 166 IsolateAllSitesForTesting(command_line);
119 } 167 }
168 #endif
120 169
121 protected: 170 protected:
122 // Navigate to |url| and wait for it to finish loading. 171 // Navigates to |url| and waits for it to finish loading.
123 void LoadAndWait(const std::string& url) { 172 void LoadAndWait(const std::string& url) {
124 TestNavigationObserver navigation_observer(contents()); 173 TestNavigationObserver navigation_observer(contents());
125 NavigateToURL(shell(), embedded_test_server()->GetURL("a.com", url)); 174 NavigateToURL(shell(), embedded_test_server()->GetURL("a.com", url));
126 EXPECT_TRUE(navigation_observer.last_navigation_succeeded()); 175 EXPECT_TRUE(navigation_observer.last_navigation_succeeded());
127 } 176 }
128 177
178 // Loads a multi-frame page. The page will have a full binary frame tree of
179 // height |height|. If |cross_process| is true, child frames will be loaded
180 // cross-process.
181 void LoadMultiFramePage(int height, bool cross_process) {
182 LoadAndWait("/find_in_page_multi_frame.html");
183
184 FrameTreeNode* root =
185 static_cast<WebContentsImpl*>(shell()->web_contents())->
186 GetFrameTree()->root();
187
188 LoadMultiFramePageChildFrames(height, cross_process, root);
189 }
190
191 // Reloads the child frame cross-process.
192 void MakeChildFrameCrossProcess() {
193 FrameTreeNode* root =
194 static_cast<WebContentsImpl*>(shell()->web_contents())->
195 GetFrameTree()->root();
196
197 TestNavigationObserver observer(shell()->web_contents());
198
199 FrameTreeNode* child = root->child_at(0);
200 GURL url(embedded_test_server()->GetURL("b.com",
201 child->current_url().path()));
202 NavigateFrameToURL(child, url);
203 EXPECT_EQ(url, observer.last_navigation_url());
204 EXPECT_TRUE(observer.last_navigation_succeeded());
205 }
206
129 void Find(const std::string& search_text, 207 void Find(const std::string& search_text,
130 const blink::WebFindOptions& options) { 208 const blink::WebFindOptions& options) {
131 contents()->Find(++last_request_id_, 209 contents()->Find(++last_request_id_,
132 base::UTF8ToUTF16(search_text), 210 base::UTF8ToUTF16(search_text),
133 options); 211 options);
134 } 212 }
135 213
136 void WaitForFinalReply() const { 214 void WaitForFinalReply() const {
137 delegate()->WaitForFinalReply(last_request_id_); 215 delegate()->WaitForFinalReply(last_request_id_);
138 } 216 }
139 217
140 WebContents* contents() const { 218 WebContents* contents() const {
141 return shell()->web_contents(); 219 return shell()->web_contents();
142 } 220 }
143 221
144 TestWebContentsDelegate* delegate() const { 222 TestWebContentsDelegate* delegate() const {
145 return static_cast<TestWebContentsDelegate*>(contents()->GetDelegate()); 223 return static_cast<TestWebContentsDelegate*>(contents()->GetDelegate());
146 } 224 }
147 225
148 int last_request_id() const { 226 int last_request_id() const {
149 return last_request_id_; 227 return last_request_id_;
150 } 228 }
151 229
152 private: 230 private:
231 // Helper function for LoadMultiFramePage. Loads child frames until the frame
232 // tree rooted at |root| is a full binary tree of height |height|.
233 void LoadMultiFramePageChildFrames(int height,
234 bool cross_process,
235 FrameTreeNode* root) {
236 if (height == 0)
237 return;
238
239 std::string hostname = root->current_origin().host();
240 if (cross_process)
241 hostname.insert(0, 1, 'a');
242 GURL url(embedded_test_server()->GetURL(hostname,
243 "/find_in_page_multi_frame.html"));
244
245 TestNavigationObserver observer(shell()->web_contents());
246
247 FrameTreeNode* child = root->child_at(0);
248 NavigateFrameToURL(child, url);
249 EXPECT_TRUE(observer.last_navigation_succeeded());
250 LoadMultiFramePageChildFrames(height - 1, cross_process, child);
251
252 child = root->child_at(1);
253 NavigateFrameToURL(child, url);
254 EXPECT_TRUE(observer.last_navigation_succeeded());
255 LoadMultiFramePageChildFrames(height - 1, cross_process, child);
256 }
257
153 TestWebContentsDelegate test_delegate_; 258 TestWebContentsDelegate test_delegate_;
154 WebContentsDelegate* normal_delegate_; 259 WebContentsDelegate* normal_delegate_;
155 260
156 // The ID of the last find request requested. 261 // The ID of the last find request requested.
157 int last_request_id_; 262 int last_request_id_;
158 263
159 DISALLOW_COPY_AND_ASSIGN(FindRequestManagerTest); 264 DISALLOW_COPY_AND_ASSIGN(FindRequestManagerTest);
160 }; 265 };
161 266
162 // TODO(paulmeyer): These tests currently fail on the linux_android_rel_ng 267 // Frames are made cross-process when the test param is set to
163 // trybot. Remove this guard once that problem is figured out. 268 // true. Cross-process frames are not used on android.
164 #if !defined(OS_ANDROID) 269 #if defined(OS_ANDROID)
270 INSTANTIATE_TEST_CASE_P(
271 FindRequestManagerTests, FindRequestManagerTest, testing::Values(false));
272 #else
273 INSTANTIATE_TEST_CASE_P(
274 FindRequestManagerTests, FindRequestManagerTest, testing::Bool());
275 #endif
165 276
166 // Test basic find-in-page functionality (such as searching forward and 277 // Tests basic find-in-page functionality (such as searching forward and
167 // backward) and check for correct results at each step. 278 // backward) and check for correct results at each step.
168 IN_PROC_BROWSER_TEST_F(FindRequestManagerTest, Basic) { 279 IN_PROC_BROWSER_TEST_P(FindRequestManagerTest, Basic) {
169 LoadAndWait("/find_in_page.html"); 280 LoadAndWait("/find_in_page.html");
281 if (GetParam())
282 MakeChildFrameCrossProcess();
170 283
171 blink::WebFindOptions options; 284 blink::WebFindOptions options;
172 Find("result", options); 285 Find("result", options);
173 WaitForFinalReply(); 286 WaitForFinalReply();
174 287
175 FindResults results = delegate()->GetFindResults(); 288 FindResults results = delegate()->GetFindResults();
176 EXPECT_EQ(last_request_id(), results.request_id); 289 EXPECT_EQ(last_request_id(), results.request_id);
177 EXPECT_EQ(19, results.number_of_matches); 290 EXPECT_EQ(19, results.number_of_matches);
178 EXPECT_EQ(1, results.active_match_ordinal); 291 EXPECT_EQ(1, results.active_match_ordinal);
179 292
(...skipping 15 matching lines...) Expand all
195 308
196 results = delegate()->GetFindResults(); 309 results = delegate()->GetFindResults();
197 EXPECT_EQ(last_request_id(), results.request_id); 310 EXPECT_EQ(last_request_id(), results.request_id);
198 EXPECT_EQ(19, results.number_of_matches); 311 EXPECT_EQ(19, results.number_of_matches);
199 EXPECT_EQ(i, results.active_match_ordinal); 312 EXPECT_EQ(i, results.active_match_ordinal);
200 } 313 }
201 } 314 }
202 315
203 // Tests searching for a word character-by-character, as would typically be done 316 // Tests searching for a word character-by-character, as would typically be done
204 // by a user typing into the find bar. 317 // by a user typing into the find bar.
205 IN_PROC_BROWSER_TEST_F(FindRequestManagerTest, CharacterByCharacter) { 318 IN_PROC_BROWSER_TEST_P(FindRequestManagerTest, CharacterByCharacter) {
206 LoadAndWait("/find_in_page.html"); 319 LoadAndWait("/find_in_page.html");
320 if (GetParam())
321 MakeChildFrameCrossProcess();
207 322
208 blink::WebFindOptions default_options; 323 blink::WebFindOptions default_options;
209 Find("r", default_options); 324 Find("r", default_options);
210 Find("re", default_options); 325 Find("re", default_options);
211 Find("res", default_options); 326 Find("res", default_options);
212 Find("resu", default_options); 327 Find("resu", default_options);
213 Find("resul", default_options); 328 Find("resul", default_options);
214 Find("result", default_options); 329 Find("result", default_options);
215 WaitForFinalReply(); 330 WaitForFinalReply();
216 331
217 FindResults results = delegate()->GetFindResults(); 332 FindResults results = delegate()->GetFindResults();
218 EXPECT_EQ(last_request_id(), results.request_id); 333 EXPECT_EQ(last_request_id(), results.request_id);
219 EXPECT_EQ(19, results.number_of_matches); 334 EXPECT_EQ(19, results.number_of_matches);
220 EXPECT_EQ(1, results.active_match_ordinal); 335 EXPECT_EQ(1, results.active_match_ordinal);
221 } 336 }
222 337
223 // Test sending a large number of find requests subsequently. 338 // Tests sending a large number of find requests subsequently.
224 IN_PROC_BROWSER_TEST_F(FindRequestManagerTest, RapidFire) { 339 IN_PROC_BROWSER_TEST_P(FindRequestManagerTest, RapidFire) {
225 LoadAndWait("/find_in_page.html"); 340 LoadAndWait("/find_in_page.html");
341 if (GetParam())
342 MakeChildFrameCrossProcess();
226 343
227 blink::WebFindOptions options; 344 blink::WebFindOptions options;
228 Find("result", options); 345 Find("result", options);
229 346
230 options.findNext = true; 347 options.findNext = true;
231 for (int i = 2; i <= 1000; ++i) 348 for (int i = 2; i <= 1000; ++i)
232 Find("result", options); 349 Find("result", options);
233 WaitForFinalReply(); 350 WaitForFinalReply();
234 351
235 FindResults results = delegate()->GetFindResults(); 352 FindResults results = delegate()->GetFindResults();
236 EXPECT_EQ(last_request_id(), results.request_id); 353 EXPECT_EQ(last_request_id(), results.request_id);
237 EXPECT_EQ(19, results.number_of_matches); 354 EXPECT_EQ(19, results.number_of_matches);
238 EXPECT_EQ(last_request_id() % results.number_of_matches, 355 EXPECT_EQ(last_request_id() % results.number_of_matches,
239 results.active_match_ordinal); 356 results.active_match_ordinal);
240 } 357 }
241 358
242 #endif // OS_ANDROID 359 // Tests removing a frame during a find session.
360 IN_PROC_BROWSER_TEST_P(FindRequestManagerTest, RemoveFrame) {
361 LoadMultiFramePage(2 /* height */, GetParam() /* cross_process */);
362
363 blink::WebFindOptions options;
364 Find("result", options);
365 options.findNext = true;
366 options.forward = false;
367 Find("result", options);
368 Find("result", options);
369 Find("result", options);
370 Find("result", options);
371 Find("result", options);
372 WaitForFinalReply();
373
374 FindResults results = delegate()->GetFindResults();
375 EXPECT_EQ(last_request_id(), results.request_id);
376 EXPECT_EQ(21, results.number_of_matches);
377 EXPECT_EQ(17, results.active_match_ordinal);
378
379 // Remove a frame.
380 FrameTreeNode* root =
381 static_cast<WebContentsImpl*>(shell()->web_contents())->
382 GetFrameTree()->root();
383 root->RemoveChild(root->child_at(0));
384
385 // The number of matches and active match ordinal should update automatically
386 // to exclude the matches from the removed frame.
387 results = delegate()->GetFindResults();
388 EXPECT_EQ(last_request_id(), results.request_id);
389 EXPECT_EQ(12, results.number_of_matches);
390 EXPECT_EQ(8, results.active_match_ordinal);
391
392 // TODO(paulemeyer): Once adding frames mid-session is handled, test that too.
393 }
394
395 // Tests Searching in a hidden frame. Matches in the hidden frame should be
396 // ignored.
397 IN_PROC_BROWSER_TEST_F(FindRequestManagerTest, HiddenFrame) {
398 LoadAndWait("/find_in_hidden_frame.html");
399
400 blink::WebFindOptions default_options;
401 Find("hello", default_options);
402 WaitForFinalReply();
403 FindResults results = delegate()->GetFindResults();
404
405 EXPECT_EQ(last_request_id(), results.request_id);
406 EXPECT_EQ(1, results.number_of_matches);
407 EXPECT_EQ(1, results.active_match_ordinal);
408 }
409
410 #if defined(OS_ANDROID)
411 // Tests requesting find match rects.
412 IN_PROC_BROWSER_TEST_F(FindRequestManagerTest, FindMatchRects) {
413 LoadAndWait("/find_in_page.html");
414
415 blink::WebFindOptions default_options;
416 Find("result", default_options);
417 WaitForFinalReply();
418 EXPECT_EQ(19, delegate()->GetFindResults().number_of_matches);
419
420 // Request the find match rects.
421 contents()->RequestFindMatchRects(-1);
422 delegate()->WaitForMatchRects();
423 const std::vector<gfx::RectF>& rects = delegate()->find_match_rects();
424
425 // The first match should be active.
426 EXPECT_EQ(rects[0], delegate()->active_match_rect());
427
428 // All results after the first two should be between them in find-in-page
429 // coordinates. This is because results 2 to 19 are inside an iframe located
430 // between results 0 and 1. This applies to the fixed div too.
431 EXPECT_LT(rects[0].y(), rects[1].y());
432 for (int i = 2; i < 19; ++i) {
433 EXPECT_LT(rects[0].y(), rects[i].y());
434 EXPECT_GT(rects[1].y(), rects[i].y());
435 }
436
437 // Result 3 should be below results 2 and 4. This is caused by the CSS
438 // transform in the containing div. If the transform doesn't work then result
439 // 3 will be between results 2 and 4.
440 EXPECT_GT(rects[3].y(), rects[2].y());
441 EXPECT_GT(rects[3].y(), rects[4].y());
442
443 // Results 6, 7, 8 and 9 should be one below the other in that same order. If
444 // overflow:scroll is not properly handled then result 8 would be below result
445 // 9 or result 7 above result 6 depending on the scroll.
446 EXPECT_LT(rects[6].y(), rects[7].y());
447 EXPECT_LT(rects[7].y(), rects[8].y());
448 EXPECT_LT(rects[8].y(), rects[9].y());
449
450 // Results 11, 12, 13 and 14 should be between results 10 and 15, as they are
451 // inside the table.
452 EXPECT_GT(rects[11].y(), rects[10].y());
453 EXPECT_GT(rects[12].y(), rects[10].y());
454 EXPECT_GT(rects[13].y(), rects[10].y());
455 EXPECT_GT(rects[14].y(), rects[10].y());
456 EXPECT_LT(rects[11].y(), rects[15].y());
457 EXPECT_LT(rects[12].y(), rects[15].y());
458 EXPECT_LT(rects[13].y(), rects[15].y());
459 EXPECT_LT(rects[14].y(), rects[15].y());
460
461 // Result 11 should be above results 12, 13 and 14 as it's in the table
462 // header.
463 EXPECT_LT(rects[11].y(), rects[12].y());
464 EXPECT_LT(rects[11].y(), rects[13].y());
465 EXPECT_LT(rects[11].y(), rects[14].y());
466
467 // Result 11 should also be right of results 12, 13 and 14 because of the
468 // colspan.
469 EXPECT_GT(rects[11].x(), rects[12].x());
470 EXPECT_GT(rects[11].x(), rects[13].x());
471 EXPECT_GT(rects[11].x(), rects[14].x());
472
473 // Result 12 should be left of results 11, 13 and 14 in the table layout.
474 EXPECT_LT(rects[12].x(), rects[11].x());
475 EXPECT_LT(rects[12].x(), rects[13].x());
476 EXPECT_LT(rects[12].x(), rects[14].x());
477
478 // Results 13, 12 and 14 should be one above the other in that order because
479 // of the rowspan and vertical-align: middle by default.
480 EXPECT_LT(rects[13].y(), rects[12].y());
481 EXPECT_LT(rects[12].y(), rects[14].y());
482
483 // Result 16 should be below result 15.
484 EXPECT_GT(rects[15].y(), rects[14].y());
485
486 // Result 18 should be normalized with respect to the position:relative div,
487 // and not it's immediate containing div. Consequently, result 18 should be
488 // above result 17.
489 EXPECT_GT(rects[17].y(), rects[18].y());
490 }
491
492 // Tests activating the find match nearest to a given point.
493 IN_PROC_BROWSER_TEST_F(FindRequestManagerTest, ActivateNearestFindMatch) {
494 LoadAndWait("/find_in_page.html");
495
496 blink::WebFindOptions default_options;
497 Find("result", default_options);
498 WaitForFinalReply();
499 EXPECT_EQ(19, delegate()->GetFindResults().number_of_matches);
500
501 // Get the find match rects.
502 contents()->RequestFindMatchRects(-1);
503 delegate()->WaitForMatchRects();
504 const std::vector<gfx::RectF>& rects = delegate()->find_match_rects();
505
506 // Activate matches via points inside each of the find match rects, in an
507 // arbitrary order. Check that the correct match becomes active after each
508 // activation.
509 int order[19] =
510 {11, 13, 2, 0, 16, 5, 7, 10, 6, 1, 15, 14, 9, 17, 18, 3, 8, 12, 4};
511 for (int i = 0; i < 19; ++i) {
512 contents()->ActivateNearestFindResult(
513 rects[order[i]].CenterPoint().x(), rects[order[i]].CenterPoint().y());
514 delegate()->WaitForNextReply();
515 EXPECT_EQ(order[i] + 1, delegate()->GetFindResults().active_match_ordinal);
516 }
517 }
518 #endif // defined(OS_ANDROID)
243 519
244 } // namespace content 520 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698