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

Unified 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: Disabled tests on Android Release because of crbug.com/615291. Created 4 years, 6 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 | « content/browser/find_request_manager.cc ('k') | content/browser/web_contents/web_contents_impl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/find_request_manager_browsertest.cc
diff --git a/content/browser/find_request_manager_browsertest.cc b/content/browser/find_request_manager_browsertest.cc
index c8ac858f4bdb5e3cd4a7a682b593841757777266..0ce93a6d6f02eb0a3726e9f356c9c14c4deb3b3a 100644
--- a/content/browser/find_request_manager_browsertest.cc
+++ b/content/browser/find_request_manager_browsertest.cc
@@ -12,6 +12,7 @@
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
+#include "content/test/content_browser_test_utils_internal.h"
#include "net/dns/mock_host_resolver.h"
#include "third_party/WebKit/public/web/WebFindOptions.h"
@@ -52,6 +53,31 @@ class TestWebContentsDelegate : public WebContentsDelegate {
return current_results_;
}
+#if defined(OS_ANDROID)
+ // Waits for the next find reply. This is useful for waiting for a single
+ // match to be activated, which results in a single find reply (without a
+ // unique request ID).
+ void WaitForNextReply() {
+ waiting_request_id_ = 0;
+ find_message_loop_runner_ = new content::MessageLoopRunner;
+ find_message_loop_runner_->Run();
+ }
+
+ // Waits for all of the find match rects to be received.
+ void WaitForMatchRects() {
+ match_rects_message_loop_runner_ = new content::MessageLoopRunner;
+ match_rects_message_loop_runner_->Run();
+ }
+
+ const std::vector<gfx::RectF>& find_match_rects() const {
+ return find_match_rects_;
+ }
+
+ const gfx::RectF& active_match_rect() const {
+ return active_match_rect_;
+ }
+#endif
+
private:
// WebContentsDelegate override.
void FindReply(WebContents* web_contents,
@@ -78,6 +104,25 @@ class TestWebContentsDelegate : public WebContentsDelegate {
}
}
+#if defined(OS_ANDROID)
+ void FindMatchRectsReply(WebContents* web_contents,
+ int version,
+ const std::vector<gfx::RectF>& rects,
+ const gfx::RectF& active_rect) override {
+ // Update the current rects.
+ find_match_rects_ = rects;
+ active_match_rect_ = active_rect;
+
+ // If we are waiting for match rects, stop waiting.
+ if (match_rects_message_loop_runner_.get())
+ match_rects_message_loop_runner_->Quit();
+ }
+
+ std::vector<gfx::RectF> find_match_rects_;
+
+ gfx::RectF active_match_rect_;
+#endif
+
// The latest known results from the current find request.
FindResults current_results_;
@@ -89,11 +134,13 @@ class TestWebContentsDelegate : public WebContentsDelegate {
int waiting_request_id_;
scoped_refptr<content::MessageLoopRunner> find_message_loop_runner_;
+ scoped_refptr<content::MessageLoopRunner> match_rects_message_loop_runner_;
DISALLOW_COPY_AND_ASSIGN(TestWebContentsDelegate);
};
-class FindRequestManagerTest : public ContentBrowserTest {
+class FindRequestManagerTest : public ContentBrowserTest,
+ public testing::WithParamInterface<bool> {
public:
FindRequestManagerTest()
: normal_delegate_(nullptr),
@@ -114,18 +161,49 @@ class FindRequestManagerTest : public ContentBrowserTest {
contents()->SetDelegate(normal_delegate_);
}
+#if !defined(OS_ANDROID)
void SetUpCommandLine(base::CommandLine* command_line) override {
IsolateAllSitesForTesting(command_line);
}
+#endif
protected:
- // Navigate to |url| and wait for it to finish loading.
+ // Navigates to |url| and waits for it to finish loading.
void LoadAndWait(const std::string& url) {
TestNavigationObserver navigation_observer(contents());
NavigateToURL(shell(), embedded_test_server()->GetURL("a.com", url));
EXPECT_TRUE(navigation_observer.last_navigation_succeeded());
}
+ // Loads a multi-frame page. The page will have a full binary frame tree of
+ // height |height|. If |cross_process| is true, child frames will be loaded
+ // cross-process.
+ void LoadMultiFramePage(int height, bool cross_process) {
+ LoadAndWait("/find_in_page_multi_frame.html");
+
+ FrameTreeNode* root =
+ static_cast<WebContentsImpl*>(shell()->web_contents())->
+ GetFrameTree()->root();
+
+ LoadMultiFramePageChildFrames(height, cross_process, root);
+ }
+
+ // Reloads the child frame cross-process.
+ void MakeChildFrameCrossProcess() {
+ FrameTreeNode* root =
+ static_cast<WebContentsImpl*>(shell()->web_contents())->
+ GetFrameTree()->root();
+
+ TestNavigationObserver observer(shell()->web_contents());
+
+ FrameTreeNode* child = root->child_at(0);
+ GURL url(embedded_test_server()->GetURL("b.com",
+ child->current_url().path()));
+ NavigateFrameToURL(child, url);
+ EXPECT_EQ(url, observer.last_navigation_url());
+ EXPECT_TRUE(observer.last_navigation_succeeded());
+ }
+
void Find(const std::string& search_text,
const blink::WebFindOptions& options) {
contents()->Find(++last_request_id_,
@@ -150,6 +228,33 @@ class FindRequestManagerTest : public ContentBrowserTest {
}
private:
+ // Helper function for LoadMultiFramePage. Loads child frames until the frame
+ // tree rooted at |root| is a full binary tree of height |height|.
+ void LoadMultiFramePageChildFrames(int height,
+ bool cross_process,
+ FrameTreeNode* root) {
+ if (height == 0)
+ return;
+
+ std::string hostname = root->current_origin().host();
+ if (cross_process)
+ hostname.insert(0, 1, 'a');
+ GURL url(embedded_test_server()->GetURL(hostname,
+ "/find_in_page_multi_frame.html"));
+
+ TestNavigationObserver observer(shell()->web_contents());
+
+ FrameTreeNode* child = root->child_at(0);
+ NavigateFrameToURL(child, url);
+ EXPECT_TRUE(observer.last_navigation_succeeded());
+ LoadMultiFramePageChildFrames(height - 1, cross_process, child);
+
+ child = root->child_at(1);
+ NavigateFrameToURL(child, url);
+ EXPECT_TRUE(observer.last_navigation_succeeded());
+ LoadMultiFramePageChildFrames(height - 1, cross_process, child);
+ }
+
TestWebContentsDelegate test_delegate_;
WebContentsDelegate* normal_delegate_;
@@ -159,14 +264,43 @@ class FindRequestManagerTest : public ContentBrowserTest {
DISALLOW_COPY_AND_ASSIGN(FindRequestManagerTest);
};
-// TODO(paulmeyer): These tests currently fail on the linux_android_rel_ng
-// trybot. Remove this guard once that problem is figured out.
-#if !defined(OS_ANDROID)
-
-// Test basic find-in-page functionality (such as searching forward and
+// Frames are made cross-process when the test param is set to
+// true. Cross-process frames are not used on android.
+#if defined(OS_ANDROID)
+INSTANTIATE_TEST_CASE_P(
+ FindRequestManagerTests, FindRequestManagerTest, testing::Values(false));
+#else
+INSTANTIATE_TEST_CASE_P(
+ FindRequestManagerTests, FindRequestManagerTest, testing::Bool());
+#endif
+
+// TODO(crbug.com/615291): These tests sometimes fail on the
+// linux_android_rel_ng trybot.
+#if defined(OS_ANDROID) && defined(NDEBUG)
+#define MAYBE_Basic DISABLED_Basic
+#define MAYBE_CharacterByCharacter DISABLED_CharacterByCharacter
+#define MAYBE_RapidFire DISABLED_RapidFire
+#define MAYBE_RemoveFrame DISABLED_RemoveFrame
+#define MAYBE_HiddenFrame DISABLED_HiddenFrame
+#define MAYBE_FindMatchRects DISABLED_FindMatchRects
+#define MAYBE_ActivateNearestFindMatch DISABLED_ActivateNearestFindMatch
+#else
+#define MAYBE_Basic Basic
+#define MAYBE_CharacterByCharacter CharacterByCharacter
+#define MAYBE_RapidFire RapidFire
+#define MAYBE_RemoveFrame RemoveFrame
+#define MAYBE_HiddenFrame HiddenFrame
+#define MAYBE_FindMatchRects FindMatchRects
+#define MAYBE_ActivateNearestFindMatch ActivateNearestFindMatch
+#endif
+
+
+// Tests basic find-in-page functionality (such as searching forward and
// backward) and check for correct results at each step.
-IN_PROC_BROWSER_TEST_F(FindRequestManagerTest, Basic) {
+IN_PROC_BROWSER_TEST_P(FindRequestManagerTest, MAYBE_Basic) {
LoadAndWait("/find_in_page.html");
+ if (GetParam())
+ MakeChildFrameCrossProcess();
blink::WebFindOptions options;
Find("result", options);
@@ -202,8 +336,10 @@ IN_PROC_BROWSER_TEST_F(FindRequestManagerTest, Basic) {
// Tests searching for a word character-by-character, as would typically be done
// by a user typing into the find bar.
-IN_PROC_BROWSER_TEST_F(FindRequestManagerTest, CharacterByCharacter) {
+IN_PROC_BROWSER_TEST_P(FindRequestManagerTest, MAYBE_CharacterByCharacter) {
LoadAndWait("/find_in_page.html");
+ if (GetParam())
+ MakeChildFrameCrossProcess();
blink::WebFindOptions default_options;
Find("r", default_options);
@@ -220,9 +356,11 @@ IN_PROC_BROWSER_TEST_F(FindRequestManagerTest, CharacterByCharacter) {
EXPECT_EQ(1, results.active_match_ordinal);
}
-// Test sending a large number of find requests subsequently.
-IN_PROC_BROWSER_TEST_F(FindRequestManagerTest, RapidFire) {
+// Tests sending a large number of find requests subsequently.
+IN_PROC_BROWSER_TEST_P(FindRequestManagerTest, MAYBE_RapidFire) {
LoadAndWait("/find_in_page.html");
+ if (GetParam())
+ MakeChildFrameCrossProcess();
blink::WebFindOptions options;
Find("result", options);
@@ -239,6 +377,165 @@ IN_PROC_BROWSER_TEST_F(FindRequestManagerTest, RapidFire) {
results.active_match_ordinal);
}
-#endif // OS_ANDROID
+// Tests removing a frame during a find session.
+IN_PROC_BROWSER_TEST_P(FindRequestManagerTest, MAYBE_RemoveFrame) {
+ LoadMultiFramePage(2 /* height */, GetParam() /* cross_process */);
+
+ blink::WebFindOptions options;
+ Find("result", options);
+ options.findNext = true;
+ options.forward = false;
+ Find("result", options);
+ Find("result", options);
+ Find("result", options);
+ Find("result", options);
+ Find("result", options);
+ WaitForFinalReply();
+
+ FindResults results = delegate()->GetFindResults();
+ EXPECT_EQ(last_request_id(), results.request_id);
+ EXPECT_EQ(21, results.number_of_matches);
+ EXPECT_EQ(17, results.active_match_ordinal);
+
+ // Remove a frame.
+ FrameTreeNode* root =
+ static_cast<WebContentsImpl*>(shell()->web_contents())->
+ GetFrameTree()->root();
+ root->RemoveChild(root->child_at(0));
+
+ // The number of matches and active match ordinal should update automatically
+ // to exclude the matches from the removed frame.
+ results = delegate()->GetFindResults();
+ EXPECT_EQ(last_request_id(), results.request_id);
+ EXPECT_EQ(12, results.number_of_matches);
+ EXPECT_EQ(8, results.active_match_ordinal);
+
+ // TODO(paulemeyer): Once adding frames mid-session is handled, test that too.
+}
+
+// Tests Searching in a hidden frame. Matches in the hidden frame should be
+// ignored.
+IN_PROC_BROWSER_TEST_F(FindRequestManagerTest, MAYBE_HiddenFrame) {
+ LoadAndWait("/find_in_hidden_frame.html");
+
+ blink::WebFindOptions default_options;
+ Find("hello", default_options);
+ WaitForFinalReply();
+ FindResults results = delegate()->GetFindResults();
+
+ EXPECT_EQ(last_request_id(), results.request_id);
+ EXPECT_EQ(1, results.number_of_matches);
+ EXPECT_EQ(1, results.active_match_ordinal);
+}
+
+#if defined(OS_ANDROID)
+// Tests requesting find match rects.
+IN_PROC_BROWSER_TEST_F(FindRequestManagerTest, MAYBE_FindMatchRects) {
+ LoadAndWait("/find_in_page.html");
+
+ blink::WebFindOptions default_options;
+ Find("result", default_options);
+ WaitForFinalReply();
+ EXPECT_EQ(19, delegate()->GetFindResults().number_of_matches);
+
+ // Request the find match rects.
+ contents()->RequestFindMatchRects(-1);
+ delegate()->WaitForMatchRects();
+ const std::vector<gfx::RectF>& rects = delegate()->find_match_rects();
+
+ // The first match should be active.
+ EXPECT_EQ(rects[0], delegate()->active_match_rect());
+
+ // All results after the first two should be between them in find-in-page
+ // coordinates. This is because results 2 to 19 are inside an iframe located
+ // between results 0 and 1. This applies to the fixed div too.
+ EXPECT_LT(rects[0].y(), rects[1].y());
+ for (int i = 2; i < 19; ++i) {
+ EXPECT_LT(rects[0].y(), rects[i].y());
+ EXPECT_GT(rects[1].y(), rects[i].y());
+ }
+
+ // Result 3 should be below results 2 and 4. This is caused by the CSS
+ // transform in the containing div. If the transform doesn't work then result
+ // 3 will be between results 2 and 4.
+ EXPECT_GT(rects[3].y(), rects[2].y());
+ EXPECT_GT(rects[3].y(), rects[4].y());
+
+ // Results 6, 7, 8 and 9 should be one below the other in that same order. If
+ // overflow:scroll is not properly handled then result 8 would be below result
+ // 9 or result 7 above result 6 depending on the scroll.
+ EXPECT_LT(rects[6].y(), rects[7].y());
+ EXPECT_LT(rects[7].y(), rects[8].y());
+ EXPECT_LT(rects[8].y(), rects[9].y());
+
+ // Results 11, 12, 13 and 14 should be between results 10 and 15, as they are
+ // inside the table.
+ EXPECT_GT(rects[11].y(), rects[10].y());
+ EXPECT_GT(rects[12].y(), rects[10].y());
+ EXPECT_GT(rects[13].y(), rects[10].y());
+ EXPECT_GT(rects[14].y(), rects[10].y());
+ EXPECT_LT(rects[11].y(), rects[15].y());
+ EXPECT_LT(rects[12].y(), rects[15].y());
+ EXPECT_LT(rects[13].y(), rects[15].y());
+ EXPECT_LT(rects[14].y(), rects[15].y());
+
+ // Result 11 should be above results 12, 13 and 14 as it's in the table
+ // header.
+ EXPECT_LT(rects[11].y(), rects[12].y());
+ EXPECT_LT(rects[11].y(), rects[13].y());
+ EXPECT_LT(rects[11].y(), rects[14].y());
+
+ // Result 11 should also be right of results 12, 13 and 14 because of the
+ // colspan.
+ EXPECT_GT(rects[11].x(), rects[12].x());
+ EXPECT_GT(rects[11].x(), rects[13].x());
+ EXPECT_GT(rects[11].x(), rects[14].x());
+
+ // Result 12 should be left of results 11, 13 and 14 in the table layout.
+ EXPECT_LT(rects[12].x(), rects[11].x());
+ EXPECT_LT(rects[12].x(), rects[13].x());
+ EXPECT_LT(rects[12].x(), rects[14].x());
+
+ // Results 13, 12 and 14 should be one above the other in that order because
+ // of the rowspan and vertical-align: middle by default.
+ EXPECT_LT(rects[13].y(), rects[12].y());
+ EXPECT_LT(rects[12].y(), rects[14].y());
+
+ // Result 16 should be below result 15.
+ EXPECT_GT(rects[15].y(), rects[14].y());
+
+ // Result 18 should be normalized with respect to the position:relative div,
+ // and not it's immediate containing div. Consequently, result 18 should be
+ // above result 17.
+ EXPECT_GT(rects[17].y(), rects[18].y());
+}
+
+// Tests activating the find match nearest to a given point.
+IN_PROC_BROWSER_TEST_F(FindRequestManagerTest, MAYBE_ActivateNearestFindMatch) {
+ LoadAndWait("/find_in_page.html");
+
+ blink::WebFindOptions default_options;
+ Find("result", default_options);
+ WaitForFinalReply();
+ EXPECT_EQ(19, delegate()->GetFindResults().number_of_matches);
+
+ // Get the find match rects.
+ contents()->RequestFindMatchRects(-1);
+ delegate()->WaitForMatchRects();
+ const std::vector<gfx::RectF>& rects = delegate()->find_match_rects();
+
+ // Activate matches via points inside each of the find match rects, in an
+ // arbitrary order. Check that the correct match becomes active after each
+ // activation.
+ int order[19] =
+ {11, 13, 2, 0, 16, 5, 7, 10, 6, 1, 15, 14, 9, 17, 18, 3, 8, 12, 4};
+ for (int i = 0; i < 19; ++i) {
+ contents()->ActivateNearestFindResult(
+ rects[order[i]].CenterPoint().x(), rects[order[i]].CenterPoint().y());
+ delegate()->WaitForNextReply();
+ EXPECT_EQ(order[i] + 1, delegate()->GetFindResults().active_match_ordinal);
+ }
+}
+#endif // defined(OS_ANDROID)
} // namespace content
« no previous file with comments | « content/browser/find_request_manager.cc ('k') | content/browser/web_contents/web_contents_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698