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