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 "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 "content/test/content_browser_test_utils_internal.h" |
16 #include "net/dns/mock_host_resolver.h" | 16 #include "net/dns/mock_host_resolver.h" |
17 #include "third_party/WebKit/public/web/WebFindOptions.h" | 17 #include "third_party/WebKit/public/web/WebFindOptions.h" |
18 | 18 |
19 namespace content { | 19 namespace content { |
20 | 20 |
21 namespace { | 21 namespace { |
22 | 22 |
23 const int kInvalidId = -1; | 23 const int kInvalidId = -1; |
24 | 24 |
25 // The results of a find request. | 25 // The results of a find request. |
26 struct FindResults { | 26 struct FindResults { |
27 int request_id = kInvalidId; | 27 FindResults(int request_id, int number_of_matches, int active_match_ordinal) |
28 int number_of_matches = 0; | 28 : request_id(request_id), |
29 int active_match_ordinal = 0; | 29 number_of_matches(number_of_matches), |
| 30 active_match_ordinal(active_match_ordinal) {} |
| 31 FindResults() : FindResults(kInvalidId, 0, 0) {} |
| 32 |
| 33 int request_id; |
| 34 int number_of_matches; |
| 35 int active_match_ordinal; |
30 }; | 36 }; |
31 | 37 |
32 } // namespace | 38 } // namespace |
33 | 39 |
34 class TestWebContentsDelegate : public WebContentsDelegate { | 40 class TestWebContentsDelegate : public WebContentsDelegate { |
35 public: | 41 public: |
36 TestWebContentsDelegate() | 42 TestWebContentsDelegate() |
37 : last_request_id_(kInvalidId), | 43 : last_request_id_(kInvalidId), |
38 last_finished_request_id_(kInvalidId), | 44 last_finished_request_id_(kInvalidId), |
39 next_reply_received_(false), | 45 next_reply_received_(false), |
| 46 record_replies_(false), |
40 waiting_for_(NOTHING) {} | 47 waiting_for_(NOTHING) {} |
41 ~TestWebContentsDelegate() override {} | 48 ~TestWebContentsDelegate() override {} |
42 | 49 |
43 // Returns the current find results. | 50 // Returns the current find results. |
44 FindResults GetFindResults() { | 51 const FindResults& GetFindResults() const { |
45 return current_results_; | 52 return current_results_; |
46 } | 53 } |
47 | 54 |
48 // Waits for all pending replies to be received. | 55 // Waits for all pending replies to be received. |
49 void WaitForFinalReply() { | 56 void WaitForFinalReply() { |
50 if (last_finished_request_id_ >= last_request_id_) | 57 if (last_finished_request_id_ >= last_request_id_) |
51 return; | 58 return; |
52 | 59 |
53 WaitFor(FINAL_REPLY); | 60 WaitFor(FINAL_REPLY); |
54 } | 61 } |
(...skipping 14 matching lines...) Expand all Loading... |
69 void MarkNextReply() { | 76 void MarkNextReply() { |
70 next_reply_received_ = false; | 77 next_reply_received_ = false; |
71 } | 78 } |
72 | 79 |
73 // Called when a new find request is issued, so the delegate knows the last | 80 // Called when a new find request is issued, so the delegate knows the last |
74 // request ID. | 81 // request ID. |
75 void UpdateLastRequest(int request_id) { | 82 void UpdateLastRequest(int request_id) { |
76 last_request_id_ = request_id; | 83 last_request_id_ = request_id; |
77 } | 84 } |
78 | 85 |
| 86 // From when this function is called, all replies coming in via FindReply() |
| 87 // will be recorded. These replies can be retrieved via GetReplyRecord(). |
| 88 void StartReplyRecord() { |
| 89 reply_record_.clear(); |
| 90 record_replies_ = true; |
| 91 } |
| 92 |
| 93 // Retreives the results from the find replies recorded since the last call to |
| 94 // StartReplyRecord(). Calling this function also stops the recording new find |
| 95 // replies. |
| 96 const std::vector<FindResults>& GetReplyRecord() { |
| 97 record_replies_ = false; |
| 98 return reply_record_; |
| 99 } |
| 100 |
79 #if defined(OS_ANDROID) | 101 #if defined(OS_ANDROID) |
80 // Waits for all of the find match rects to be received. | 102 // Waits for all of the find match rects to be received. |
81 void WaitForMatchRects() { | 103 void WaitForMatchRects() { |
82 WaitFor(MATCH_RECTS); | 104 WaitFor(MATCH_RECTS); |
83 } | 105 } |
84 | 106 |
85 const std::vector<gfx::RectF>& find_match_rects() const { | 107 const std::vector<gfx::RectF>& find_match_rects() const { |
86 return find_match_rects_; | 108 return find_match_rects_; |
87 } | 109 } |
88 | 110 |
(...skipping 12 matching lines...) Expand all Loading... |
101 #endif | 123 #endif |
102 }; | 124 }; |
103 | 125 |
104 // WebContentsDelegate override. | 126 // WebContentsDelegate override. |
105 void FindReply(WebContents* web_contents, | 127 void FindReply(WebContents* web_contents, |
106 int request_id, | 128 int request_id, |
107 int number_of_matches, | 129 int number_of_matches, |
108 const gfx::Rect& selection_rect, | 130 const gfx::Rect& selection_rect, |
109 int active_match_ordinal, | 131 int active_match_ordinal, |
110 bool final_update) override { | 132 bool final_update) override { |
| 133 if (record_replies_) { |
| 134 reply_record_.emplace_back( |
| 135 request_id, number_of_matches, active_match_ordinal); |
| 136 } |
| 137 |
111 // Update the current results. | 138 // Update the current results. |
112 if (request_id > current_results_.request_id) | 139 if (request_id > current_results_.request_id) |
113 current_results_.request_id = request_id; | 140 current_results_.request_id = request_id; |
114 if (number_of_matches != -1) | 141 if (number_of_matches != -1) |
115 current_results_.number_of_matches = number_of_matches; | 142 current_results_.number_of_matches = number_of_matches; |
116 if (active_match_ordinal != -1) | 143 if (active_match_ordinal != -1) |
117 current_results_.active_match_ordinal = active_match_ordinal; | 144 current_results_.active_match_ordinal = active_match_ordinal; |
118 | 145 |
119 if (!final_update) | 146 if (!final_update) |
120 return; | 147 return; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 | 207 |
181 // The ID of the last find request issued. | 208 // The ID of the last find request issued. |
182 int last_request_id_; | 209 int last_request_id_; |
183 | 210 |
184 // The ID of the last find request to finish (all replies received). | 211 // The ID of the last find request to finish (all replies received). |
185 int last_finished_request_id_; | 212 int last_finished_request_id_; |
186 | 213 |
187 // Indicates whether the next reply after MarkNextReply() has been received. | 214 // Indicates whether the next reply after MarkNextReply() has been received. |
188 bool next_reply_received_; | 215 bool next_reply_received_; |
189 | 216 |
| 217 // Indicates whether the find results from incoming find replies are currently |
| 218 // being recorded. |
| 219 bool record_replies_; |
| 220 |
| 221 // A record of all find replies that have come in via FindReply() since |
| 222 // StartReplyRecor() was last called. |
| 223 std::vector<FindResults> reply_record_; |
| 224 |
190 // Indicates what |message_loop_runner_| is waiting for, if anything. | 225 // Indicates what |message_loop_runner_| is waiting for, if anything. |
191 WaitingFor waiting_for_; | 226 WaitingFor waiting_for_; |
192 | 227 |
193 scoped_refptr<content::MessageLoopRunner> message_loop_runner_; | 228 scoped_refptr<content::MessageLoopRunner> message_loop_runner_; |
194 | 229 |
195 DISALLOW_COPY_AND_ASSIGN(TestWebContentsDelegate); | 230 DISALLOW_COPY_AND_ASSIGN(TestWebContentsDelegate); |
196 }; | 231 }; |
197 | 232 |
198 class FindRequestManagerTest : public ContentBrowserTest, | 233 class FindRequestManagerTest : public ContentBrowserTest, |
199 public testing::WithParamInterface<bool> { | 234 public testing::WithParamInterface<bool> { |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
410 EXPECT_EQ(last_request_id() % results.number_of_matches, | 445 EXPECT_EQ(last_request_id() % results.number_of_matches, |
411 results.active_match_ordinal); | 446 results.active_match_ordinal); |
412 } | 447 } |
413 | 448 |
414 // Tests removing a frame during a find session. | 449 // Tests removing a frame during a find session. |
415 IN_PROC_BROWSER_TEST_P(FindRequestManagerTest, MAYBE(RemoveFrame)) { | 450 IN_PROC_BROWSER_TEST_P(FindRequestManagerTest, MAYBE(RemoveFrame)) { |
416 LoadMultiFramePage(2 /* height */, GetParam() /* cross_process */); | 451 LoadMultiFramePage(2 /* height */, GetParam() /* cross_process */); |
417 | 452 |
418 blink::WebFindOptions options; | 453 blink::WebFindOptions options; |
419 Find("result", options); | 454 Find("result", options); |
| 455 delegate()->WaitForFinalReply(); |
420 options.findNext = true; | 456 options.findNext = true; |
421 options.forward = false; | 457 options.forward = false; |
422 Find("result", options); | 458 Find("result", options); |
423 Find("result", options); | 459 Find("result", options); |
424 Find("result", options); | 460 Find("result", options); |
425 Find("result", options); | 461 Find("result", options); |
426 Find("result", options); | 462 Find("result", options); |
427 delegate()->WaitForFinalReply(); | 463 delegate()->WaitForFinalReply(); |
428 | 464 |
429 FindResults results = delegate()->GetFindResults(); | 465 FindResults results = delegate()->GetFindResults(); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
481 | 517 |
482 Find("result", options); | 518 Find("result", options); |
483 delegate()->WaitForFinalReply(); | 519 delegate()->WaitForFinalReply(); |
484 | 520 |
485 results = delegate()->GetFindResults(); | 521 results = delegate()->GetFindResults(); |
486 EXPECT_EQ(last_request_id(), results.request_id); | 522 EXPECT_EQ(last_request_id(), results.request_id); |
487 EXPECT_EQ(8, results.number_of_matches); | 523 EXPECT_EQ(8, results.number_of_matches); |
488 EXPECT_EQ(4, results.active_match_ordinal); | 524 EXPECT_EQ(4, results.active_match_ordinal); |
489 } | 525 } |
490 | 526 |
| 527 IN_PROC_BROWSER_TEST_F(FindRequestManagerTest, MAYBE(FindInPage_Issue627799)) { |
| 528 LoadAndWait("/find_in_long_page.html"); |
| 529 |
| 530 blink::WebFindOptions options; |
| 531 Find("42", options); |
| 532 delegate()->WaitForFinalReply(); |
| 533 |
| 534 FindResults results = delegate()->GetFindResults(); |
| 535 EXPECT_EQ(last_request_id(), results.request_id); |
| 536 EXPECT_EQ(970, results.number_of_matches); |
| 537 EXPECT_EQ(1, results.active_match_ordinal); |
| 538 |
| 539 delegate()->StartReplyRecord(); |
| 540 options.findNext = true; |
| 541 options.forward = false; |
| 542 Find("42", options); |
| 543 delegate()->WaitForFinalReply(); |
| 544 |
| 545 // This is the crux of the issue that this test guards against. Searching |
| 546 // across the frame boundary should not cause the frame to be re-scoped. If |
| 547 // the re-scope occurs, then we will see the number of matches change in one |
| 548 // of the recorded find replies. |
| 549 for (auto& reply : delegate()->GetReplyRecord()) { |
| 550 EXPECT_EQ(last_request_id(), reply.request_id); |
| 551 EXPECT_TRUE(reply.number_of_matches == kInvalidId || |
| 552 reply.number_of_matches == results.number_of_matches); |
| 553 } |
| 554 } |
| 555 |
491 #if defined(OS_ANDROID) | 556 #if defined(OS_ANDROID) |
492 // Tests requesting find match rects. | 557 // Tests requesting find match rects. |
493 IN_PROC_BROWSER_TEST_F(FindRequestManagerTest, MAYBE(FindMatchRects)) { | 558 IN_PROC_BROWSER_TEST_F(FindRequestManagerTest, MAYBE(FindMatchRects)) { |
494 LoadAndWait("/find_in_page.html"); | 559 LoadAndWait("/find_in_page.html"); |
495 | 560 |
496 blink::WebFindOptions default_options; | 561 blink::WebFindOptions default_options; |
497 Find("result", default_options); | 562 Find("result", default_options); |
498 delegate()->WaitForFinalReply(); | 563 delegate()->WaitForFinalReply(); |
499 EXPECT_EQ(19, delegate()->GetFindResults().number_of_matches); | 564 EXPECT_EQ(19, delegate()->GetFindResults().number_of_matches); |
500 | 565 |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 delegate()->MarkNextReply(); | 659 delegate()->MarkNextReply(); |
595 contents()->ActivateNearestFindResult( | 660 contents()->ActivateNearestFindResult( |
596 rects[order[i]].CenterPoint().x(), rects[order[i]].CenterPoint().y()); | 661 rects[order[i]].CenterPoint().x(), rects[order[i]].CenterPoint().y()); |
597 delegate()->WaitForNextReply(); | 662 delegate()->WaitForNextReply(); |
598 EXPECT_EQ(order[i] + 1, delegate()->GetFindResults().active_match_ordinal); | 663 EXPECT_EQ(order[i] + 1, delegate()->GetFindResults().active_match_ordinal); |
599 } | 664 } |
600 } | 665 } |
601 #endif // defined(OS_ANDROID) | 666 #endif // defined(OS_ANDROID) |
602 | 667 |
603 } // namespace content | 668 } // namespace content |
OLD | NEW |