1// Copyright (c) 2012 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/files/file_util.h"
6#include "base/message_loop/message_loop.h"
7#include "base/prefs/pref_service.h"
8#include "base/strings/string16.h"
9#include "base/strings/string_util.h"
10#include "base/strings/utf_string_conversions.h"
11#include "chrome/app/chrome_command_ids.h"
12#include "chrome/browser/history/history_service.h"
13#include "chrome/browser/history/history_service_factory.h"
14#include "chrome/browser/profiles/profile.h"
15#include "chrome/browser/ui/browser.h"
16#include "chrome/browser/ui/browser_commands.h"
17#include "chrome/browser/ui/browser_finder.h"
18#include "chrome/browser/ui/browser_navigator.h"
19#include "chrome/browser/ui/browser_tabstrip.h"
20#include "chrome/browser/ui/browser_window.h"
21#include "chrome/browser/ui/chrome_pages.h"
22#include "chrome/browser/ui/find_bar/find_bar.h"
23#include "chrome/browser/ui/find_bar/find_bar_controller.h"
24#include "chrome/browser/ui/find_bar/find_bar_host_unittest_util.h"
25#include "chrome/browser/ui/find_bar/find_notification_details.h"
26#include "chrome/browser/ui/find_bar/find_tab_helper.h"
27#include "chrome/browser/ui/tabs/tab_strip_model.h"
28#include "chrome/common/pref_names.h"
29#include "chrome/common/url_constants.h"
30#include "chrome/test/base/find_in_page_observer.h"
31#include "chrome/test/base/in_process_browser_test.h"
32#include "chrome/test/base/ui_test_utils.h"
33#include "content/public/browser/download_manager.h"
34#include "content/public/browser/notification_service.h"
35#include "content/public/browser/notification_types.h"
36#include "content/public/browser/render_view_host.h"
37#include "content/public/browser/web_contents.h"
38#include "content/public/test/browser_test_utils.h"
39#include "net/base/filename_util.h"
40#include "ui/base/accelerators/accelerator.h"
41#include "ui/events/keycodes/keyboard_codes.h"
42
43#if defined(OS_WIN)
44#include "ui/aura/window.h"
45#include "ui/aura/window_tree_host.h"
46#endif
47
48using base::ASCIIToUTF16;
49using base::WideToUTF16;
50using content::NavigationController;
51using content::WebContents;
52
53namespace {
54
55const char kAnchorPage[] = "anchor.html";
56const char kAnchor[] = "#chapter2";
57const char kFramePage[] = "frames.html";
58const char kFrameData[] = "framedata_general.html";
59const char kUserSelectPage[] = "user-select.html";
60const char kCrashPage[] = "crash_1341577.html";
61const char kTooFewMatchesPage[] = "bug_1155639.html";
62const char kLongTextareaPage[] = "large_textarea.html";
63const char kPrematureEnd[] = "premature_end.html";
64const char kMoveIfOver[] = "move_if_obscuring.html";
65const char kBitstackCrash[] = "crash_14491.html";
66const char kSelectChangesOrdinal[] = "select_changes_ordinal.html";
67const char kStartAfterSelection[] = "start_after_selection.html";
68const char kSimple[] = "simple.html";
69const char kLinkPage[] = "link.html";
70
71const bool kBack = false;
72const bool kFwd = true;
73
74const bool kIgnoreCase = false;
75const bool kCaseSensitive = true;
76
77const int kMoveIterations = 30;
78
79}  // namespace
80
81class FindInPageControllerTest : public InProcessBrowserTest {
82 public:
83  FindInPageControllerTest() {
84    chrome::DisableFindBarAnimationsDuringTesting(true);
85  }
86
87 protected:
88  bool GetFindBarWindowInfoForBrowser(
89      Browser* browser, gfx::Point* position, bool* fully_visible) {
90    FindBarTesting* find_bar =
91        browser->GetFindBarController()->find_bar()->GetFindBarTesting();
92    return find_bar->GetFindBarWindowInfo(position, fully_visible);
93  }
94
95  bool GetFindBarWindowInfo(gfx::Point* position, bool* fully_visible) {
96    return GetFindBarWindowInfoForBrowser(browser(), position, fully_visible);
97  }
98
99  base::string16 GetFindBarTextForBrowser(Browser* browser) {
100    FindBar* find_bar = browser->GetFindBarController()->find_bar();
101    return find_bar->GetFindText();
102  }
103
104  base::string16 GetFindBarText() {
105    return GetFindBarTextForBrowser(browser());
106  }
107
108  base::string16 GetFindBarMatchCountTextForBrowser(Browser* browser) {
109    FindBarTesting* find_bar =
110        browser->GetFindBarController()->find_bar()->GetFindBarTesting();
111    return find_bar->GetMatchCountText();
112  }
113
114  base::string16 GetMatchCountText() {
115    return GetFindBarMatchCountTextForBrowser(browser());
116  }
117
118  int GetFindBarWidthForBrowser(Browser* browser) {
119    FindBarTesting* find_bar =
120        browser->GetFindBarController()->find_bar()->GetFindBarTesting();
121    return find_bar->GetWidth();
122  }
123
124  void EnsureFindBoxOpenForBrowser(Browser* browser) {
125    chrome::ShowFindBar(browser);
126    gfx::Point position;
127    bool fully_visible = false;
128    EXPECT_TRUE(GetFindBarWindowInfoForBrowser(
129                    browser, &position, &fully_visible));
130    EXPECT_TRUE(fully_visible);
131  }
132
133  void EnsureFindBoxOpen() {
134    EnsureFindBoxOpenForBrowser(browser());
135  }
136
137  // Platform independent FindInPage that takes |const wchar_t*|
138  // as an input.
139  int FindInPageWchar(WebContents* web_contents,
140                      const wchar_t* search_str,
141                      bool forward,
142                      bool case_sensitive,
143                      int* ordinal) {
144    base::string16 search_str16(WideToUTF16(std::wstring(search_str)));
145    Browser* browser = chrome::FindBrowserWithWebContents(web_contents);
146    browser->GetFindBarController()->find_bar()->SetFindTextAndSelectedRange(
147        search_str16, gfx::Range());
148    return ui_test_utils::FindInPage(
149        web_contents, search_str16, forward, case_sensitive, ordinal, NULL);
150  }
151
152  // Calls FindInPageWchar till the find box's x position != |start_x_position|.
153  // Return |start_x_position| if the find box has not moved after iterating
154  // through all matches of |search_str|.
155  int FindInPageTillBoxMoves(WebContents* web_contents,
156                             int start_x_position,
157                             const wchar_t* search_str,
158                             int expected_matches) {
159    // Search for |search_str| which the Find box is obscuring.
160    for (int index = 0; index < expected_matches; ++index) {
161      int ordinal = 0;
162      EXPECT_EQ(expected_matches, FindInPageWchar(web_contents, search_str,
163                                                  kFwd, kIgnoreCase, &ordinal));
164
165      // Check the position.
166      bool fully_visible;
167      gfx::Point position;
168      EXPECT_TRUE(GetFindBarWindowInfo(&position, &fully_visible));
169      EXPECT_TRUE(fully_visible);
170
171      // If the Find box has moved then we are done.
172      if (position.x() != start_x_position)
173        return position.x();
174    }
175    return start_x_position;
176  }
177
178  GURL GetURL(const std::string& filename) {
179    return ui_test_utils::GetTestUrl(
180        base::FilePath().AppendASCII("find_in_page"),
181        base::FilePath().AppendASCII(filename));
182  }
183
184  void FlushHistoryService() {
185    HistoryServiceFactory::GetForProfile(
186        browser()->profile(), Profile::IMPLICIT_ACCESS)->FlushForTest(
187        base::Bind(&base::MessageLoop::Quit,
188                   base::Unretained(base::MessageLoop::current()->current())));
189    content::RunMessageLoop();
190  }
191};
192
193// This test loads a page with frames and starts FindInPage requests.
194IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindInPageFrames) {
195  // First we navigate to our frames page.
196  GURL url = GetURL(kFramePage);
197  ui_test_utils::NavigateToURL(browser(), url);
198
199  // Try incremental search (mimicking user typing in).
200  int ordinal = 0;
201  WebContents* web_contents =
202      browser()->tab_strip_model()->GetActiveWebContents();
203  EXPECT_EQ(18, FindInPageWchar(web_contents, L"g",
204                                kFwd, kIgnoreCase, &ordinal));
205  EXPECT_EQ(1, ordinal);
206  EXPECT_EQ(11, FindInPageWchar(web_contents, L"go",
207                                kFwd, kIgnoreCase, &ordinal));
208  EXPECT_EQ(1, ordinal);
209  EXPECT_EQ(4, FindInPageWchar(web_contents, L"goo",
210                               kFwd, kIgnoreCase, &ordinal));
211  EXPECT_EQ(1, ordinal);
212  EXPECT_EQ(3, FindInPageWchar(web_contents, L"goog",
213                               kFwd, kIgnoreCase, &ordinal));
214  EXPECT_EQ(1, ordinal);
215  EXPECT_EQ(2, FindInPageWchar(web_contents, L"googl",
216                               kFwd, kIgnoreCase, &ordinal));
217  EXPECT_EQ(1, ordinal);
218  EXPECT_EQ(1, FindInPageWchar(web_contents, L"google",
219                               kFwd, kIgnoreCase, &ordinal));
220  EXPECT_EQ(1, ordinal);
221  EXPECT_EQ(0, FindInPageWchar(web_contents, L"google!",
222                               kFwd, kIgnoreCase, &ordinal));
223  EXPECT_EQ(0, ordinal);
224
225  // Negative test (no matches should be found).
226  EXPECT_EQ(0, FindInPageWchar(web_contents, L"Non-existing string",
227                               kFwd, kIgnoreCase, &ordinal));
228  EXPECT_EQ(0, ordinal);
229
230  // 'horse' only exists in the three right frames.
231  EXPECT_EQ(3, FindInPageWchar(web_contents, L"horse",
232                               kFwd, kIgnoreCase, &ordinal));
233  EXPECT_EQ(1, ordinal);
234
235  // 'cat' only exists in the first frame.
236  EXPECT_EQ(1, FindInPageWchar(web_contents, L"cat",
237                               kFwd, kIgnoreCase, &ordinal));
238  EXPECT_EQ(1, ordinal);
239
240  // Try searching again, should still come up with 1 match.
241  EXPECT_EQ(1, FindInPageWchar(web_contents, L"cat",
242                               kFwd, kIgnoreCase, &ordinal));
243  EXPECT_EQ(1, ordinal);
244
245  // Try searching backwards, ignoring case, should still come up with 1 match.
246  EXPECT_EQ(1, FindInPageWchar(web_contents, L"CAT",
247                               kBack, kIgnoreCase, &ordinal));
248  EXPECT_EQ(1, ordinal);
249
250  // Try case sensitive, should NOT find it.
251  EXPECT_EQ(0, FindInPageWchar(web_contents, L"CAT",
252                               kFwd, kCaseSensitive, &ordinal));
253  EXPECT_EQ(0, ordinal);
254
255  // Try again case sensitive, but this time with right case.
256  EXPECT_EQ(1, FindInPageWchar(web_contents, L"dog",
257                               kFwd, kCaseSensitive, &ordinal));
258  EXPECT_EQ(1, ordinal);
259
260  // Try non-Latin characters ('Hreggvidur' with 'eth' for 'd' in left frame).
261  EXPECT_EQ(1, FindInPageWchar(web_contents, L"Hreggvi\u00F0ur",
262                               kFwd, kIgnoreCase, &ordinal));
263  EXPECT_EQ(1, ordinal);
264  EXPECT_EQ(1, FindInPageWchar(web_contents, L"Hreggvi\u00F0ur",
265                               kFwd, kCaseSensitive, &ordinal));
266  EXPECT_EQ(1, ordinal);
267  EXPECT_EQ(0, FindInPageWchar(web_contents, L"hreggvi\u00F0ur",
268                               kFwd, kCaseSensitive, &ordinal));
269  EXPECT_EQ(0, ordinal);
270}
271
272// Verify search for text within various forms and text areas.
273IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindInPageFormsTextAreas) {
274  std::vector<GURL> urls;
275  urls.push_back(GetURL("textintextarea.html"));
276  urls.push_back(GetURL("smalltextarea.html"));
277  urls.push_back(GetURL("populatedform.html"));
278  WebContents* web_contents =
279      browser()->tab_strip_model()->GetActiveWebContents();
280
281  for (size_t i = 0; i < urls.size(); ++i) {
282    ui_test_utils::NavigateToURL(browser(), urls[i]);
283    EXPECT_EQ(1, FindInPageWchar(web_contents, L"cat",
284                                 kFwd, kIgnoreCase, NULL));
285    EXPECT_EQ(0, FindInPageWchar(web_contents, L"bat",
286                                 kFwd, kIgnoreCase, NULL));
287  }
288}
289
290// Verify search for text within special URLs such as chrome:history,
291// chrome://downloads, data directory
292#if defined(OS_WIN)
293// Disabled due to crbug.com/175711
294#define MAYBE_SearchWithinSpecialURL \
295        DISABLED_SearchWithinSpecialURL
296#else
297#define MAYBE_SearchWithinSpecialURL \
298        SearchWithinSpecialURL
299#endif
300IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, MAYBE_SearchWithinSpecialURL) {
301  WebContents* web_contents =
302      browser()->tab_strip_model()->GetActiveWebContents();
303
304  base::FilePath data_dir =
305      ui_test_utils::GetTestFilePath(base::FilePath(), base::FilePath());
306  ui_test_utils::NavigateToURL(browser(), net::FilePathToFileURL(data_dir));
307  EXPECT_EQ(1, FindInPageWchar(web_contents, L"downloads",
308                               kFwd, kIgnoreCase, NULL));
309
310  ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIHistoryURL));
311
312  // The history page does an async request to the history service and then
313  // updates the renderer. So we make a query as well, and by the time it comes
314  // back we know the data is on its way to the renderer.
315  FlushHistoryService();
316
317  base::string16 query(data_dir.LossyDisplayName());
318  EXPECT_EQ(1,
319            ui_test_utils::FindInPage(web_contents, query,
320                                      kFwd, kIgnoreCase, NULL, NULL));
321
322  GURL download_url = ui_test_utils::GetTestUrl(
323      base::FilePath().AppendASCII("downloads"),
324      base::FilePath().AppendASCII("a_zip_file.zip"));
325  ui_test_utils::DownloadURL(browser(), download_url);
326
327  ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIDownloadsURL));
328  FlushHistoryService();
329  EXPECT_EQ(1,
330            FindInPageWchar(web_contents,
331                            base::ASCIIToWide(download_url.spec()).c_str(),
332                            kFwd, kIgnoreCase, NULL));
333}
334
335// Verify search selection coordinates. The data file used is set-up such that
336// the text occurs on the same line, and we verify their positions by verifying
337// their relative positions.
338IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindInPageSpecialURLs) {
339  std::wstring search_string(L"\u5728\u897f\u660c\u536b\u661f\u53d1");
340  gfx::Rect first, second, first_reverse;
341  WebContents* web_contents =
342      browser()->tab_strip_model()->GetActiveWebContents();
343  ui_test_utils::NavigateToURL(browser(), GetURL("specialchar.html"));
344  ui_test_utils::FindInPage(web_contents, WideToUTF16(search_string),
345                            kFwd, kIgnoreCase, NULL, &first);
346  ui_test_utils::FindInPage(web_contents, WideToUTF16(search_string),
347                            kFwd, kIgnoreCase, NULL, &second);
348
349  // We have search occurrence in the same row, so top-bottom coordinates should
350  // be the same even for second search.
351  ASSERT_EQ(first.y(), second.y());
352  ASSERT_EQ(first.bottom(), second.bottom());
353  ASSERT_LT(first.x(), second.x());
354  ASSERT_LT(first.right(), second.right());
355
356  ui_test_utils::FindInPage(
357      web_contents, WideToUTF16(search_string), kBack, kIgnoreCase, NULL,
358      &first_reverse);
359  // We find next and we go back so find coordinates should be the same as
360  // previous ones.
361  ASSERT_EQ(first, first_reverse);
362}
363
364// Verifies that comments and meta data are not searchable.
365IN_PROC_BROWSER_TEST_F(FindInPageControllerTest,
366                       CommentsAndMetaDataNotSearchable) {
367  WebContents* web_contents =
368      browser()->tab_strip_model()->GetActiveWebContents();
369  ui_test_utils::NavigateToURL(browser(), GetURL("specialchar.html"));
370
371  std::wstring search_string =
372      L"\u4e2d\u65b0\u793e\u8bb0\u8005\u5b8b\u5409\u6cb3\u6444\u4e2d\u65b0\u7f51";
373  EXPECT_EQ(0, ui_test_utils::FindInPage(
374      web_contents, WideToUTF16(search_string), kFwd, kIgnoreCase, NULL, NULL));
375}
376
377// Verifies that span and lists are searchable.
378IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, SpanAndListsSearchable) {
379  WebContents* web_contents =
380      browser()->tab_strip_model()->GetActiveWebContents();
381  ui_test_utils::NavigateToURL(browser(), GetURL("FindRandomTests.html"));
382
383  std::wstring search_string = L"has light blue eyes and my father has dark";
384  EXPECT_EQ(1, ui_test_utils::FindInPage(
385      web_contents, WideToUTF16(search_string), kFwd, kIgnoreCase, NULL, NULL));
386
387  search_string = L"Google\nApple\nandroid";
388  EXPECT_EQ(1, ui_test_utils::FindInPage(
389      web_contents, WideToUTF16(search_string), kFwd, kIgnoreCase, NULL, NULL));
390}
391
392// Find in a very large page.
393// Disabled due to http://crbug.com/398017
394IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, DISABLED_LargePage) {
395  WebContents* web_contents =
396      browser()->tab_strip_model()->GetActiveWebContents();
397  ui_test_utils::NavigateToURL(browser(), GetURL("largepage.html"));
398
399  std::wstring search_string = L"daughter of Prince";
400  EXPECT_EQ(373,
401            FindInPageWchar(web_contents, search_string.c_str(),
402                            kFwd, kIgnoreCase, NULL));
403}
404
405// Find a very long string in a large page.
406IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindLongString) {
407  WebContents* web_contents =
408      browser()->tab_strip_model()->GetActiveWebContents();
409  ui_test_utils::NavigateToURL(browser(), GetURL("largepage.html"));
410
411  base::FilePath path = ui_test_utils::GetTestFilePath(
412      base::FilePath().AppendASCII("find_in_page"),
413      base::FilePath().AppendASCII("LongFind.txt"));
414  std::string query;
415  base::ReadFileToString(path, &query);
416  std::wstring search_string = base::UTF8ToWide(query);
417  EXPECT_EQ(1,
418            FindInPageWchar(web_contents, search_string.c_str(),
419                            kFwd, kIgnoreCase, NULL));
420}
421
422// Find a big font string in a page.
423IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, BigString) {
424  WebContents* web_contents =
425      browser()->tab_strip_model()->GetActiveWebContents();
426  ui_test_utils::NavigateToURL(browser(), GetURL("BigText.html"));
427  EXPECT_EQ(1,
428            FindInPageWchar(web_contents, L"SomeLargeString",
429                            kFwd, kIgnoreCase, NULL));
430}
431
432// http://crbug.com/369169
433#if defined(OS_CHROMEOS)
434#define MAYBE_SingleOccurrence DISABLED_SingleOccurrence
435#else
436#define MAYBE_SingleOccurrence SingleOccurrence
437#endif
438// Search Back and Forward on a single occurrence.
439IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, MAYBE_SingleOccurrence) {
440  WebContents* web_contents =
441      browser()->tab_strip_model()->GetActiveWebContents();
442  ui_test_utils::NavigateToURL(browser(), GetURL("FindRandomTests.html"));
443
444  gfx::Rect first_rect;
445  EXPECT_EQ(1,
446            ui_test_utils::FindInPage(web_contents,
447                                      ASCIIToUTF16("2010 Pro Bowl"), kFwd,
448                                      kIgnoreCase, NULL, &first_rect));
449
450  gfx::Rect second_rect;
451  EXPECT_EQ(1,
452            ui_test_utils::FindInPage(web_contents,
453                                      ASCIIToUTF16("2010 Pro Bowl"), kFwd,
454                                      kIgnoreCase, NULL, &second_rect));
455
456  // Doing a fake find so we have no previous search.
457  ui_test_utils::FindInPage(web_contents, ASCIIToUTF16("ghgfjgfh201232rere"),
458                            kFwd, kIgnoreCase, NULL, NULL);
459
460  ASSERT_EQ(first_rect, second_rect);
461
462  EXPECT_EQ(1,
463            ui_test_utils::FindInPage(web_contents,
464                                      ASCIIToUTF16("2010 Pro Bowl"), kFwd,
465                                      kIgnoreCase, NULL, &first_rect));
466  EXPECT_EQ(1,
467            ui_test_utils::FindInPage(web_contents,
468                                      ASCIIToUTF16("2010 Pro Bowl"), kBack,
469                                      kIgnoreCase, NULL, &second_rect));
470  ASSERT_EQ(first_rect, second_rect);
471}
472
473// Find the whole text file page and find count should be 1.
474IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindWholeFileContent) {
475  WebContents* web_contents =
476      browser()->tab_strip_model()->GetActiveWebContents();
477
478  base::FilePath path = ui_test_utils::GetTestFilePath(
479      base::FilePath().AppendASCII("find_in_page"),
480      base::FilePath().AppendASCII("find_test.txt"));
481  ui_test_utils::NavigateToURL(browser(), net::FilePathToFileURL(path));
482
483  std::string query;
484  base::ReadFileToString(path, &query);
485  std::wstring search_string = base::UTF8ToWide(query);
486  EXPECT_EQ(1,
487            FindInPageWchar(web_contents, search_string.c_str(),
488                            false, false, NULL));
489}
490
491// This test loads a single-frame page and makes sure the ordinal returned makes
492// sense as we FindNext over all the items.
493IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindInPageOrdinal) {
494  // First we navigate to our page.
495  GURL url = GetURL(kFrameData);
496  ui_test_utils::NavigateToURL(browser(), url);
497
498  // Search for 'o', which should make the first item active and return
499  // '1 in 3' (1st ordinal of a total of 3 matches).
500  WebContents* web_contents =
501      browser()->tab_strip_model()->GetActiveWebContents();
502  int ordinal = 0;
503  EXPECT_EQ(3, FindInPageWchar(web_contents, L"o",
504                               kFwd, kIgnoreCase, &ordinal));
505  EXPECT_EQ(1, ordinal);
506  EXPECT_EQ(3, FindInPageWchar(web_contents, L"o",
507                               kFwd, kIgnoreCase, &ordinal));
508  EXPECT_EQ(2, ordinal);
509  EXPECT_EQ(3, FindInPageWchar(web_contents, L"o",
510                               kFwd, kIgnoreCase, &ordinal));
511  EXPECT_EQ(3, ordinal);
512  // Go back one match.
513  EXPECT_EQ(3, FindInPageWchar(web_contents, L"o",
514                               kBack, kIgnoreCase, &ordinal));
515  EXPECT_EQ(2, ordinal);
516  EXPECT_EQ(3, FindInPageWchar(web_contents, L"o",
517                               kFwd, kIgnoreCase, &ordinal));
518  EXPECT_EQ(3, ordinal);
519  // This should wrap to the top.
520  EXPECT_EQ(3, FindInPageWchar(web_contents, L"o",
521                               kFwd, kIgnoreCase, &ordinal));
522  EXPECT_EQ(1, ordinal);
523  // This should go back to the end.
524  EXPECT_EQ(3, FindInPageWchar(web_contents, L"o",
525                               kBack, kIgnoreCase, &ordinal));
526  EXPECT_EQ(3, ordinal);
527}
528
529// This tests that the ordinal is correctly adjusted after a selection
530IN_PROC_BROWSER_TEST_F(FindInPageControllerTest,
531                       SelectChangesOrdinal_Issue20883) {
532  // First we navigate to our test content.
533  GURL url = GetURL(kSelectChangesOrdinal);
534  ui_test_utils::NavigateToURL(browser(), url);
535
536  // Search for a text that exists within a link on the page.
537  WebContents* web_contents =
538      browser()->tab_strip_model()->GetActiveWebContents();
539  ASSERT_TRUE(NULL != web_contents);
540  FindTabHelper* find_tab_helper =
541      FindTabHelper::FromWebContents(web_contents);
542
543  int ordinal = 0;
544  EXPECT_EQ(4, FindInPageWchar(web_contents,
545                               L"google",
546                               kFwd, kIgnoreCase, &ordinal));
547  EXPECT_EQ(1, ordinal);
548
549  // Move the selection to link 1, after searching.
550  std::string result;
551  ASSERT_TRUE(content::ExecuteScriptAndExtractString(
552      web_contents,
553      "window.domAutomationController.send(selectLink1());",
554      &result));
555
556  // Do a find-next after the selection.  This should move forward
557  // from there to the 3rd instance of 'google'.
558  EXPECT_EQ(4, FindInPageWchar(web_contents,
559                               L"google",
560                               kFwd, kIgnoreCase, &ordinal));
561  EXPECT_EQ(3, ordinal);
562
563  // End the find session.
564  find_tab_helper->StopFinding(FindBarController::kKeepSelectionOnPage);
565}
566
567// This tests that we start searching after selected text.
568IN_PROC_BROWSER_TEST_F(FindInPageControllerTest,
569                       StartSearchAfterSelection) {
570  // First we navigate to our test content.
571  ui_test_utils::NavigateToURL(browser(), GetURL(kStartAfterSelection));
572
573  WebContents* web_contents =
574      browser()->tab_strip_model()->GetActiveWebContents();
575  ASSERT_TRUE(web_contents != NULL);
576  int ordinal = 0;
577
578  // Move the selection to the text span.
579  std::string result;
580  ASSERT_TRUE(content::ExecuteScriptAndExtractString(
581      web_contents,
582      "window.domAutomationController.send(selectSpan());",
583      &result));
584
585  // Do a find-next after the selection. This should select the 2nd occurrence
586  // of the word 'find'.
587  EXPECT_EQ(4, FindInPageWchar(web_contents,
588                               L"fi",
589                               kFwd, kIgnoreCase, &ordinal));
590  EXPECT_EQ(2, ordinal);
591
592  // Refine the search, current active match should not change.
593  EXPECT_EQ(4, FindInPageWchar(web_contents,
594                               L"find",
595                               kFwd, kIgnoreCase, &ordinal));
596  EXPECT_EQ(2, ordinal);
597
598  // Refine the search to 'findMe'. The first new match is before the current
599  // active match, the second one is after it. This verifies that refining a
600  // search doesn't reset it.
601  EXPECT_EQ(2, FindInPageWchar(web_contents,
602                               L"findMe",
603                               kFwd, kIgnoreCase, &ordinal));
604  EXPECT_EQ(2, ordinal);
605}
606
607// This test loads a page with frames and makes sure the ordinal returned makes
608// sense.
609IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindInPageMultiFramesOrdinal) {
610  // First we navigate to our page.
611  GURL url = GetURL(kFramePage);
612  ui_test_utils::NavigateToURL(browser(), url);
613
614  // Search for 'a', which should make the first item active and return
615  // '1 in 7' (1st ordinal of a total of 7 matches).
616  WebContents* web_contents =
617      browser()->tab_strip_model()->GetActiveWebContents();
618  int ordinal = 0;
619  EXPECT_EQ(7,
620            FindInPageWchar(web_contents, L"a", kFwd, kIgnoreCase, &ordinal));
621  EXPECT_EQ(1, ordinal);
622  EXPECT_EQ(7,
623            FindInPageWchar(web_contents, L"a", kFwd, kIgnoreCase, &ordinal));
624  EXPECT_EQ(2, ordinal);
625  EXPECT_EQ(7,
626            FindInPageWchar(web_contents, L"a", kFwd, kIgnoreCase, &ordinal));
627  EXPECT_EQ(3, ordinal);
628  EXPECT_EQ(7,
629            FindInPageWchar(web_contents, L"a", kFwd, kIgnoreCase, &ordinal));
630  EXPECT_EQ(4, ordinal);
631  // Go back one, which should go back one frame.
632  EXPECT_EQ(7,
633            FindInPageWchar(web_contents, L"a", kBack, kIgnoreCase, &ordinal));
634  EXPECT_EQ(3, ordinal);
635  EXPECT_EQ(7,
636            FindInPageWchar(web_contents, L"a", kFwd, kIgnoreCase, &ordinal));
637  EXPECT_EQ(4, ordinal);
638  EXPECT_EQ(7,
639            FindInPageWchar(web_contents, L"a", kFwd, kIgnoreCase, &ordinal));
640  EXPECT_EQ(5, ordinal);
641  EXPECT_EQ(7,
642            FindInPageWchar(web_contents, L"a", kFwd, kIgnoreCase, &ordinal));
643  EXPECT_EQ(6, ordinal);
644  EXPECT_EQ(7,
645            FindInPageWchar(web_contents, L"a", kFwd, kIgnoreCase, &ordinal));
646  EXPECT_EQ(7, ordinal);
647  // Now we should wrap back to frame 1.
648  EXPECT_EQ(7,
649            FindInPageWchar(web_contents, L"a", kFwd, kIgnoreCase, &ordinal));
650  EXPECT_EQ(1, ordinal);
651  // Now we should wrap back to frame last frame.
652  EXPECT_EQ(7,
653            FindInPageWchar(web_contents, L"a", kBack, kIgnoreCase, &ordinal));
654  EXPECT_EQ(7, ordinal);
655}
656
657// We could get ordinals out of whack when restarting search in subframes.
658// See http://crbug.com/5132.
659IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindInPage_Issue5132) {
660  // First we navigate to our page.
661  GURL url = GetURL(kFramePage);
662  ui_test_utils::NavigateToURL(browser(), url);
663
664  // Search for 'goa' three times (6 matches on page).
665  int ordinal = 0;
666  WebContents* web_contents =
667      browser()->tab_strip_model()->GetActiveWebContents();
668  EXPECT_EQ(6, FindInPageWchar(web_contents, L"goa",
669                               kFwd, kIgnoreCase, &ordinal));
670  EXPECT_EQ(1, ordinal);
671  EXPECT_EQ(6, FindInPageWchar(web_contents, L"goa",
672                               kFwd, kIgnoreCase, &ordinal));
673  EXPECT_EQ(2, ordinal);
674  EXPECT_EQ(6, FindInPageWchar(web_contents, L"goa",
675                               kFwd, kIgnoreCase, &ordinal));
676  EXPECT_EQ(3, ordinal);
677  // Add space to search (should result in no matches).
678  EXPECT_EQ(0, FindInPageWchar(web_contents, L"goa ",
679                               kFwd, kIgnoreCase, &ordinal));
680  EXPECT_EQ(0, ordinal);
681  // Remove the space, should be back to '3 out of 6')
682  EXPECT_EQ(6, FindInPageWchar(web_contents, L"goa",
683                               kFwd, kIgnoreCase, &ordinal));
684  EXPECT_EQ(3, ordinal);
685}
686
687// This tests that the ordinal and match count is cleared after a navigation,
688// as reported in issue http://crbug.com/126468.
689IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, NavigateClearsOrdinal) {
690  // First we navigate to our test content.
691  GURL url = GetURL(kSimple);
692  ui_test_utils::NavigateToURL(browser(), url);
693
694  // Open the Find box. In most tests we can just search without opening the
695  // box first, but in this case we are testing functionality triggered by
696  // NOTIFICATION_NAV_ENTRY_COMMITTED in the FindBarController and the observer
697  // for that event isn't setup unless the box is open.
698  EnsureFindBoxOpen();
699
700  // Search for a text that exists within a link on the page.
701  WebContents* web_contents =
702      browser()->tab_strip_model()->GetActiveWebContents();
703  ASSERT_TRUE(NULL != web_contents);
704  int ordinal = 0;
705  EXPECT_EQ(8, FindInPageWchar(web_contents,
706                               L"e",
707                               kFwd, kIgnoreCase, &ordinal));
708  EXPECT_EQ(1, ordinal);
709
710  // Then navigate away (to any page).
711  url = GetURL(kLinkPage);
712  ui_test_utils::NavigateToURL(browser(), url);
713
714  // Open the Find box again.
715  EnsureFindBoxOpen();
716
717  EXPECT_EQ(ASCIIToUTF16("e"), GetFindBarText());
718  EXPECT_EQ(ASCIIToUTF16(""), GetMatchCountText());
719}
720
721// Load a page with no selectable text and make sure we don't crash.
722IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindUnselectableText) {
723  // First we navigate to our page.
724  GURL url = GetURL(kUserSelectPage);
725  ui_test_utils::NavigateToURL(browser(), url);
726
727  int ordinal = 0;
728  WebContents* web_contents =
729      browser()->tab_strip_model()->GetActiveWebContents();
730  EXPECT_EQ(1, FindInPageWchar(web_contents,
731                               L"text",
732                               kFwd, kIgnoreCase, &ordinal));
733  EXPECT_EQ(1, ordinal);
734}
735
736// Try to reproduce the crash seen in issue 1341577.
737IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindCrash_Issue1341577) {
738  // First we navigate to our page.
739  GURL url = GetURL(kCrashPage);
740  ui_test_utils::NavigateToURL(browser(), url);
741
742  // This would crash the tab. These must be the first two find requests issued
743  // against the frame, otherwise an active frame pointer is set and it wont
744  // produce the crash.
745  // We used to check the return value and |ordinal|. With ICU 4.2, FiP does
746  // not find a stand-alone dependent vowel sign of Indic scripts. So, the
747  // exptected values are all 0. To make this test pass regardless of
748  // ICU version, we just call FiP and see if there's any crash.
749  // TODO(jungshik): According to a native Malayalam speaker, it's ok not
750  // to find U+0D4C. Still need to investigate further this issue.
751  int ordinal = 0;
752  WebContents* web_contents =
753      browser()->tab_strip_model()->GetActiveWebContents();
754  FindInPageWchar(web_contents, L"\u0D4C", kFwd, kIgnoreCase, &ordinal);
755  FindInPageWchar(web_contents, L"\u0D4C", kFwd, kIgnoreCase, &ordinal);
756
757  // This should work fine.
758  EXPECT_EQ(1, FindInPageWchar(web_contents, L"\u0D24\u0D46",
759                               kFwd, kIgnoreCase, &ordinal));
760  EXPECT_EQ(1, ordinal);
761  EXPECT_EQ(0, FindInPageWchar(web_contents, L"nostring",
762                               kFwd, kIgnoreCase, &ordinal));
763  EXPECT_EQ(0, ordinal);
764}
765
766// Try to reproduce the crash seen in http://crbug.com/14491, where an assert
767// hits in the BitStack size comparison in WebKit.
768IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindCrash_Issue14491) {
769  // First we navigate to our page.
770  GURL url = GetURL(kBitstackCrash);
771  ui_test_utils::NavigateToURL(browser(), url);
772
773  // This used to crash the tab.
774  int ordinal = 0;
775  EXPECT_EQ(0, FindInPageWchar(browser()->tab_strip_model()->
776                                   GetActiveWebContents(),
777                               L"s", kFwd, kIgnoreCase, &ordinal));
778  EXPECT_EQ(0, ordinal);
779}
780
781// Test to make sure Find does the right thing when restarting from a timeout.
782// We used to have a problem where we'd stop finding matches when all of the
783// following conditions were true:
784// 1) The page has a lot of text to search.
785// 2) The page contains more than one match.
786// 3) It takes longer than the time-slice given to each Find operation (100
787//    ms) to find one or more of those matches (so Find times out and has to try
788//    again from where it left off).
789IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindRestarts_Issue1155639) {
790  // First we navigate to our page.
791  GURL url = GetURL(kTooFewMatchesPage);
792  ui_test_utils::NavigateToURL(browser(), url);
793
794  // This string appears 5 times at the bottom of a long page. If Find restarts
795  // properly after a timeout, it will find 5 matches, not just 1.
796  int ordinal = 0;
797  EXPECT_EQ(5, FindInPageWchar(browser()->tab_strip_model()->
798                                   GetActiveWebContents(),
799                               L"008.xml",
800                               kFwd, kIgnoreCase, &ordinal));
801  EXPECT_EQ(1, ordinal);
802}
803
804// Make sure we don't get into an infinite loop when text box contains very
805// large amount of text.
806// Disable the test as it started being flaky, see http://crbug/367701.
807IN_PROC_BROWSER_TEST_F(FindInPageControllerTest,
808                       DISABLED_FindRestarts_Issue70505) {
809  // First we navigate to our page.
810  GURL url = GetURL(kLongTextareaPage);
811  ui_test_utils::NavigateToURL(browser(), url);
812
813  // If this test hangs on the FindInPage call, then it might be a regression
814  // such as the one found in issue http://crbug.com/70505.
815  int ordinal = 0;
816  FindInPageWchar(browser()->tab_strip_model()->GetActiveWebContents(),
817                  L"a", kFwd, kIgnoreCase, &ordinal);
818  EXPECT_EQ(1, ordinal);
819  // TODO(finnur): We cannot reliably get the matchcount for this Find call
820  // until we fix issue http://crbug.com/71176.
821}
822
823// This tests bug 11761: FindInPage terminates search prematurely.
824// This test is not expected to pass until bug 11761 is fixed.
825IN_PROC_BROWSER_TEST_F(FindInPageControllerTest,
826                       DISABLED_FindInPagePrematureEnd) {
827  // First we navigate to our special focus tracking page.
828  GURL url = GetURL(kPrematureEnd);
829  ui_test_utils::NavigateToURL(browser(), url);
830
831  WebContents* web_contents =
832      browser()->tab_strip_model()->GetActiveWebContents();
833  ASSERT_TRUE(NULL != web_contents);
834
835  // Search for a text that exists within a link on the page.
836  int ordinal = 0;
837  EXPECT_EQ(2, FindInPageWchar(web_contents, L"html ",
838                               kFwd, kIgnoreCase, &ordinal));
839  EXPECT_EQ(1, ordinal);
840}
841
842// Verify that the find bar is hidden on reload and navigation.
843IN_PROC_BROWSER_TEST_F(FindInPageControllerTest,
844                       HideFindBarOnNavigateAndReload) {
845  // First we navigate to our special focus tracking page.
846  GURL url = GetURL(kSimple);
847  GURL url2 = GetURL(kFramePage);
848  ui_test_utils::NavigateToURL(browser(), url);
849
850  chrome::ShowFindBar(browser());
851
852  gfx::Point position;
853  bool fully_visible = false;
854
855  // Make sure it is open.
856  EXPECT_TRUE(GetFindBarWindowInfo(&position, &fully_visible));
857  EXPECT_TRUE(fully_visible);
858
859  // Reload and make sure the find window goes away.
860  content::WindowedNotificationObserver observer(
861      content::NOTIFICATION_LOAD_STOP,
862      content::Source<NavigationController>(
863          &browser()->tab_strip_model()->GetActiveWebContents()->
864              GetController()));
865  chrome::Reload(browser(), CURRENT_TAB);
866  observer.Wait();
867  EXPECT_TRUE(GetFindBarWindowInfo(&position, &fully_visible));
868  EXPECT_FALSE(fully_visible);
869
870  // Open the find bar again.
871  chrome::ShowFindBar(browser());
872
873  // Make sure it is open.
874  EXPECT_TRUE(GetFindBarWindowInfo(&position, &fully_visible));
875  EXPECT_TRUE(fully_visible);
876
877  // Navigate and make sure the find window goes away.
878  ui_test_utils::NavigateToURL(browser(), url2);
879
880  EXPECT_TRUE(GetFindBarWindowInfo(&position, &fully_visible));
881  EXPECT_FALSE(fully_visible);
882}
883
884IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindStayVisibleOnAnchorLoad) {
885  // First we navigate to our special focus tracking page.
886  GURL url = GetURL(kAnchorPage);
887  ui_test_utils::NavigateToURL(browser(), url);
888
889  chrome::ShowFindBar(browser());
890
891  gfx::Point position;
892  bool fully_visible = false;
893
894  // Make sure it is open.
895  EXPECT_TRUE(GetFindBarWindowInfo(&position, &fully_visible));
896  EXPECT_TRUE(fully_visible);
897
898  // Navigate to the same page (but add an anchor/ref/fragment/whatever the kids
899  // are calling it these days).
900  GURL url_with_anchor = url.Resolve(kAnchor);
901  ui_test_utils::NavigateToURL(browser(), url_with_anchor);
902
903  // Make sure it is still open.
904  EXPECT_TRUE(GetFindBarWindowInfo(&position, &fully_visible));
905  EXPECT_TRUE(fully_visible);
906}
907
908// FindDisappearOnNewTabAndHistory is flaky, at least on Mac.
909// See http://crbug.com/43072
910#if defined(OS_MACOSX)
911#define MAYBE_FindDisappearOnNewTabAndHistory DISABLED_FindDisappearOnNewTabAndHistory
912#else
913#define MAYBE_FindDisappearOnNewTabAndHistory FindDisappearOnNewTabAndHistory
914#endif
915
916// Make sure Find box disappears when History/Downloads page is opened, and
917// when a New Tab is opened.
918IN_PROC_BROWSER_TEST_F(FindInPageControllerTest,
919                       MAYBE_FindDisappearOnNewTabAndHistory) {
920  // First we navigate to our special focus tracking page.
921  GURL url = GetURL(kSimple);
922  ui_test_utils::NavigateToURL(browser(), url);
923
924  chrome::ShowFindBar(browser());
925
926  gfx::Point position;
927  bool fully_visible = false;
928
929  // Make sure it is open.
930  EXPECT_TRUE(GetFindBarWindowInfo(&position, &fully_visible));
931  EXPECT_TRUE(fully_visible);
932
933  // Open another tab (tab B).
934  chrome::NewTab(browser());
935  ui_test_utils::NavigateToURL(browser(), url);
936
937  // Make sure Find box is closed.
938  EXPECT_TRUE(GetFindBarWindowInfo(&position, &fully_visible));
939  EXPECT_FALSE(fully_visible);
940
941  // Close tab B.
942  chrome::CloseTab(browser());
943
944  // Make sure Find window appears again.
945  EXPECT_TRUE(GetFindBarWindowInfo(&position, &fully_visible));
946  EXPECT_TRUE(fully_visible);
947
948  chrome::ShowHistory(browser());
949
950  // Make sure Find box is closed.
951  EXPECT_TRUE(GetFindBarWindowInfo(&position, &fully_visible));
952  EXPECT_FALSE(fully_visible);
953}
954
955// Make sure Find box moves out of the way if it is obscuring the active match.
956IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindMovesWhenObscuring) {
957  GURL url = GetURL(kMoveIfOver);
958  ui_test_utils::NavigateToURL(browser(), url);
959
960  chrome::ShowFindBar(browser());
961
962  // This is needed on GTK because the reposition operation is asynchronous.
963  base::MessageLoop::current()->RunUntilIdle();
964
965  gfx::Point start_position;
966  gfx::Point position;
967  bool fully_visible = false;
968  int ordinal = 0;
969
970  // Make sure it is open.
971  EXPECT_TRUE(GetFindBarWindowInfo(&start_position, &fully_visible));
972  EXPECT_TRUE(fully_visible);
973
974  WebContents* web_contents =
975      browser()->tab_strip_model()->GetActiveWebContents();
976
977  int moved_x_coord = FindInPageTillBoxMoves(web_contents, start_position.x(),
978      L"Chromium", kMoveIterations);
979  // The find box should have moved.
980  EXPECT_TRUE(moved_x_coord != start_position.x());
981
982  // Search for something guaranteed not to be obscured by the Find box.
983  EXPECT_EQ(1, FindInPageWchar(web_contents, L"Done",
984                               kFwd, kIgnoreCase, &ordinal));
985  // Check the position.
986  EXPECT_TRUE(GetFindBarWindowInfo(&position, &fully_visible));
987  EXPECT_TRUE(fully_visible);
988
989  // Make sure Find box has moved back to its original location.
990  EXPECT_EQ(position.x(), start_position.x());
991
992  // Move the find box again.
993  moved_x_coord = FindInPageTillBoxMoves(web_contents, start_position.x(),
994      L"Chromium", kMoveIterations);
995  EXPECT_TRUE(moved_x_coord != start_position.x());
996
997  // Search for an invalid string.
998  EXPECT_EQ(0, FindInPageWchar(web_contents, L"WeirdSearchString",
999                               kFwd, kIgnoreCase, &ordinal));
1000
1001  // Check the position.
1002  EXPECT_TRUE(GetFindBarWindowInfo(&position, &fully_visible));
1003  EXPECT_TRUE(fully_visible);
1004
1005  // Make sure Find box has moved back to its original location.
1006  EXPECT_EQ(position.x(), start_position.x());
1007}
1008
1009// FindNextInNewTabUsesPrepopulate times-out on Mac and Aura.
1010// See http://crbug.com/43070
1011#if defined(OS_MACOSX) || defined(USE_AURA)
1012#define MAYBE_FindNextInNewTabUsesPrepopulate \
1013    DISABLED_FindNextInNewTabUsesPrepopulate
1014#else
1015#define MAYBE_FindNextInNewTabUsesPrepopulate FindNextInNewTabUsesPrepopulate
1016#endif
1017
1018// Make sure F3 in a new tab works if Find has previous string to search for.
1019IN_PROC_BROWSER_TEST_F(FindInPageControllerTest,
1020                       MAYBE_FindNextInNewTabUsesPrepopulate) {
1021  // First we navigate to any page.
1022  GURL url = GetURL(kSimple);
1023  ui_test_utils::NavigateToURL(browser(), url);
1024
1025  // Search for 'no_match'. No matches should be found.
1026  int ordinal = 0;
1027  WebContents* web_contents =
1028      browser()->tab_strip_model()->GetActiveWebContents();
1029  EXPECT_EQ(0, FindInPageWchar(web_contents, L"no_match",
1030                               kFwd, kIgnoreCase, &ordinal));
1031  EXPECT_EQ(0, ordinal);
1032
1033  // Open another tab (tab B).
1034  chrome::NewTab(browser());
1035  ui_test_utils::NavigateToURL(browser(), url);
1036
1037  // Simulate what happens when you press F3 for FindNext. We should get a
1038  // response here (a hang means search was aborted).
1039  EXPECT_EQ(0, ui_test_utils::FindInPage(web_contents, base::string16(),
1040                                         kFwd, kIgnoreCase, &ordinal, NULL));
1041  EXPECT_EQ(0, ordinal);
1042
1043  // Open another tab (tab C).
1044  chrome::NewTab(browser());
1045  ui_test_utils::NavigateToURL(browser(), url);
1046
1047  // Simulate what happens when you press F3 for FindNext. We should get a
1048  // response here (a hang means search was aborted).
1049  EXPECT_EQ(0, ui_test_utils::FindInPage(web_contents, base::string16(),
1050                                         kFwd, kIgnoreCase, &ordinal, NULL));
1051  EXPECT_EQ(0, ordinal);
1052}
1053
1054// Make sure Find box does not become UI-inactive when no text is in the box as
1055// we switch to a tab contents with an empty find string. See issue 13570.
1056IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, StayActive) {
1057  // First we navigate to any page.
1058  GURL url = GetURL(kSimple);
1059  ui_test_utils::NavigateToURL(browser(), url);
1060
1061  chrome::ShowFindBar(browser());
1062
1063  // Simulate a user clearing the search string. Ideally, we should be
1064  // simulating keypresses here for searching for something and pressing
1065  // backspace, but that's been proven flaky in the past, so we go straight to
1066  // web_contents.
1067  FindTabHelper* find_tab_helper = FindTabHelper::FromWebContents(
1068      browser()->tab_strip_model()->GetActiveWebContents());
1069  // Stop the (non-existing) find operation, and clear the selection (which
1070  // signals the UI is still active).
1071  find_tab_helper->StopFinding(FindBarController::kClearSelectionOnPage);
1072  // Make sure the Find UI flag hasn't been cleared, it must be so that the UI
1073  // still responds to browser window resizing.
1074  ASSERT_TRUE(find_tab_helper->find_ui_active());
1075}
1076
1077// Make sure F3 works after you FindNext a couple of times and end the Find
1078// session. See issue http://crbug.com/28306.
1079IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, RestartSearchFromF3) {
1080  // First we navigate to a simple page.
1081  GURL url = GetURL(kSimple);
1082  ui_test_utils::NavigateToURL(browser(), url);
1083
1084  // Search for 'page'. Should have 1 match.
1085  int ordinal = 0;
1086  WebContents* web_contents =
1087      browser()->tab_strip_model()->GetActiveWebContents();
1088  EXPECT_EQ(1, FindInPageWchar(web_contents, L"page",
1089                               kFwd, kIgnoreCase, &ordinal));
1090  EXPECT_EQ(1, ordinal);
1091
1092  // Simulate what happens when you press F3 for FindNext. Still should show
1093  // one match. This cleared the pre-populate string at one point (see bug).
1094  EXPECT_EQ(1, ui_test_utils::FindInPage(web_contents, base::string16(),
1095                                         kFwd, kIgnoreCase, &ordinal, NULL));
1096  EXPECT_EQ(1, ordinal);
1097
1098  // End the Find session, thereby making the next F3 start afresh.
1099  browser()->GetFindBarController()->EndFindSession(
1100      FindBarController::kKeepSelectionOnPage,
1101      FindBarController::kKeepResultsInFindBox);
1102
1103  // Simulate F3 while Find box is closed. Should have 1 match.
1104  EXPECT_EQ(1, FindInPageWchar(web_contents, L"", kFwd, kIgnoreCase, &ordinal));
1105  EXPECT_EQ(1, ordinal);
1106}
1107
1108// When re-opening the find bar with F3, the find bar should be re-populated
1109// with the last search from the same tab rather than the last overall search.
1110// The only exception is if there is a global pasteboard (for example on Mac).
1111// http://crbug.com/30006
1112IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, PreferPreviousSearch) {
1113  // First we navigate to any page.
1114  GURL url = GetURL(kSimple);
1115  ui_test_utils::NavigateToURL(browser(), url);
1116
1117  // Find "Default".
1118  int ordinal = 0;
1119  WebContents* web_contents_1 =
1120      browser()->tab_strip_model()->GetActiveWebContents();
1121  EXPECT_EQ(1, FindInPageWchar(web_contents_1, L"text",
1122                               kFwd, kIgnoreCase, &ordinal));
1123
1124  // Create a second tab.
1125  // For some reason we can't use AddSelectedTabWithURL here on ChromeOS. It
1126  // could be some delicate assumption about the tab starting off unselected or
1127  // something relating to user gesture.
1128  chrome::AddTabAt(browser(), GURL(), -1, true);
1129  ui_test_utils::NavigateToURL(browser(), url);
1130  WebContents* web_contents_2 =
1131      browser()->tab_strip_model()->GetActiveWebContents();
1132  EXPECT_NE(web_contents_1, web_contents_2);
1133
1134  // Find "given".
1135  FindInPageWchar(web_contents_2, L"given", kFwd, kIgnoreCase, &ordinal);
1136
1137  // Switch back to first tab.
1138  browser()->tab_strip_model()->ActivateTabAt(0, false);
1139  browser()->GetFindBarController()->EndFindSession(
1140      FindBarController::kKeepSelectionOnPage,
1141      FindBarController::kKeepResultsInFindBox);
1142  // Simulate F3.
1143  ui_test_utils::FindInPage(web_contents_1, base::string16(),
1144                            kFwd, kIgnoreCase, &ordinal, NULL);
1145  FindBar* find_bar = browser()->GetFindBarController()->find_bar();
1146  if (find_bar->HasGlobalFindPasteboard()) {
1147    EXPECT_EQ(FindTabHelper::FromWebContents(web_contents_1)->find_text(),
1148              WideToUTF16(L"given"));
1149  } else {
1150    EXPECT_EQ(FindTabHelper::FromWebContents(web_contents_1)->find_text(),
1151              WideToUTF16(L"text"));
1152  }
1153}
1154
1155// This tests that whenever you close and reopen the Find bar, it should show
1156// the last search entered in that tab. http://crbug.com/40121.
1157IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, PrepopulateSameTab) {
1158  // First we navigate to any page.
1159  GURL url = GetURL(kSimple);
1160  ui_test_utils::NavigateToURL(browser(), url);
1161
1162  // Search for the word "page".
1163  int ordinal = 0;
1164  WebContents* web_contents =
1165      browser()->tab_strip_model()->GetActiveWebContents();
1166  EXPECT_EQ(1, FindInPageWchar(web_contents, L"page",
1167                               kFwd, kIgnoreCase, &ordinal));
1168
1169  // Open the Find box.
1170  EnsureFindBoxOpen();
1171
1172  EXPECT_EQ(ASCIIToUTF16("page"), GetFindBarText());
1173  EXPECT_EQ(ASCIIToUTF16("1 of 1"), GetMatchCountText());
1174
1175  // Close the Find box.
1176  browser()->GetFindBarController()->EndFindSession(
1177      FindBarController::kKeepSelectionOnPage,
1178      FindBarController::kKeepResultsInFindBox);
1179
1180  // Open the Find box again.
1181  EnsureFindBoxOpen();
1182
1183  // After the Find box has been reopened, it should have been prepopulated with
1184  // the word "page" again.
1185  EXPECT_EQ(ASCIIToUTF16("page"), GetFindBarText());
1186  EXPECT_EQ(ASCIIToUTF16("1 of 1"), GetMatchCountText());
1187}
1188
1189// This tests that whenever you open Find in a new tab it should prepopulate
1190// with a previous search term (in any tab), if a search has not been issued in
1191// this tab before.
1192IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, PrepopulateInNewTab) {
1193  // First we navigate to any page.
1194  GURL url = GetURL(kSimple);
1195  ui_test_utils::NavigateToURL(browser(), url);
1196
1197  // Search for the word "page".
1198  int ordinal = 0;
1199  WebContents* web_contents_1 =
1200      browser()->tab_strip_model()->GetActiveWebContents();
1201  EXPECT_EQ(1, FindInPageWchar(web_contents_1, L"page",
1202                               kFwd, kIgnoreCase, &ordinal));
1203  EXPECT_EQ(ASCIIToUTF16("1 of 1"), GetMatchCountText());
1204
1205  // Now create a second tab and load the same page.
1206  chrome::AddSelectedTabWithURL(browser(), url, ui::PAGE_TRANSITION_TYPED);
1207  WebContents* web_contents_2 =
1208      browser()->tab_strip_model()->GetActiveWebContents();
1209  EXPECT_NE(web_contents_1, web_contents_2);
1210
1211  // Open the Find box.
1212  EnsureFindBoxOpen();
1213
1214  // The new tab should have "page" prepopulated, since that was the last search
1215  // in the first tab.
1216  EXPECT_EQ(ASCIIToUTF16("page"), GetFindBarText());
1217  // But it should not seem like a search has been issued.
1218  EXPECT_EQ(base::string16(), GetMatchCountText());
1219}
1220
1221// This makes sure that we can search for A in tabA, then for B in tabB and
1222// when we come back to tabA we should still see A (because that was the last
1223// search in that tab).
1224IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, PrepopulatePreserveLast) {
1225  FindBar* find_bar = browser()->GetFindBarController()->find_bar();
1226  if (find_bar->HasGlobalFindPasteboard())
1227    return;
1228
1229  // First we navigate to any page.
1230  GURL url = GetURL(kSimple);
1231  ui_test_utils::NavigateToURL(browser(), url);
1232
1233  // Search for the word "page".
1234  int ordinal = 0;
1235  WebContents* web_contents_1 =
1236      browser()->tab_strip_model()->GetActiveWebContents();
1237  EXPECT_EQ(1, FindInPageWchar(web_contents_1, L"page",
1238                               kFwd, kIgnoreCase, &ordinal));
1239
1240  // Open the Find box.
1241  EnsureFindBoxOpen();
1242
1243  EXPECT_EQ(ASCIIToUTF16("page"), GetFindBarText());
1244
1245  // Close the Find box.
1246  browser()->GetFindBarController()->EndFindSession(
1247      FindBarController::kKeepSelectionOnPage,
1248      FindBarController::kKeepResultsInFindBox);
1249
1250  // Now create a second tab and load the same page.
1251  chrome::AddTabAt(browser(), GURL(), -1, true);
1252  ui_test_utils::NavigateToURL(browser(), url);
1253  WebContents* web_contents_2 =
1254      browser()->tab_strip_model()->GetActiveWebContents();
1255  EXPECT_NE(web_contents_1, web_contents_2);
1256
1257  // Search for the word "text".
1258  FindInPageWchar(web_contents_2, L"text", kFwd, kIgnoreCase, &ordinal);
1259
1260  // Go back to the first tab and make sure we have NOT switched the prepopulate
1261  // text to "text".
1262  browser()->tab_strip_model()->ActivateTabAt(0, false);
1263
1264  // Open the Find box.
1265  EnsureFindBoxOpen();
1266
1267  // After the Find box has been reopened, it should have been prepopulated with
1268  // the word "page" again, since that was the last search in that tab.
1269  EXPECT_EQ(ASCIIToUTF16("page"), GetFindBarText());
1270
1271  // Close the Find box.
1272  browser()->GetFindBarController()->EndFindSession(
1273      FindBarController::kKeepSelectionOnPage,
1274      FindBarController::kKeepResultsInFindBox);
1275
1276  // Re-open the Find box.
1277  // This is a special case: previous search in WebContents used to get cleared
1278  // if you opened and closed the FindBox, which would cause the global
1279  // prepopulate value to show instead of last search in this tab.
1280  EnsureFindBoxOpen();
1281
1282  // After the Find box has been reopened, it should have been prepopulated with
1283  // the word "page" again, since that was the last search in that tab.
1284  EXPECT_EQ(ASCIIToUTF16("page"), GetFindBarText());
1285}
1286
1287// TODO(rohitrao): Searching in incognito tabs does not work in browser tests in
1288// Linux views.  Investigate and fix.  http://crbug.com/40948
1289#if defined(OS_LINUX) && defined(TOOLKIT_VIEWS)
1290#define MAYBE_NoIncognitoPrepopulate DISABLED_NoIncognitoPrepopulate
1291#else
1292#define MAYBE_NoIncognitoPrepopulate NoIncognitoPrepopulate
1293#endif
1294
1295// This tests that search terms entered into an incognito find bar are not used
1296// as prepopulate terms for non-incognito windows.
1297IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, MAYBE_NoIncognitoPrepopulate) {
1298  FindBar* find_bar = browser()->GetFindBarController()->find_bar();
1299  if (find_bar->HasGlobalFindPasteboard())
1300    return;
1301
1302  // First we navigate to the "simple" test page.
1303  GURL url = GetURL(kSimple);
1304  ui_test_utils::NavigateToURL(browser(), url);
1305
1306  // Search for the word "page" in the normal browser tab.
1307  int ordinal = 0;
1308  WebContents* web_contents_1 =
1309      browser()->tab_strip_model()->GetActiveWebContents();
1310  EXPECT_EQ(1, FindInPageWchar(web_contents_1, L"page",
1311                               kFwd, kIgnoreCase, &ordinal));
1312
1313  // Open the Find box.
1314  EnsureFindBoxOpenForBrowser(browser());
1315  EXPECT_EQ(ASCIIToUTF16("page"), GetFindBarTextForBrowser(browser()));
1316
1317  // Close the Find box.
1318  browser()->GetFindBarController()->EndFindSession(
1319      FindBarController::kKeepSelectionOnPage,
1320      FindBarController::kKeepResultsInFindBox);
1321
1322  // Open a new incognito window and navigate to the same page.
1323  Profile* incognito_profile = browser()->profile()->GetOffTheRecordProfile();
1324  Browser* incognito_browser =
1325      new Browser(Browser::CreateParams(incognito_profile,
1326                                        browser()->host_desktop_type()));
1327  content::WindowedNotificationObserver observer(
1328      content::NOTIFICATION_LOAD_STOP,
1329      content::NotificationService::AllSources());
1330  chrome::AddSelectedTabWithURL(incognito_browser, url,
1331                                ui::PAGE_TRANSITION_AUTO_TOPLEVEL);
1332  observer.Wait();
1333  incognito_browser->window()->Show();
1334
1335  // Open the find box and make sure that it is prepopulated with "page".
1336  EnsureFindBoxOpenForBrowser(incognito_browser);
1337  EXPECT_EQ(ASCIIToUTF16("page"), GetFindBarTextForBrowser(incognito_browser));
1338
1339  // Search for the word "text" in the incognito tab.
1340  WebContents* incognito_tab =
1341      incognito_browser->tab_strip_model()->GetActiveWebContents();
1342  EXPECT_EQ(1, FindInPageWchar(incognito_tab, L"text",
1343                               kFwd, kIgnoreCase, &ordinal));
1344  EXPECT_EQ(ASCIIToUTF16("text"), GetFindBarTextForBrowser(incognito_browser));
1345
1346  // Close the Find box.
1347  incognito_browser->GetFindBarController()->EndFindSession(
1348      FindBarController::kKeepSelectionOnPage,
1349      FindBarController::kKeepResultsInFindBox);
1350
1351  // Now open a new tab in the original (non-incognito) browser.
1352  chrome::AddSelectedTabWithURL(browser(), url, ui::PAGE_TRANSITION_TYPED);
1353  WebContents* web_contents_2 =
1354      browser()->tab_strip_model()->GetActiveWebContents();
1355  EXPECT_NE(web_contents_1, web_contents_2);
1356
1357  // Open the Find box and make sure it is prepopulated with the search term
1358  // from the original browser, not the search term from the incognito window.
1359  EnsureFindBoxOpenForBrowser(browser());
1360  EXPECT_EQ(ASCIIToUTF16("page"), GetFindBarTextForBrowser(browser()));
1361}
1362
1363// This makes sure that dismissing the find bar with kActivateSelection works.
1364IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, ActivateLinkNavigatesPage) {
1365  // First we navigate to our test content.
1366  GURL url = GetURL(kLinkPage);
1367  ui_test_utils::NavigateToURL(browser(), url);
1368
1369  WebContents* web_contents =
1370      browser()->tab_strip_model()->GetActiveWebContents();
1371  FindTabHelper* find_tab_helper =
1372      FindTabHelper::FromWebContents(web_contents);
1373
1374  int ordinal = 0;
1375  FindInPageWchar(web_contents, L"link", kFwd, kIgnoreCase, &ordinal);
1376  EXPECT_EQ(ordinal, 1);
1377
1378  // End the find session, click on the link.
1379  content::WindowedNotificationObserver observer(
1380      content::NOTIFICATION_LOAD_STOP,
1381      content::Source<NavigationController>(&web_contents->GetController()));
1382  find_tab_helper->StopFinding(FindBarController::kActivateSelectionOnPage);
1383  observer.Wait();
1384}
1385
1386IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FitWindow) {
1387  Browser::CreateParams params(Browser::TYPE_POPUP, browser()->profile(),
1388                               browser()->host_desktop_type());
1389  params.initial_bounds = gfx::Rect(0, 0, 250, 500);
1390  Browser* popup = new Browser(params);
1391  content::WindowedNotificationObserver observer(
1392      content::NOTIFICATION_LOAD_STOP,
1393      content::NotificationService::AllSources());
1394  chrome::AddSelectedTabWithURL(
1395      popup, GURL(url::kAboutBlankURL), ui::PAGE_TRANSITION_LINK);
1396  // Wait for the page to finish loading.
1397  observer.Wait();
1398  popup->window()->Show();
1399
1400  // On GTK, bounds change is asynchronous.
1401  base::MessageLoop::current()->RunUntilIdle();
1402
1403  EnsureFindBoxOpenForBrowser(popup);
1404
1405  // GTK adjusts FindBar size asynchronously.
1406  base::MessageLoop::current()->RunUntilIdle();
1407
1408  ASSERT_LE(GetFindBarWidthForBrowser(popup),
1409            popup->window()->GetBounds().width());
1410}
1411
1412IN_PROC_BROWSER_TEST_F(FindInPageControllerTest,
1413                       FindMovesOnTabClose_Issue1343052) {
1414  EnsureFindBoxOpen();
1415  content::RunAllPendingInMessageLoop();  // Needed on Linux.
1416
1417  gfx::Point position;
1418  EXPECT_TRUE(GetFindBarWindowInfo(&position, NULL));
1419
1420  // Open another tab.
1421  GURL url = GetURL(kSimple);
1422  ui_test_utils::NavigateToURLWithDisposition(
1423      browser(), url, NEW_FOREGROUND_TAB,
1424      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1425
1426  // Close it.
1427  chrome::CloseTab(browser());
1428
1429  // See if the Find window has moved.
1430  gfx::Point position2;
1431  EXPECT_TRUE(GetFindBarWindowInfo(&position2, NULL));
1432  EXPECT_EQ(position, position2);
1433
1434  // Toggle the bookmark bar state. Note that this starts an animation, and
1435  // there isn't a good way other than looping and polling to see when it's
1436  // done. So instead we change the state and open a new tab, since the new tab
1437  // animation doesn't happen on tab change.
1438  chrome::ToggleBookmarkBar(browser());
1439
1440  ui_test_utils::NavigateToURLWithDisposition(
1441      browser(), url, NEW_FOREGROUND_TAB,
1442      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1443
1444  EnsureFindBoxOpen();
1445  content::RunAllPendingInMessageLoop();  // Needed on Linux.
1446  EXPECT_TRUE(GetFindBarWindowInfo(&position, NULL));
1447
1448  ui_test_utils::NavigateToURLWithDisposition(
1449      browser(), url, NEW_FOREGROUND_TAB,
1450      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1451  chrome::CloseTab(browser());
1452  EXPECT_TRUE(GetFindBarWindowInfo(&position2, NULL));
1453  EXPECT_EQ(position, position2);
1454}
1455
1456// Verify that if there's a global pasteboard (for example on Mac) then doing
1457// a search on one tab will clear the matches label on the other tabs.
1458IN_PROC_BROWSER_TEST_F(FindInPageControllerTest,
1459                       GlobalPasteBoardClearMatches) {
1460  FindBar* find_bar = browser()->GetFindBarController()->find_bar();
1461  if (!find_bar->HasGlobalFindPasteboard())
1462    return;
1463
1464  // First we navigate to any page.
1465  GURL url = GetURL(kSimple);
1466  ui_test_utils::NavigateToURL(browser(), url);
1467
1468  // Change the match count on the first tab to "1 of 1".
1469  int ordinal = 0;
1470  WebContents* web_contents_1 =
1471      browser()->tab_strip_model()->GetActiveWebContents();
1472  EXPECT_EQ(1, FindInPageWchar(web_contents_1, L"page",
1473                               kFwd, kIgnoreCase, &ordinal));
1474  EnsureFindBoxOpen();
1475  EXPECT_EQ(ASCIIToUTF16("1 of 1"), GetMatchCountText());
1476
1477  // Next, do a search in a second tab.
1478  chrome::AddTabAt(browser(), GURL(), -1, true);
1479  ui_test_utils::NavigateToURL(browser(), url);
1480  WebContents* web_contents_2 =
1481      browser()->tab_strip_model()->GetActiveWebContents();
1482  FindInPageWchar(web_contents_2, L"text", kFwd, kIgnoreCase, &ordinal);
1483  EXPECT_EQ(ASCIIToUTF16("1 of 1"), GetMatchCountText());
1484
1485  // Go back to the first tab and verify that the match text is cleared.
1486  // text to "text".
1487  browser()->tab_strip_model()->ActivateTabAt(0, false);
1488  EXPECT_EQ(ASCIIToUTF16(""), GetMatchCountText());
1489}
1490
1491// Verify that Incognito window doesn't propagate find string to other widows.
1492IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, GlobalPasteboardIncognito) {
1493  Browser* browser_incognito = CreateIncognitoBrowser();
1494  WebContents* web_contents_1 =
1495      browser()->tab_strip_model()->GetActiveWebContents();
1496  FindInPageWchar(web_contents_1, L"page", kFwd, kIgnoreCase, NULL);
1497  EXPECT_EQ(ASCIIToUTF16("page"), GetFindBarText());
1498  WebContents* web_contents_2 =
1499      browser_incognito->tab_strip_model()->GetActiveWebContents();
1500  FindInPageWchar(web_contents_2, L"Incognito", kFwd, kIgnoreCase, NULL);
1501  EXPECT_EQ(ASCIIToUTF16("Incognito"),
1502      GetFindBarTextForBrowser(browser_incognito));
1503  EXPECT_EQ(ASCIIToUTF16("page"), GetFindBarText());
1504}
1505
1506// Find text in regular window, find different text in incognito, send
1507// IDC_FIND_NEXT to incognito. It should search for the second phrase.
1508IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, IncognitoFindNextSecret) {
1509  WebContents* web_contents =
1510      browser()->tab_strip_model()->GetActiveWebContents();
1511  // On Mac this updates the find pboard.
1512  FindInPageWchar(web_contents, L"bar", kFwd, kIgnoreCase, NULL);
1513
1514  Browser* browser_incognito = CreateIncognitoBrowser();
1515  ui_test_utils::NavigateToURL(browser_incognito,
1516                               GURL("data:text/plain,barfoofoo"));
1517  WebContents* web_contents_incognito =
1518        browser_incognito->tab_strip_model()->GetActiveWebContents();
1519  FindInPageWchar(web_contents_incognito, L"foo", true, kIgnoreCase, NULL);
1520  EXPECT_EQ(ASCIIToUTF16("foo"),
1521      GetFindBarTextForBrowser(browser_incognito));
1522  EXPECT_EQ(ASCIIToUTF16("1 of 2"),
1523      GetFindBarMatchCountTextForBrowser(browser_incognito));
1524
1525  // Close the find bar.
1526  FindTabHelper* find_tab_helper =
1527      FindTabHelper::FromWebContents(web_contents_incognito);
1528  find_tab_helper->StopFinding(FindBarController::kActivateSelectionOnPage);
1529
1530  // Cmd + G triggers IDC_FIND_NEXT command. Thus we test FindInPage()
1531  // method from browser_commands.cc. FindInPageWchar() bypasses it.
1532  EXPECT_TRUE(chrome::ExecuteCommand(browser_incognito, IDC_FIND_NEXT));
1533  ui_test_utils::FindInPageNotificationObserver observer(
1534      web_contents_incognito);
1535  observer.Wait();
1536  EXPECT_EQ(ASCIIToUTF16("foo"),
1537      GetFindBarTextForBrowser(browser_incognito));
1538  EXPECT_EQ(ASCIIToUTF16("2 of 2"),
1539      GetFindBarMatchCountTextForBrowser(browser_incognito));
1540}
1541
1542// Find text in regular window, send IDC_FIND_NEXT to incognito. It should
1543// search for the first phrase.
1544IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, IncognitoFindNextShared) {
1545  WebContents* web_contents =
1546      browser()->tab_strip_model()->GetActiveWebContents();
1547  // On Mac this updates the find pboard.
1548  FindInPageWchar(web_contents, L"bar", kFwd, kIgnoreCase, NULL);
1549
1550  Browser* browser_incognito = CreateIncognitoBrowser();
1551  ui_test_utils::NavigateToURL(browser_incognito,
1552                               GURL("data:text/plain,bar"));
1553
1554  EXPECT_TRUE(chrome::ExecuteCommand(browser_incognito, IDC_FIND_NEXT));
1555  WebContents* web_contents_incognito =
1556      browser_incognito->tab_strip_model()->GetActiveWebContents();
1557  ui_test_utils::FindInPageNotificationObserver observer(
1558      web_contents_incognito);
1559  observer.Wait();
1560  EXPECT_EQ(ASCIIToUTF16("bar"),
1561            GetFindBarTextForBrowser(browser_incognito));
1562}
1563