90fd7db35640fd450c6ef87d276a2b71977ec18d
[platform/framework/web/crosswalk.git] / src / chrome / browser / history / history_browsertest.cc
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 <vector>
6
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/app/chrome_command_ids.h"
13 #include "chrome/browser/history/history_db_task.h"
14 #include "chrome/browser/history/history_service.h"
15 #include "chrome/browser/history/history_service_factory.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/ui/browser.h"
18 #include "chrome/browser/ui/browser_commands.h"
19 #include "chrome/browser/ui/tabs/tab_strip_model.h"
20 #include "chrome/common/chrome_switches.h"
21 #include "chrome/common/pref_names.h"
22 #include "chrome/common/url_constants.h"
23 #include "chrome/test/base/in_process_browser_test.h"
24 #include "chrome/test/base/ui_test_utils.h"
25 #include "content/public/browser/web_contents.h"
26 #include "content/public/test/browser_test_utils.h"
27 #include "content/public/test/test_browser_thread.h"
28 #include "url/gurl.h"
29
30 using content::BrowserThread;
31
32 namespace {
33
34 // Note: WaitableEvent is not used for synchronization between the main thread
35 // and history backend thread because the history subsystem posts tasks back
36 // to the main thread. Had we tried to Signal an event in such a task
37 // and Wait for it on the main thread, the task would not run at all because
38 // the main thread would be blocked on the Wait call, resulting in a deadlock.
39
40 // A task to be scheduled on the history backend thread.
41 // Notifies the main thread after all history backend thread tasks have run.
42 class WaitForHistoryTask : public history::HistoryDBTask {
43  public:
44   WaitForHistoryTask() {}
45
46   bool RunOnDBThread(history::HistoryBackend* backend,
47                      history::HistoryDatabase* db) override {
48     return true;
49   }
50
51   void DoneRunOnMainThread() override { base::MessageLoop::current()->Quit(); }
52
53  private:
54   ~WaitForHistoryTask() override {}
55
56   DISALLOW_COPY_AND_ASSIGN(WaitForHistoryTask);
57 };
58
59 }  // namespace
60
61 class HistoryBrowserTest : public InProcessBrowserTest {
62  protected:
63   void SetUpCommandLine(CommandLine* command_line) override {
64     command_line->AppendSwitch(switches::kEnableFileCookies);
65   }
66
67   PrefService* GetPrefs() {
68     return GetProfile()->GetPrefs();
69   }
70
71   Profile* GetProfile() {
72     return browser()->profile();
73   }
74
75   std::vector<GURL> GetHistoryContents() {
76     ui_test_utils::HistoryEnumerator enumerator(GetProfile());
77     return enumerator.urls();
78   }
79
80   GURL GetTestUrl() {
81     return ui_test_utils::GetTestUrl(
82         base::FilePath(base::FilePath::kCurrentDirectory),
83         base::FilePath(FILE_PATH_LITERAL("title2.html")));
84   }
85
86   void WaitForHistoryBackendToRun() {
87     base::CancelableTaskTracker task_tracker;
88     scoped_ptr<history::HistoryDBTask> task(new WaitForHistoryTask());
89     HistoryService* history =
90         HistoryServiceFactory::GetForProfile(GetProfile(),
91                                              Profile::EXPLICIT_ACCESS);
92     history->HistoryService::ScheduleDBTask(task.Pass(), &task_tracker);
93     content::RunMessageLoop();
94   }
95
96   void ExpectEmptyHistory() {
97     std::vector<GURL> urls(GetHistoryContents());
98     EXPECT_EQ(0U, urls.size());
99   }
100
101   void LoadAndWaitForURL(const GURL& url) {
102     base::string16 expected_title(base::ASCIIToUTF16("OK"));
103     content::TitleWatcher title_watcher(
104         browser()->tab_strip_model()->GetActiveWebContents(), expected_title);
105     title_watcher.AlsoWaitForTitle(base::ASCIIToUTF16("FAIL"));
106     ui_test_utils::NavigateToURL(browser(), url);
107     EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
108   }
109
110   void LoadAndWaitForFile(const char* filename) {
111     GURL url = ui_test_utils::GetTestUrl(
112         base::FilePath().AppendASCII("History"),
113         base::FilePath().AppendASCII(filename));
114     LoadAndWaitForURL(url);
115   }
116 };
117
118 // Test that the browser history is saved (default setting).
119 IN_PROC_BROWSER_TEST_F(HistoryBrowserTest, SavingHistoryEnabled) {
120   EXPECT_FALSE(GetPrefs()->GetBoolean(prefs::kSavingBrowserHistoryDisabled));
121
122   EXPECT_TRUE(HistoryServiceFactory::GetForProfile(
123       GetProfile(), Profile::EXPLICIT_ACCESS));
124   EXPECT_TRUE(HistoryServiceFactory::GetForProfile(
125       GetProfile(), Profile::IMPLICIT_ACCESS));
126
127   ui_test_utils::WaitForHistoryToLoad(HistoryServiceFactory::GetForProfile(
128       browser()->profile(), Profile::EXPLICIT_ACCESS));
129   ExpectEmptyHistory();
130
131   ui_test_utils::NavigateToURL(browser(), GetTestUrl());
132   WaitForHistoryBackendToRun();
133
134   {
135     std::vector<GURL> urls(GetHistoryContents());
136     ASSERT_EQ(1U, urls.size());
137     EXPECT_EQ(GetTestUrl().spec(), urls[0].spec());
138   }
139 }
140
141 // Test that disabling saving browser history really works.
142 IN_PROC_BROWSER_TEST_F(HistoryBrowserTest, SavingHistoryDisabled) {
143   GetPrefs()->SetBoolean(prefs::kSavingBrowserHistoryDisabled, true);
144
145   EXPECT_TRUE(HistoryServiceFactory::GetForProfile(
146       GetProfile(), Profile::EXPLICIT_ACCESS));
147   EXPECT_FALSE(HistoryServiceFactory::GetForProfile(
148       GetProfile(), Profile::IMPLICIT_ACCESS));
149
150   ui_test_utils::WaitForHistoryToLoad(HistoryServiceFactory::GetForProfile(
151       browser()->profile(), Profile::EXPLICIT_ACCESS));
152   ExpectEmptyHistory();
153
154   ui_test_utils::NavigateToURL(browser(), GetTestUrl());
155   WaitForHistoryBackendToRun();
156   ExpectEmptyHistory();
157 }
158
159 // Test that changing the pref takes effect immediately
160 // when the browser is running.
161 IN_PROC_BROWSER_TEST_F(HistoryBrowserTest, SavingHistoryEnabledThenDisabled) {
162   EXPECT_FALSE(GetPrefs()->GetBoolean(prefs::kSavingBrowserHistoryDisabled));
163
164   ui_test_utils::WaitForHistoryToLoad(HistoryServiceFactory::GetForProfile(
165       browser()->profile(), Profile::EXPLICIT_ACCESS));
166
167   ui_test_utils::NavigateToURL(browser(), GetTestUrl());
168   WaitForHistoryBackendToRun();
169
170   {
171     std::vector<GURL> urls(GetHistoryContents());
172     ASSERT_EQ(1U, urls.size());
173     EXPECT_EQ(GetTestUrl().spec(), urls[0].spec());
174   }
175
176   GetPrefs()->SetBoolean(prefs::kSavingBrowserHistoryDisabled, true);
177
178   ui_test_utils::NavigateToURL(browser(), GetTestUrl());
179   WaitForHistoryBackendToRun();
180
181   {
182     // No additional entries should be present in the history.
183     std::vector<GURL> urls(GetHistoryContents());
184     ASSERT_EQ(1U, urls.size());
185     EXPECT_EQ(GetTestUrl().spec(), urls[0].spec());
186   }
187 }
188
189 // Test that changing the pref takes effect immediately
190 // when the browser is running.
191 IN_PROC_BROWSER_TEST_F(HistoryBrowserTest, SavingHistoryDisabledThenEnabled) {
192   GetPrefs()->SetBoolean(prefs::kSavingBrowserHistoryDisabled, true);
193
194   ui_test_utils::WaitForHistoryToLoad(HistoryServiceFactory::GetForProfile(
195       browser()->profile(), Profile::EXPLICIT_ACCESS));
196   ExpectEmptyHistory();
197
198   ui_test_utils::NavigateToURL(browser(), GetTestUrl());
199   WaitForHistoryBackendToRun();
200   ExpectEmptyHistory();
201
202   GetPrefs()->SetBoolean(prefs::kSavingBrowserHistoryDisabled, false);
203
204   ui_test_utils::NavigateToURL(browser(), GetTestUrl());
205   WaitForHistoryBackendToRun();
206
207   {
208     std::vector<GURL> urls(GetHistoryContents());
209     ASSERT_EQ(1U, urls.size());
210     EXPECT_EQ(GetTestUrl().spec(), urls[0].spec());
211   }
212 }
213
214 IN_PROC_BROWSER_TEST_F(HistoryBrowserTest, VerifyHistoryLength1) {
215   // Test the history length for the following page transitions.
216   //   -open-> Page 1.
217   LoadAndWaitForFile("history_length_test_page_1.html");
218 }
219
220 IN_PROC_BROWSER_TEST_F(HistoryBrowserTest, VerifyHistoryLength2) {
221   // Test the history length for the following page transitions.
222   //   -open-> Page 2 -redirect-> Page 3.
223   LoadAndWaitForFile("history_length_test_page_2.html");
224 }
225
226 IN_PROC_BROWSER_TEST_F(HistoryBrowserTest, VerifyHistoryLength3) {
227   // Test the history length for the following page transitions.
228   // -open-> Page 1 -> open Page 2 -redirect Page 3. open Page 4
229   // -navigate_backward-> Page 3 -navigate_backward->Page 1
230   // -navigate_forward-> Page 3 -navigate_forward-> Page 4
231   LoadAndWaitForFile("history_length_test_page_1.html");
232   LoadAndWaitForFile("history_length_test_page_2.html");
233   LoadAndWaitForFile("history_length_test_page_4.html");
234 }
235
236 IN_PROC_BROWSER_TEST_F(HistoryBrowserTest,
237                        ConsiderRedirectAfterGestureAsUserInitiated) {
238   // Test the history length for the following page transition.
239   //
240   // -open-> Page 11 -slow_redirect-> Page 12.
241   //
242   // If redirect occurs after a user gesture, e.g., mouse click, the
243   // redirect is more likely to be user-initiated rather than automatic.
244   // Therefore, Page 11 should be in the history in addition to Page 12.
245   LoadAndWaitForFile("history_length_test_page_11.html");
246
247   content::SimulateMouseClick(
248       browser()->tab_strip_model()->GetActiveWebContents(), 0,
249       blink::WebMouseEvent::ButtonLeft);
250   LoadAndWaitForFile("history_length_test_page_11.html");
251 }
252
253 IN_PROC_BROWSER_TEST_F(HistoryBrowserTest,
254                        ConsiderSlowRedirectAsUserInitiated) {
255   // Test the history length for the following page transition.
256   //
257   // -open-> Page 21 -redirect-> Page 22.
258   //
259   // If redirect occurs more than 5 seconds later after the page is loaded,
260   // the redirect is likely to be user-initiated.
261   // Therefore, Page 21 should be in the history in addition to Page 22.
262   LoadAndWaitForFile("history_length_test_page_21.html");
263 }
264
265 // http://crbug.com/22111
266 #if defined(OS_LINUX)
267 #define MAYBE_HistorySearchXSS DISABLED_HistorySearchXSS
268 #else
269 #define MAYBE_HistorySearchXSS HistorySearchXSS
270 #endif
271 IN_PROC_BROWSER_TEST_F(HistoryBrowserTest, MAYBE_HistorySearchXSS) {
272   GURL url(std::string(chrome::kChromeUIHistoryURL) +
273       "#q=%3Cimg%20src%3Dx%3Ax%20onerror%3D%22document.title%3D'XSS'%22%3E");
274   ui_test_utils::NavigateToURL(browser(), url);
275   // Mainly, this is to ensure we send a synchronous message to the renderer
276   // so that we're not susceptible (less susceptible?) to a race condition.
277   // Should a race condition ever trigger, it won't result in flakiness.
278   int num = ui_test_utils::FindInPage(
279       browser()->tab_strip_model()->GetActiveWebContents(),
280       base::ASCIIToUTF16("<img"), true,
281       true, NULL, NULL);
282   EXPECT_GT(num, 0);
283   EXPECT_EQ(base::ASCIIToUTF16("History"),
284             browser()->tab_strip_model()->GetActiveWebContents()->GetTitle());
285 }
286
287 // Verify that history persists after session restart.
288 IN_PROC_BROWSER_TEST_F(HistoryBrowserTest, PRE_HistoryPersists) {
289   ui_test_utils::NavigateToURL(browser(), GetTestUrl());
290   std::vector<GURL> urls(GetHistoryContents());
291   ASSERT_EQ(1u, urls.size());
292   ASSERT_EQ(GetTestUrl(), urls[0]);
293 }
294
295 IN_PROC_BROWSER_TEST_F(HistoryBrowserTest, HistoryPersists) {
296   std::vector<GURL> urls(GetHistoryContents());
297   ASSERT_EQ(1u, urls.size());
298   ASSERT_EQ(GetTestUrl(), urls[0]);
299 }
300
301 // Invalid URLs should not go in history.
302 IN_PROC_BROWSER_TEST_F(HistoryBrowserTest, InvalidURLNoHistory) {
303   GURL non_existant = ui_test_utils::GetTestUrl(
304       base::FilePath().AppendASCII("History"),
305       base::FilePath().AppendASCII("non_existant_file.html"));
306   ui_test_utils::NavigateToURL(browser(), non_existant);
307   ExpectEmptyHistory();
308 }
309
310 // New tab page should not show up in history.
311 IN_PROC_BROWSER_TEST_F(HistoryBrowserTest, NewTabNoHistory) {
312   ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUINewTabURL));
313   ExpectEmptyHistory();
314 }
315
316 // Incognito browsing should not show up in history.
317 IN_PROC_BROWSER_TEST_F(HistoryBrowserTest, IncognitoNoHistory) {
318   ui_test_utils::NavigateToURL(CreateIncognitoBrowser(), GetTestUrl());
319   ExpectEmptyHistory();
320 }
321
322 // Multiple navigations to the same url should have a single history.
323 IN_PROC_BROWSER_TEST_F(HistoryBrowserTest, NavigateMultiTimes) {
324   ui_test_utils::NavigateToURL(browser(), GetTestUrl());
325   ui_test_utils::NavigateToURL(browser(), GetTestUrl());
326   std::vector<GURL> urls(GetHistoryContents());
327   ASSERT_EQ(1u, urls.size());
328   ASSERT_EQ(GetTestUrl(), urls[0]);
329 }
330
331 // Verify history with multiple windows and tabs.
332 IN_PROC_BROWSER_TEST_F(HistoryBrowserTest, MultiTabsWindowsHistory) {
333   GURL url1 = GetTestUrl();
334   GURL url2  = ui_test_utils::GetTestUrl(
335       base::FilePath(), base::FilePath(FILE_PATH_LITERAL("title1.html")));
336   GURL url3  = ui_test_utils::GetTestUrl(
337       base::FilePath(), base::FilePath(FILE_PATH_LITERAL("title3.html")));
338   GURL url4  = ui_test_utils::GetTestUrl(
339       base::FilePath(), base::FilePath(FILE_PATH_LITERAL("simple.html")));
340
341   ui_test_utils::NavigateToURL(browser(), url1);
342   Browser* browser2 = CreateBrowser(browser()->profile());
343   ui_test_utils::NavigateToURL(browser2, url2);
344   ui_test_utils::NavigateToURLWithDisposition(
345       browser2, url3, NEW_FOREGROUND_TAB,
346       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
347   ui_test_utils::NavigateToURLWithDisposition(
348       browser2, url4, NEW_FOREGROUND_TAB,
349       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
350
351   std::vector<GURL> urls(GetHistoryContents());
352   ASSERT_EQ(4u, urls.size());
353   ASSERT_EQ(url4, urls[0]);
354   ASSERT_EQ(url3, urls[1]);
355   ASSERT_EQ(url2, urls[2]);
356   ASSERT_EQ(url1, urls[3]);
357 }
358
359 // Downloaded URLs should not show up in history.
360 IN_PROC_BROWSER_TEST_F(HistoryBrowserTest, DownloadNoHistory) {
361   GURL download_url = ui_test_utils::GetTestUrl(
362       base::FilePath().AppendASCII("downloads"),
363       base::FilePath().AppendASCII("a_zip_file.zip"));
364   ui_test_utils::DownloadURL(browser(), download_url);
365   ExpectEmptyHistory();
366 }
367
368 // HTTP meta-refresh redirects should have separate history entries.
369 IN_PROC_BROWSER_TEST_F(HistoryBrowserTest, RedirectHistory) {
370   GURL redirector = ui_test_utils::GetTestUrl(
371       base::FilePath().AppendASCII("History"),
372       base::FilePath().AppendASCII("redirector.html"));
373   GURL landing_url = ui_test_utils::GetTestUrl(
374       base::FilePath().AppendASCII("History"),
375       base::FilePath().AppendASCII("landing.html"));
376   ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
377       browser(), redirector, 2);
378   ASSERT_EQ(landing_url,
379             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
380   std::vector<GURL> urls(GetHistoryContents());
381   ASSERT_EQ(2u, urls.size());
382   ASSERT_EQ(landing_url, urls[0]);
383   ASSERT_EQ(redirector, urls[1]);
384 }
385
386 // Verify that navigation brings current page to top of history list.
387 IN_PROC_BROWSER_TEST_F(HistoryBrowserTest, NavigateBringPageToTop) {
388   GURL url1 = GetTestUrl();
389   GURL url2  = ui_test_utils::GetTestUrl(
390       base::FilePath(), base::FilePath(FILE_PATH_LITERAL("title3.html")));
391
392   ui_test_utils::NavigateToURL(browser(), url1);
393   ui_test_utils::NavigateToURL(browser(), url2);
394
395   std::vector<GURL> urls(GetHistoryContents());
396   ASSERT_EQ(2u, urls.size());
397   ASSERT_EQ(url2, urls[0]);
398   ASSERT_EQ(url1, urls[1]);
399 }
400
401 // Verify that reloading a page brings it to top of history list.
402 IN_PROC_BROWSER_TEST_F(HistoryBrowserTest, ReloadBringPageToTop) {
403   GURL url1 = GetTestUrl();
404   GURL url2  = ui_test_utils::GetTestUrl(
405       base::FilePath(), base::FilePath(FILE_PATH_LITERAL("title3.html")));
406
407   ui_test_utils::NavigateToURL(browser(), url1);
408   ui_test_utils::NavigateToURLWithDisposition(
409       browser(), url2, NEW_BACKGROUND_TAB,
410       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
411
412   std::vector<GURL> urls(GetHistoryContents());
413   ASSERT_EQ(2u, urls.size());
414   ASSERT_EQ(url2, urls[0]);
415   ASSERT_EQ(url1, urls[1]);
416
417   content::WebContents* tab =
418       browser()->tab_strip_model()->GetActiveWebContents();
419   tab->GetController().Reload(false);
420   content::WaitForLoadStop(tab);
421
422   urls = GetHistoryContents();
423   ASSERT_EQ(2u, urls.size());
424   ASSERT_EQ(url1, urls[0]);
425   ASSERT_EQ(url2, urls[1]);
426 }
427
428 // Verify that back/forward brings current page to top of history list.
429 IN_PROC_BROWSER_TEST_F(HistoryBrowserTest, BackForwardBringPageToTop) {
430   GURL url1 = GetTestUrl();
431   GURL url2  = ui_test_utils::GetTestUrl(
432       base::FilePath(), base::FilePath(FILE_PATH_LITERAL("title3.html")));
433
434   ui_test_utils::NavigateToURL(browser(), url1);
435   ui_test_utils::NavigateToURL(browser(), url2);
436
437   content::WebContents* tab =
438       browser()->tab_strip_model()->GetActiveWebContents();
439   chrome::GoBack(browser(), CURRENT_TAB);
440   content::WaitForLoadStop(tab);
441
442   std::vector<GURL> urls(GetHistoryContents());
443   ASSERT_EQ(2u, urls.size());
444   ASSERT_EQ(url1, urls[0]);
445   ASSERT_EQ(url2, urls[1]);
446
447   chrome::GoForward(browser(), CURRENT_TAB);
448   content::WaitForLoadStop(tab);
449   urls = GetHistoryContents();
450   ASSERT_EQ(2u, urls.size());
451   ASSERT_EQ(url2, urls[0]);
452   ASSERT_EQ(url1, urls[1]);
453 }
454
455 // Verify that submitting form adds target page to history list.
456 IN_PROC_BROWSER_TEST_F(HistoryBrowserTest, SubmitFormAddsTargetPage) {
457   GURL form = ui_test_utils::GetTestUrl(
458       base::FilePath().AppendASCII("History"),
459       base::FilePath().AppendASCII("form.html"));
460   GURL target = ui_test_utils::GetTestUrl(
461       base::FilePath().AppendASCII("History"),
462       base::FilePath().AppendASCII("target.html"));
463   ui_test_utils::NavigateToURL(browser(), form);
464
465   content::WebContents* web_contents =
466       browser()->tab_strip_model()->GetActiveWebContents();
467   base::string16 expected_title(base::ASCIIToUTF16("Target Page"));
468   content::TitleWatcher title_watcher(
469       browser()->tab_strip_model()->GetActiveWebContents(), expected_title);
470   ASSERT_TRUE(content::ExecuteScript(
471       web_contents, "document.getElementById('form').submit()"));
472   EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
473
474   std::vector<GURL> urls(GetHistoryContents());
475   ASSERT_EQ(2u, urls.size());
476   ASSERT_EQ(target, urls[0]);
477   ASSERT_EQ(form, urls[1]);
478 }
479
480 // Verify history shortcut opens only one history tab per window.  Also, make
481 // sure that existing history tab is activated.
482 IN_PROC_BROWSER_TEST_F(HistoryBrowserTest, OneHistoryTabPerWindow) {
483   GURL history_url(chrome::kChromeUIHistoryURL);
484
485   // Even after navigate completes, the currently-active tab title is
486   // 'Loading...' for a brief time while the history page loads.
487   content::WebContents* web_contents =
488       browser()->tab_strip_model()->GetActiveWebContents();
489   base::string16 expected_title(base::ASCIIToUTF16("History"));
490   content::TitleWatcher title_watcher(web_contents, expected_title);
491   chrome::ExecuteCommand(browser(), IDC_SHOW_HISTORY);
492   EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
493
494   ui_test_utils::NavigateToURLWithDisposition(
495       browser(),
496       GURL(url::kAboutBlankURL),
497       NEW_FOREGROUND_TAB,
498       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
499   chrome::ExecuteCommand(browser(), IDC_SHOW_HISTORY);
500
501   content::WebContents* active_web_contents =
502       browser()->tab_strip_model()->GetActiveWebContents();
503   ASSERT_EQ(web_contents, active_web_contents);
504   ASSERT_EQ(history_url, active_web_contents->GetURL());
505
506   content::WebContents* second_tab =
507       browser()->tab_strip_model()->GetWebContentsAt(1);
508   ASSERT_NE(history_url, second_tab->GetURL());
509 }