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:
WaitForHistoryTask()44 WaitForHistoryTask() {}
45
RunOnDBThread(history::HistoryBackend * backend,history::HistoryDatabase * db)46 virtual bool RunOnDBThread(history::HistoryBackend* backend,
47 history::HistoryDatabase* db) OVERRIDE {
48 return true;
49 }
50
DoneRunOnMainThread()51 virtual void DoneRunOnMainThread() OVERRIDE {
52 base::MessageLoop::current()->Quit();
53 }
54
55 private:
~WaitForHistoryTask()56 virtual ~WaitForHistoryTask() {}
57
58 DISALLOW_COPY_AND_ASSIGN(WaitForHistoryTask);
59 };
60
61 } // namespace
62
63 class HistoryBrowserTest : public InProcessBrowserTest {
64 protected:
SetUpCommandLine(CommandLine * command_line)65 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
66 command_line->AppendSwitch(switches::kEnableFileCookies);
67 }
68
GetPrefs()69 PrefService* GetPrefs() {
70 return GetProfile()->GetPrefs();
71 }
72
GetProfile()73 Profile* GetProfile() {
74 return browser()->profile();
75 }
76
GetHistoryContents()77 std::vector<GURL> GetHistoryContents() {
78 ui_test_utils::HistoryEnumerator enumerator(GetProfile());
79 return enumerator.urls();
80 }
81
GetTestUrl()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
WaitForHistoryBackendToRun()88 void WaitForHistoryBackendToRun() {
89 base::CancelableTaskTracker task_tracker;
90 scoped_ptr<history::HistoryDBTask> task(new WaitForHistoryTask());
91 HistoryService* history =
92 HistoryServiceFactory::GetForProfile(GetProfile(),
93 Profile::EXPLICIT_ACCESS);
94 history->HistoryService::ScheduleDBTask(task.Pass(), &task_tracker);
95 content::RunMessageLoop();
96 }
97
ExpectEmptyHistory()98 void ExpectEmptyHistory() {
99 std::vector<GURL> urls(GetHistoryContents());
100 EXPECT_EQ(0U, urls.size());
101 }
102
LoadAndWaitForURL(const GURL & url)103 void LoadAndWaitForURL(const GURL& url) {
104 base::string16 expected_title(base::ASCIIToUTF16("OK"));
105 content::TitleWatcher title_watcher(
106 browser()->tab_strip_model()->GetActiveWebContents(), expected_title);
107 title_watcher.AlsoWaitForTitle(base::ASCIIToUTF16("FAIL"));
108 ui_test_utils::NavigateToURL(browser(), url);
109 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
110 }
111
LoadAndWaitForFile(const char * filename)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).
IN_PROC_BROWSER_TEST_F(HistoryBrowserTest,SavingHistoryEnabled)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.
IN_PROC_BROWSER_TEST_F(HistoryBrowserTest,SavingHistoryDisabled)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.
IN_PROC_BROWSER_TEST_F(HistoryBrowserTest,SavingHistoryEnabledThenDisabled)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.
IN_PROC_BROWSER_TEST_F(HistoryBrowserTest,SavingHistoryDisabledThenEnabled)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
IN_PROC_BROWSER_TEST_F(HistoryBrowserTest,VerifyHistoryLength1)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
IN_PROC_BROWSER_TEST_F(HistoryBrowserTest,VerifyHistoryLength2)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
IN_PROC_BROWSER_TEST_F(HistoryBrowserTest,VerifyHistoryLength3)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
IN_PROC_BROWSER_TEST_F(HistoryBrowserTest,ConsiderRedirectAfterGestureAsUserInitiated)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 blink::WebMouseEvent::ButtonLeft);
252 LoadAndWaitForFile("history_length_test_page_11.html");
253 }
254
IN_PROC_BROWSER_TEST_F(HistoryBrowserTest,ConsiderSlowRedirectAsUserInitiated)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
IN_PROC_BROWSER_TEST_F(HistoryBrowserTest,MAYBE_HistorySearchXSS)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 base::ASCIIToUTF16("<img"), true,
283 true, NULL, NULL);
284 EXPECT_GT(num, 0);
285 EXPECT_EQ(base::ASCIIToUTF16("History"),
286 browser()->tab_strip_model()->GetActiveWebContents()->GetTitle());
287 }
288
289 // Verify that history persists after session restart.
IN_PROC_BROWSER_TEST_F(HistoryBrowserTest,PRE_HistoryPersists)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
IN_PROC_BROWSER_TEST_F(HistoryBrowserTest,HistoryPersists)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.
IN_PROC_BROWSER_TEST_F(HistoryBrowserTest,InvalidURLNoHistory)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.
IN_PROC_BROWSER_TEST_F(HistoryBrowserTest,NewTabNoHistory)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.
IN_PROC_BROWSER_TEST_F(HistoryBrowserTest,IncognitoNoHistory)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.
IN_PROC_BROWSER_TEST_F(HistoryBrowserTest,NavigateMultiTimes)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.
IN_PROC_BROWSER_TEST_F(HistoryBrowserTest,MultiTabsWindowsHistory)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.
IN_PROC_BROWSER_TEST_F(HistoryBrowserTest,DownloadNoHistory)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.
IN_PROC_BROWSER_TEST_F(HistoryBrowserTest,RedirectHistory)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.
IN_PROC_BROWSER_TEST_F(HistoryBrowserTest,NavigateBringPageToTop)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.
IN_PROC_BROWSER_TEST_F(HistoryBrowserTest,ReloadBringPageToTop)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.
IN_PROC_BROWSER_TEST_F(HistoryBrowserTest,BackForwardBringPageToTop)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.
IN_PROC_BROWSER_TEST_F(HistoryBrowserTest,SubmitFormAddsTargetPage)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 base::string16 expected_title(base::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.
IN_PROC_BROWSER_TEST_F(HistoryBrowserTest,OneHistoryTabPerWindow)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 base::string16 expected_title(base::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(),
498 GURL(url::kAboutBlankURL),
499 NEW_FOREGROUND_TAB,
500 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
501 chrome::ExecuteCommand(browser(), IDC_SHOW_HISTORY);
502
503 content::WebContents* active_web_contents =
504 browser()->tab_strip_model()->GetActiveWebContents();
505 ASSERT_EQ(web_contents, active_web_contents);
506 ASSERT_EQ(history_url, active_web_contents->GetURL());
507
508 content::WebContents* second_tab =
509 browser()->tab_strip_model()->GetWebContentsAt(1);
510 ASSERT_NE(history_url, second_tab->GetURL());
511 }
512