find_in_page_manager_inttest.mm 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. // Copyright 2019 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. #include "base/strings/escape.h"
  5. #import "base/test/ios/wait_util.h"
  6. #include "ios/testing/embedded_test_server_handlers.h"
  7. #import "ios/web/find_in_page/find_in_page_java_script_feature.h"
  8. #import "ios/web/public/find_in_page/find_in_page_manager.h"
  9. #import "ios/web/public/js_messaging/web_frames_manager.h"
  10. #import "ios/web/public/test/fakes/fake_find_in_page_manager_delegate.h"
  11. #import "ios/web/public/test/fakes/fake_web_client.h"
  12. #import "ios/web/public/test/navigation_test_util.h"
  13. #import "ios/web/public/test/web_test_with_web_state.h"
  14. #include "net/test/embedded_test_server/embedded_test_server.h"
  15. #include "net/test/embedded_test_server/request_handler_util.h"
  16. #include "testing/gtest/include/gtest/gtest.h"
  17. #if !defined(__has_feature) || !__has_feature(objc_arc)
  18. #error "This file requires ARC support."
  19. #endif
  20. using base::test::ios::kWaitForJSCompletionTimeout;
  21. using base::test::ios::WaitUntilConditionOrTimeout;
  22. using base::test::ios::kWaitForPageLoadTimeout;
  23. namespace {
  24. // Page with text "Main frame body" and iframe with src URL equal to the URL
  25. // query string.
  26. const char kFindPageUrl[] = "/iframe?";
  27. // URL of iframe with text contents "iframe iframe text".
  28. const char kFindInPageIFrameUrl[] = "/echo-query?iframe iframe text";
  29. }
  30. namespace web {
  31. // Tests the FindInPageManager and verifies that values passed to
  32. // FindInPageManagerDelegate are correct.
  33. class FindInPageManagerTest : public WebTestWithWebState {
  34. protected:
  35. void SetUp() override {
  36. WebTestWithWebState::SetUp();
  37. test_server_.RegisterRequestHandler(base::BindRepeating(
  38. &net::test_server::HandlePrefixedRequest, "/echo-query",
  39. base::BindRepeating(&testing::HandlePageWithContents)));
  40. test_server_.RegisterRequestHandler(
  41. base::BindRepeating(&net::test_server::HandlePrefixedRequest, "/iframe",
  42. base::BindRepeating(&testing::HandleIFrame)));
  43. ASSERT_TRUE(test_server_.Start());
  44. GetFindInPageManager()->SetDelegate(&delegate_);
  45. }
  46. // Returns the FindInPageManager associated with |web_state()|.
  47. FindInPageManager* GetFindInPageManager() {
  48. return web::FindInPageManager::FromWebState(web_state());
  49. }
  50. // Waits until the delegate receives |index| from
  51. // DidSelectMatch(). Returns False if delegate never receives |index| within
  52. // time.
  53. [[nodiscard]] bool WaitForSelectedMatchAtIndex(int index) {
  54. return WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^bool {
  55. base::RunLoop().RunUntilIdle();
  56. return delegate_.state() && delegate_.state()->index == index;
  57. });
  58. }
  59. net::EmbeddedTestServer test_server_;
  60. FakeFindInPageManagerDelegate delegate_;
  61. };
  62. // Tests that find in page returns a single match for text which exists only in
  63. // the main frame.
  64. TEST_F(FindInPageManagerTest, FindMatchInMainFrame) {
  65. std::string url_spec =
  66. kFindPageUrl +
  67. base::EscapeQueryParamValue(kFindInPageIFrameUrl, /*use_plus=*/true);
  68. test::LoadUrl(web_state(), test_server_.GetURL(url_spec));
  69. ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForPageLoadTimeout, ^{
  70. return web_state()->GetWebFramesManager()->GetAllWebFrames().size() == 2;
  71. }));
  72. GetFindInPageManager()->Find(@"Main frame text",
  73. FindInPageOptions::FindInPageSearch);
  74. EXPECT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^bool {
  75. return delegate_.state();
  76. }));
  77. EXPECT_EQ(1, delegate_.state()->match_count);
  78. EXPECT_EQ(web_state(), delegate_.state()->web_state);
  79. }
  80. // Checks that find in page finds text that exists within the main frame and
  81. // an iframe.
  82. TEST_F(FindInPageManagerTest, FindMatchInMainFrameAndIFrame) {
  83. std::string url_spec =
  84. kFindPageUrl +
  85. base::EscapeQueryParamValue(kFindInPageIFrameUrl, /*use_plus=*/true);
  86. test::LoadUrl(web_state(), test_server_.GetURL(url_spec));
  87. ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForPageLoadTimeout, ^{
  88. return web_state()->GetWebFramesManager()->GetAllWebFrames().size() == 2;
  89. }));
  90. GetFindInPageManager()->Find(@"frame", FindInPageOptions::FindInPageSearch);
  91. EXPECT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^bool {
  92. return delegate_.state();
  93. }));
  94. EXPECT_EQ(3, delegate_.state()->match_count);
  95. EXPECT_EQ(web_state(), delegate_.state()->web_state);
  96. }
  97. // Checks that find in page returns no matches for text not contained on the
  98. // page.
  99. TEST_F(FindInPageManagerTest, FindNoMatch) {
  100. std::string url_spec =
  101. kFindPageUrl +
  102. base::EscapeQueryParamValue(kFindInPageIFrameUrl, /*use_plus=*/true);
  103. test::LoadUrl(web_state(), test_server_.GetURL(url_spec));
  104. ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForPageLoadTimeout, ^{
  105. return web_state()->GetWebFramesManager()->GetAllWebFrames().size() == 2;
  106. }));
  107. GetFindInPageManager()->Find(@"foobar", FindInPageOptions::FindInPageSearch);
  108. EXPECT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^bool {
  109. return delegate_.state();
  110. }));
  111. EXPECT_EQ(0, delegate_.state()->match_count);
  112. EXPECT_EQ(web_state(), delegate_.state()->web_state);
  113. }
  114. // Tests FindInPageNext iteration when matches exist in both the main frame and
  115. // an iframe.
  116. TEST_F(FindInPageManagerTest, FindForwardIterateThroughAllMatches) {
  117. std::string url_spec =
  118. kFindPageUrl +
  119. base::EscapeQueryParamValue(kFindInPageIFrameUrl, /*use_plus=*/true);
  120. test::LoadUrl(web_state(), test_server_.GetURL(url_spec));
  121. ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForPageLoadTimeout, ^{
  122. return web_state()->GetWebFramesManager()->GetAllWebFrames().size() == 2;
  123. }));
  124. GetFindInPageManager()->Find(@"frame", FindInPageOptions::FindInPageSearch);
  125. EXPECT_TRUE(WaitForSelectedMatchAtIndex(0));
  126. EXPECT_EQ(3, delegate_.state()->match_count);
  127. GetFindInPageManager()->Find(@"frame", FindInPageOptions::FindInPageNext);
  128. EXPECT_TRUE(WaitForSelectedMatchAtIndex(1));
  129. GetFindInPageManager()->Find(@"frame", FindInPageOptions::FindInPageNext);
  130. EXPECT_TRUE(WaitForSelectedMatchAtIndex(2));
  131. GetFindInPageManager()->Find(@"frame", FindInPageOptions::FindInPageNext);
  132. EXPECT_TRUE(WaitForSelectedMatchAtIndex(0));
  133. }
  134. // Tests FindInPagePrevious iteration when matches exist in both the main frame
  135. // and an iframe.
  136. TEST_F(FindInPageManagerTest, FindBackwardsIterateThroughAllMatches) {
  137. std::string url_spec =
  138. kFindPageUrl +
  139. base::EscapeQueryParamValue(kFindInPageIFrameUrl, /*use_plus=*/true);
  140. test::LoadUrl(web_state(), test_server_.GetURL(url_spec));
  141. ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForPageLoadTimeout, ^{
  142. return web_state()->GetWebFramesManager()->GetAllWebFrames().size() == 2;
  143. }));
  144. GetFindInPageManager()->Find(@"frame", FindInPageOptions::FindInPageSearch);
  145. EXPECT_TRUE(WaitForSelectedMatchAtIndex(0));
  146. EXPECT_EQ(3, delegate_.state()->match_count);
  147. GetFindInPageManager()->Find(@"frame", FindInPageOptions::FindInPagePrevious);
  148. EXPECT_TRUE(WaitForSelectedMatchAtIndex(2));
  149. GetFindInPageManager()->Find(@"frame", FindInPageOptions::FindInPagePrevious);
  150. EXPECT_TRUE(WaitForSelectedMatchAtIndex(1));
  151. GetFindInPageManager()->Find(@"frame", FindInPageOptions::FindInPagePrevious);
  152. EXPECT_TRUE(WaitForSelectedMatchAtIndex(0));
  153. }
  154. // Tests FindInPageNext iteration when matches exist in only an iframe.
  155. TEST_F(FindInPageManagerTest, FindIterateThroughIframeMatches) {
  156. std::string url_spec =
  157. kFindPageUrl +
  158. base::EscapeQueryParamValue(kFindInPageIFrameUrl, /*use_plus=*/true);
  159. test::LoadUrl(web_state(), test_server_.GetURL(url_spec));
  160. ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForPageLoadTimeout, ^{
  161. return web_state()->GetWebFramesManager()->GetAllWebFrames().size() == 2;
  162. }));
  163. GetFindInPageManager()->Find(@"iframe", FindInPageOptions::FindInPageSearch);
  164. EXPECT_TRUE(WaitForSelectedMatchAtIndex(0));
  165. EXPECT_EQ(2, delegate_.state()->match_count);
  166. GetFindInPageManager()->Find(@"iframe", FindInPageOptions::FindInPageNext);
  167. EXPECT_TRUE(WaitForSelectedMatchAtIndex(1));
  168. GetFindInPageManager()->Find(@"iframe", FindInPageOptions::FindInPageNext);
  169. EXPECT_TRUE(WaitForSelectedMatchAtIndex(0));
  170. }
  171. // Tests FindInPageNext and FindInPagePrevious iteration while passing null
  172. // query.
  173. TEST_F(FindInPageManagerTest, FindIterationWithNullQuery) {
  174. std::string url_spec =
  175. kFindPageUrl +
  176. base::EscapeQueryParamValue(kFindInPageIFrameUrl, /*use_plus=*/true);
  177. test::LoadUrl(web_state(), test_server_.GetURL(url_spec));
  178. ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForPageLoadTimeout, ^{
  179. return web_state()->GetWebFramesManager()->GetAllWebFrames().size() == 2;
  180. }));
  181. GetFindInPageManager()->Find(@"iframe", FindInPageOptions::FindInPageSearch);
  182. EXPECT_TRUE(WaitForSelectedMatchAtIndex(0));
  183. GetFindInPageManager()->Find(nil, FindInPageOptions::FindInPageNext);
  184. EXPECT_TRUE(WaitForSelectedMatchAtIndex(1));
  185. EXPECT_EQ(@"iframe", delegate_.state()->query);
  186. GetFindInPageManager()->Find(nil, FindInPageOptions::FindInPagePrevious);
  187. EXPECT_TRUE(WaitForSelectedMatchAtIndex(0));
  188. EXPECT_EQ(@"iframe", delegate_.state()->query);
  189. }
  190. } // namespace web