OLD | NEW |
| (Empty) |
1 // Copyright (c) 2010 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/file_util.h" | |
6 #include "base/path_service.h" | |
7 #include "base/scoped_ptr.h" | |
8 #include "base/stl_util-inl.h" | |
9 #include "base/string_util.h" | |
10 #include "base/utf_string_conversions.h" | |
11 #include "chrome/browser/profiles/profile_manager.h" | |
12 #include "chrome/browser/history/history.h" | |
13 #include "chrome/browser/renderer_host/site_instance.h" | |
14 #include "chrome/browser/renderer_host/test/test_render_view_host.h" | |
15 #include "chrome/browser/sessions/session_service.h" | |
16 #include "chrome/browser/sessions/session_service_test_helper.h" | |
17 #include "chrome/browser/sessions/session_types.h" | |
18 #include "chrome/browser/tab_contents/navigation_controller.h" | |
19 #include "chrome/browser/tab_contents/navigation_entry.h" | |
20 #include "chrome/browser/tab_contents/tab_contents.h" | |
21 #include "chrome/browser/tab_contents/tab_contents_delegate.h" | |
22 #include "chrome/browser/tab_contents/test_tab_contents.h" | |
23 #include "chrome/common/notification_registrar.h" | |
24 #include "chrome/common/render_messages.h" | |
25 #include "chrome/common/render_messages_params.h" | |
26 #include "chrome/test/test_notification_tracker.h" | |
27 #include "chrome/test/testing_profile.h" | |
28 #include "net/base/net_util.h" | |
29 #include "testing/gtest/include/gtest/gtest.h" | |
30 #include "webkit/glue/webkit_glue.h" | |
31 | |
32 using base::Time; | |
33 | |
34 // NavigationControllerTest ---------------------------------------------------- | |
35 | |
36 class NavigationControllerTest : public RenderViewHostTestHarness { | |
37 public: | |
38 NavigationControllerTest() {} | |
39 }; | |
40 | |
41 // NavigationControllerHistoryTest --------------------------------------------- | |
42 | |
43 class NavigationControllerHistoryTest : public NavigationControllerTest { | |
44 public: | |
45 NavigationControllerHistoryTest() | |
46 : url0("http://foo1"), | |
47 url1("http://foo1"), | |
48 url2("http://foo1"), | |
49 profile_manager_(NULL) { | |
50 } | |
51 | |
52 virtual ~NavigationControllerHistoryTest() { | |
53 // Prevent our base class from deleting the profile since profile's | |
54 // lifetime is managed by profile_manager_. | |
55 STLDeleteElements(&windows_); | |
56 } | |
57 | |
58 // testing::Test overrides. | |
59 virtual void SetUp() { | |
60 NavigationControllerTest::SetUp(); | |
61 | |
62 // Force the session service to be created. | |
63 SessionService* service = new SessionService(profile()); | |
64 profile()->set_session_service(service); | |
65 service->SetWindowType(window_id, Browser::TYPE_NORMAL); | |
66 service->SetWindowBounds(window_id, gfx::Rect(0, 1, 2, 3), false); | |
67 service->SetTabIndexInWindow(window_id, | |
68 controller().session_id(), 0); | |
69 controller().SetWindowID(window_id); | |
70 | |
71 session_helper_.set_service(service); | |
72 } | |
73 | |
74 virtual void TearDown() { | |
75 // Release profile's reference to the session service. Otherwise the file | |
76 // will still be open and we won't be able to delete the directory below. | |
77 profile()->set_session_service(NULL); | |
78 session_helper_.set_service(NULL); | |
79 | |
80 // Make sure we wait for history to shut down before continuing. The task | |
81 // we add will cause our message loop to quit once it is destroyed. | |
82 HistoryService* history = | |
83 profile()->GetHistoryService(Profile::IMPLICIT_ACCESS); | |
84 if (history) { | |
85 history->SetOnBackendDestroyTask(new MessageLoop::QuitTask); | |
86 MessageLoop::current()->Run(); | |
87 } | |
88 | |
89 // Do normal cleanup before deleting the profile directory below. | |
90 NavigationControllerTest::TearDown(); | |
91 | |
92 ASSERT_TRUE(file_util::Delete(test_dir_, true)); | |
93 ASSERT_FALSE(file_util::PathExists(test_dir_)); | |
94 } | |
95 | |
96 // Deletes the current profile manager and creates a new one. Indirectly this | |
97 // shuts down the history database and reopens it. | |
98 void ReopenDatabase() { | |
99 session_helper_.set_service(NULL); | |
100 profile()->set_session_service(NULL); | |
101 | |
102 SessionService* service = new SessionService(profile()); | |
103 profile()->set_session_service(service); | |
104 session_helper_.set_service(service); | |
105 } | |
106 | |
107 void GetLastSession() { | |
108 profile()->GetSessionService()->TabClosed(controller().window_id(), | |
109 controller().session_id(), | |
110 false); | |
111 | |
112 ReopenDatabase(); | |
113 Time close_time; | |
114 | |
115 session_helper_.ReadWindows(&windows_); | |
116 } | |
117 | |
118 CancelableRequestConsumer consumer; | |
119 | |
120 // URLs for testing. | |
121 const GURL url0; | |
122 const GURL url1; | |
123 const GURL url2; | |
124 | |
125 std::vector<SessionWindow*> windows_; | |
126 | |
127 SessionID window_id; | |
128 | |
129 SessionServiceTestHelper session_helper_; | |
130 | |
131 private: | |
132 ProfileManager* profile_manager_; | |
133 FilePath test_dir_; | |
134 }; | |
135 | |
136 void RegisterForAllNavNotifications(TestNotificationTracker* tracker, | |
137 NavigationController* controller) { | |
138 tracker->ListenFor(NotificationType::NAV_ENTRY_COMMITTED, | |
139 Source<NavigationController>(controller)); | |
140 tracker->ListenFor(NotificationType::NAV_LIST_PRUNED, | |
141 Source<NavigationController>(controller)); | |
142 tracker->ListenFor(NotificationType::NAV_ENTRY_CHANGED, | |
143 Source<NavigationController>(controller)); | |
144 } | |
145 | |
146 // ----------------------------------------------------------------------------- | |
147 | |
148 TEST_F(NavigationControllerTest, Defaults) { | |
149 EXPECT_FALSE(controller().pending_entry()); | |
150 EXPECT_FALSE(controller().GetLastCommittedEntry()); | |
151 EXPECT_EQ(controller().pending_entry_index(), -1); | |
152 EXPECT_EQ(controller().last_committed_entry_index(), -1); | |
153 EXPECT_EQ(controller().entry_count(), 0); | |
154 EXPECT_FALSE(controller().CanGoBack()); | |
155 EXPECT_FALSE(controller().CanGoForward()); | |
156 } | |
157 | |
158 TEST_F(NavigationControllerTest, LoadURL) { | |
159 TestNotificationTracker notifications; | |
160 RegisterForAllNavNotifications(¬ifications, &controller()); | |
161 | |
162 const GURL url1("http://foo1"); | |
163 const GURL url2("http://foo2"); | |
164 | |
165 controller().LoadURL(url1, GURL(), PageTransition::TYPED); | |
166 // Creating a pending notification should not have issued any of the | |
167 // notifications we're listening for. | |
168 EXPECT_EQ(0U, notifications.size()); | |
169 | |
170 // The load should now be pending. | |
171 EXPECT_EQ(controller().entry_count(), 0); | |
172 EXPECT_EQ(controller().last_committed_entry_index(), -1); | |
173 EXPECT_EQ(controller().pending_entry_index(), -1); | |
174 EXPECT_FALSE(controller().GetLastCommittedEntry()); | |
175 EXPECT_TRUE(controller().pending_entry()); | |
176 EXPECT_FALSE(controller().CanGoBack()); | |
177 EXPECT_FALSE(controller().CanGoForward()); | |
178 EXPECT_EQ(contents()->GetMaxPageID(), -1); | |
179 | |
180 // We should have gotten no notifications from the preceeding checks. | |
181 EXPECT_EQ(0U, notifications.size()); | |
182 | |
183 rvh()->SendNavigate(0, url1); | |
184 EXPECT_TRUE(notifications.Check1AndReset( | |
185 NotificationType::NAV_ENTRY_COMMITTED)); | |
186 | |
187 // The load should now be committed. | |
188 EXPECT_EQ(controller().entry_count(), 1); | |
189 EXPECT_EQ(controller().last_committed_entry_index(), 0); | |
190 EXPECT_EQ(controller().pending_entry_index(), -1); | |
191 EXPECT_TRUE(controller().GetLastCommittedEntry()); | |
192 EXPECT_FALSE(controller().pending_entry()); | |
193 EXPECT_FALSE(controller().CanGoBack()); | |
194 EXPECT_FALSE(controller().CanGoForward()); | |
195 EXPECT_EQ(contents()->GetMaxPageID(), 0); | |
196 | |
197 // Load another... | |
198 controller().LoadURL(url2, GURL(), PageTransition::TYPED); | |
199 | |
200 // The load should now be pending. | |
201 EXPECT_EQ(controller().entry_count(), 1); | |
202 EXPECT_EQ(controller().last_committed_entry_index(), 0); | |
203 EXPECT_EQ(controller().pending_entry_index(), -1); | |
204 EXPECT_TRUE(controller().GetLastCommittedEntry()); | |
205 EXPECT_TRUE(controller().pending_entry()); | |
206 // TODO(darin): maybe this should really be true? | |
207 EXPECT_FALSE(controller().CanGoBack()); | |
208 EXPECT_FALSE(controller().CanGoForward()); | |
209 EXPECT_EQ(contents()->GetMaxPageID(), 0); | |
210 | |
211 rvh()->SendNavigate(1, url2); | |
212 EXPECT_TRUE(notifications.Check1AndReset( | |
213 NotificationType::NAV_ENTRY_COMMITTED)); | |
214 | |
215 // The load should now be committed. | |
216 EXPECT_EQ(controller().entry_count(), 2); | |
217 EXPECT_EQ(controller().last_committed_entry_index(), 1); | |
218 EXPECT_EQ(controller().pending_entry_index(), -1); | |
219 EXPECT_TRUE(controller().GetLastCommittedEntry()); | |
220 EXPECT_FALSE(controller().pending_entry()); | |
221 EXPECT_TRUE(controller().CanGoBack()); | |
222 EXPECT_FALSE(controller().CanGoForward()); | |
223 EXPECT_EQ(contents()->GetMaxPageID(), 1); | |
224 } | |
225 | |
226 // Tests what happens when the same page is loaded again. Should not create a | |
227 // new session history entry. This is what happens when you press enter in the | |
228 // URL bar to reload: a pending entry is created and then it is discarded when | |
229 // the load commits (because WebCore didn't actually make a new entry). | |
230 TEST_F(NavigationControllerTest, LoadURL_SamePage) { | |
231 TestNotificationTracker notifications; | |
232 RegisterForAllNavNotifications(¬ifications, &controller()); | |
233 | |
234 const GURL url1("http://foo1"); | |
235 | |
236 controller().LoadURL(url1, GURL(), PageTransition::TYPED); | |
237 EXPECT_EQ(0U, notifications.size()); | |
238 rvh()->SendNavigate(0, url1); | |
239 EXPECT_TRUE(notifications.Check1AndReset( | |
240 NotificationType::NAV_ENTRY_COMMITTED)); | |
241 | |
242 controller().LoadURL(url1, GURL(), PageTransition::TYPED); | |
243 EXPECT_EQ(0U, notifications.size()); | |
244 rvh()->SendNavigate(0, url1); | |
245 EXPECT_TRUE(notifications.Check1AndReset( | |
246 NotificationType::NAV_ENTRY_COMMITTED)); | |
247 | |
248 // We should not have produced a new session history entry. | |
249 EXPECT_EQ(controller().entry_count(), 1); | |
250 EXPECT_EQ(controller().last_committed_entry_index(), 0); | |
251 EXPECT_EQ(controller().pending_entry_index(), -1); | |
252 EXPECT_TRUE(controller().GetLastCommittedEntry()); | |
253 EXPECT_FALSE(controller().pending_entry()); | |
254 EXPECT_FALSE(controller().CanGoBack()); | |
255 EXPECT_FALSE(controller().CanGoForward()); | |
256 } | |
257 | |
258 // Tests loading a URL but discarding it before the load commits. | |
259 TEST_F(NavigationControllerTest, LoadURL_Discarded) { | |
260 TestNotificationTracker notifications; | |
261 RegisterForAllNavNotifications(¬ifications, &controller()); | |
262 | |
263 const GURL url1("http://foo1"); | |
264 const GURL url2("http://foo2"); | |
265 | |
266 controller().LoadURL(url1, GURL(), PageTransition::TYPED); | |
267 EXPECT_EQ(0U, notifications.size()); | |
268 rvh()->SendNavigate(0, url1); | |
269 EXPECT_TRUE(notifications.Check1AndReset( | |
270 NotificationType::NAV_ENTRY_COMMITTED)); | |
271 | |
272 controller().LoadURL(url2, GURL(), PageTransition::TYPED); | |
273 controller().DiscardNonCommittedEntries(); | |
274 EXPECT_EQ(0U, notifications.size()); | |
275 | |
276 // Should not have produced a new session history entry. | |
277 EXPECT_EQ(controller().entry_count(), 1); | |
278 EXPECT_EQ(controller().last_committed_entry_index(), 0); | |
279 EXPECT_EQ(controller().pending_entry_index(), -1); | |
280 EXPECT_TRUE(controller().GetLastCommittedEntry()); | |
281 EXPECT_FALSE(controller().pending_entry()); | |
282 EXPECT_FALSE(controller().CanGoBack()); | |
283 EXPECT_FALSE(controller().CanGoForward()); | |
284 } | |
285 | |
286 // Tests navigations that come in unrequested. This happens when the user | |
287 // navigates from the web page, and here we test that there is no pending entry. | |
288 TEST_F(NavigationControllerTest, LoadURL_NoPending) { | |
289 TestNotificationTracker notifications; | |
290 RegisterForAllNavNotifications(¬ifications, &controller()); | |
291 | |
292 // First make an existing committed entry. | |
293 const GURL kExistingURL1("http://eh"); | |
294 controller().LoadURL(kExistingURL1, GURL(), | |
295 PageTransition::TYPED); | |
296 rvh()->SendNavigate(0, kExistingURL1); | |
297 EXPECT_TRUE(notifications.Check1AndReset( | |
298 NotificationType::NAV_ENTRY_COMMITTED)); | |
299 | |
300 // Do a new navigation without making a pending one. | |
301 const GURL kNewURL("http://see"); | |
302 rvh()->SendNavigate(99, kNewURL); | |
303 | |
304 // There should no longer be any pending entry, and the third navigation we | |
305 // just made should be committed. | |
306 EXPECT_TRUE(notifications.Check1AndReset( | |
307 NotificationType::NAV_ENTRY_COMMITTED)); | |
308 EXPECT_EQ(-1, controller().pending_entry_index()); | |
309 EXPECT_EQ(1, controller().last_committed_entry_index()); | |
310 EXPECT_EQ(kNewURL, controller().GetActiveEntry()->url()); | |
311 } | |
312 | |
313 // Tests navigating to a new URL when there is a new pending navigation that is | |
314 // not the one that just loaded. This will happen if the user types in a URL to | |
315 // somewhere slow, and then navigates the current page before the typed URL | |
316 // commits. | |
317 TEST_F(NavigationControllerTest, LoadURL_NewPending) { | |
318 TestNotificationTracker notifications; | |
319 RegisterForAllNavNotifications(¬ifications, &controller()); | |
320 | |
321 // First make an existing committed entry. | |
322 const GURL kExistingURL1("http://eh"); | |
323 controller().LoadURL(kExistingURL1, GURL(), | |
324 PageTransition::TYPED); | |
325 rvh()->SendNavigate(0, kExistingURL1); | |
326 EXPECT_TRUE(notifications.Check1AndReset( | |
327 NotificationType::NAV_ENTRY_COMMITTED)); | |
328 | |
329 // Make a pending entry to somewhere new. | |
330 const GURL kExistingURL2("http://bee"); | |
331 controller().LoadURL(kExistingURL2, GURL(), | |
332 PageTransition::TYPED); | |
333 EXPECT_EQ(0U, notifications.size()); | |
334 | |
335 // Before that commits, do a new navigation. | |
336 const GURL kNewURL("http://see"); | |
337 rvh()->SendNavigate(3, kNewURL); | |
338 | |
339 // There should no longer be any pending entry, and the third navigation we | |
340 // just made should be committed. | |
341 EXPECT_TRUE(notifications.Check1AndReset( | |
342 NotificationType::NAV_ENTRY_COMMITTED)); | |
343 EXPECT_EQ(-1, controller().pending_entry_index()); | |
344 EXPECT_EQ(1, controller().last_committed_entry_index()); | |
345 EXPECT_EQ(kNewURL, controller().GetActiveEntry()->url()); | |
346 } | |
347 | |
348 // Tests navigating to a new URL when there is a pending back/forward | |
349 // navigation. This will happen if the user hits back, but before that commits, | |
350 // they navigate somewhere new. | |
351 TEST_F(NavigationControllerTest, LoadURL_ExistingPending) { | |
352 TestNotificationTracker notifications; | |
353 RegisterForAllNavNotifications(¬ifications, &controller()); | |
354 | |
355 // First make some history. | |
356 const GURL kExistingURL1("http://eh"); | |
357 controller().LoadURL(kExistingURL1, GURL(), | |
358 PageTransition::TYPED); | |
359 rvh()->SendNavigate(0, kExistingURL1); | |
360 EXPECT_TRUE(notifications.Check1AndReset( | |
361 NotificationType::NAV_ENTRY_COMMITTED)); | |
362 | |
363 const GURL kExistingURL2("http://bee"); | |
364 controller().LoadURL(kExistingURL2, GURL(), | |
365 PageTransition::TYPED); | |
366 rvh()->SendNavigate(1, kExistingURL2); | |
367 EXPECT_TRUE(notifications.Check1AndReset( | |
368 NotificationType::NAV_ENTRY_COMMITTED)); | |
369 | |
370 // Now make a pending back/forward navigation. The zeroth entry should be | |
371 // pending. | |
372 controller().GoBack(); | |
373 EXPECT_EQ(0U, notifications.size()); | |
374 EXPECT_EQ(0, controller().pending_entry_index()); | |
375 EXPECT_EQ(1, controller().last_committed_entry_index()); | |
376 | |
377 // Before that commits, do a new navigation. | |
378 const GURL kNewURL("http://see"); | |
379 NavigationController::LoadCommittedDetails details; | |
380 rvh()->SendNavigate(3, kNewURL); | |
381 | |
382 // There should no longer be any pending entry, and the third navigation we | |
383 // just made should be committed. | |
384 EXPECT_TRUE(notifications.Check1AndReset( | |
385 NotificationType::NAV_ENTRY_COMMITTED)); | |
386 EXPECT_EQ(-1, controller().pending_entry_index()); | |
387 EXPECT_EQ(2, controller().last_committed_entry_index()); | |
388 EXPECT_EQ(kNewURL, controller().GetActiveEntry()->url()); | |
389 } | |
390 | |
391 TEST_F(NavigationControllerTest, Reload) { | |
392 TestNotificationTracker notifications; | |
393 RegisterForAllNavNotifications(¬ifications, &controller()); | |
394 | |
395 const GURL url1("http://foo1"); | |
396 | |
397 controller().LoadURL(url1, GURL(), PageTransition::TYPED); | |
398 EXPECT_EQ(0U, notifications.size()); | |
399 rvh()->SendNavigate(0, url1); | |
400 EXPECT_TRUE(notifications.Check1AndReset( | |
401 NotificationType::NAV_ENTRY_COMMITTED)); | |
402 | |
403 controller().Reload(true); | |
404 EXPECT_EQ(0U, notifications.size()); | |
405 | |
406 // The reload is pending. | |
407 EXPECT_EQ(controller().entry_count(), 1); | |
408 EXPECT_EQ(controller().last_committed_entry_index(), 0); | |
409 EXPECT_EQ(controller().pending_entry_index(), 0); | |
410 EXPECT_TRUE(controller().GetLastCommittedEntry()); | |
411 EXPECT_TRUE(controller().pending_entry()); | |
412 EXPECT_FALSE(controller().CanGoBack()); | |
413 EXPECT_FALSE(controller().CanGoForward()); | |
414 | |
415 rvh()->SendNavigate(0, url1); | |
416 EXPECT_TRUE(notifications.Check1AndReset( | |
417 NotificationType::NAV_ENTRY_COMMITTED)); | |
418 | |
419 // Now the reload is committed. | |
420 EXPECT_EQ(controller().entry_count(), 1); | |
421 EXPECT_EQ(controller().last_committed_entry_index(), 0); | |
422 EXPECT_EQ(controller().pending_entry_index(), -1); | |
423 EXPECT_TRUE(controller().GetLastCommittedEntry()); | |
424 EXPECT_FALSE(controller().pending_entry()); | |
425 EXPECT_FALSE(controller().CanGoBack()); | |
426 EXPECT_FALSE(controller().CanGoForward()); | |
427 } | |
428 | |
429 // Tests what happens when a reload navigation produces a new page. | |
430 TEST_F(NavigationControllerTest, Reload_GeneratesNewPage) { | |
431 TestNotificationTracker notifications; | |
432 RegisterForAllNavNotifications(¬ifications, &controller()); | |
433 | |
434 const GURL url1("http://foo1"); | |
435 const GURL url2("http://foo2"); | |
436 | |
437 controller().LoadURL(url1, GURL(), PageTransition::TYPED); | |
438 rvh()->SendNavigate(0, url1); | |
439 EXPECT_TRUE(notifications.Check1AndReset( | |
440 NotificationType::NAV_ENTRY_COMMITTED)); | |
441 | |
442 controller().Reload(true); | |
443 EXPECT_EQ(0U, notifications.size()); | |
444 | |
445 rvh()->SendNavigate(1, url2); | |
446 EXPECT_TRUE(notifications.Check1AndReset( | |
447 NotificationType::NAV_ENTRY_COMMITTED)); | |
448 | |
449 // Now the reload is committed. | |
450 EXPECT_EQ(controller().entry_count(), 2); | |
451 EXPECT_EQ(controller().last_committed_entry_index(), 1); | |
452 EXPECT_EQ(controller().pending_entry_index(), -1); | |
453 EXPECT_TRUE(controller().GetLastCommittedEntry()); | |
454 EXPECT_FALSE(controller().pending_entry()); | |
455 EXPECT_TRUE(controller().CanGoBack()); | |
456 EXPECT_FALSE(controller().CanGoForward()); | |
457 } | |
458 | |
459 // Tests what happens when we navigate back successfully | |
460 TEST_F(NavigationControllerTest, Back) { | |
461 TestNotificationTracker notifications; | |
462 RegisterForAllNavNotifications(¬ifications, &controller()); | |
463 | |
464 const GURL url1("http://foo1"); | |
465 rvh()->SendNavigate(0, url1); | |
466 EXPECT_TRUE(notifications.Check1AndReset( | |
467 NotificationType::NAV_ENTRY_COMMITTED)); | |
468 | |
469 const GURL url2("http://foo2"); | |
470 rvh()->SendNavigate(1, url2); | |
471 EXPECT_TRUE(notifications.Check1AndReset( | |
472 NotificationType::NAV_ENTRY_COMMITTED)); | |
473 | |
474 controller().GoBack(); | |
475 EXPECT_EQ(0U, notifications.size()); | |
476 | |
477 // We should now have a pending navigation to go back. | |
478 EXPECT_EQ(controller().entry_count(), 2); | |
479 EXPECT_EQ(controller().last_committed_entry_index(), 1); | |
480 EXPECT_EQ(controller().pending_entry_index(), 0); | |
481 EXPECT_TRUE(controller().GetLastCommittedEntry()); | |
482 EXPECT_TRUE(controller().pending_entry()); | |
483 EXPECT_FALSE(controller().CanGoBack()); | |
484 EXPECT_TRUE(controller().CanGoForward()); | |
485 | |
486 rvh()->SendNavigate(0, url2); | |
487 EXPECT_TRUE(notifications.Check1AndReset( | |
488 NotificationType::NAV_ENTRY_COMMITTED)); | |
489 | |
490 // The back navigation completed successfully. | |
491 EXPECT_EQ(controller().entry_count(), 2); | |
492 EXPECT_EQ(controller().last_committed_entry_index(), 0); | |
493 EXPECT_EQ(controller().pending_entry_index(), -1); | |
494 EXPECT_TRUE(controller().GetLastCommittedEntry()); | |
495 EXPECT_FALSE(controller().pending_entry()); | |
496 EXPECT_FALSE(controller().CanGoBack()); | |
497 EXPECT_TRUE(controller().CanGoForward()); | |
498 } | |
499 | |
500 // Tests what happens when a back navigation produces a new page. | |
501 TEST_F(NavigationControllerTest, Back_GeneratesNewPage) { | |
502 TestNotificationTracker notifications; | |
503 RegisterForAllNavNotifications(¬ifications, &controller()); | |
504 | |
505 const GURL url1("http://foo1"); | |
506 const GURL url2("http://foo2"); | |
507 const GURL url3("http://foo3"); | |
508 | |
509 controller().LoadURL(url1, GURL(), PageTransition::TYPED); | |
510 rvh()->SendNavigate(0, url1); | |
511 EXPECT_TRUE(notifications.Check1AndReset( | |
512 NotificationType::NAV_ENTRY_COMMITTED)); | |
513 | |
514 controller().LoadURL(url2, GURL(), PageTransition::TYPED); | |
515 rvh()->SendNavigate(1, url2); | |
516 EXPECT_TRUE(notifications.Check1AndReset( | |
517 NotificationType::NAV_ENTRY_COMMITTED)); | |
518 | |
519 controller().GoBack(); | |
520 EXPECT_EQ(0U, notifications.size()); | |
521 | |
522 // We should now have a pending navigation to go back. | |
523 EXPECT_EQ(controller().entry_count(), 2); | |
524 EXPECT_EQ(controller().last_committed_entry_index(), 1); | |
525 EXPECT_EQ(controller().pending_entry_index(), 0); | |
526 EXPECT_TRUE(controller().GetLastCommittedEntry()); | |
527 EXPECT_TRUE(controller().pending_entry()); | |
528 EXPECT_FALSE(controller().CanGoBack()); | |
529 EXPECT_TRUE(controller().CanGoForward()); | |
530 | |
531 rvh()->SendNavigate(2, url3); | |
532 EXPECT_TRUE(notifications.Check1AndReset( | |
533 NotificationType::NAV_ENTRY_COMMITTED)); | |
534 | |
535 // The back navigation resulted in a completely new navigation. | |
536 // TODO(darin): perhaps this behavior will be confusing to users? | |
537 EXPECT_EQ(controller().entry_count(), 3); | |
538 EXPECT_EQ(controller().last_committed_entry_index(), 2); | |
539 EXPECT_EQ(controller().pending_entry_index(), -1); | |
540 EXPECT_TRUE(controller().GetLastCommittedEntry()); | |
541 EXPECT_FALSE(controller().pending_entry()); | |
542 EXPECT_TRUE(controller().CanGoBack()); | |
543 EXPECT_FALSE(controller().CanGoForward()); | |
544 } | |
545 | |
546 // Receives a back message when there is a new pending navigation entry. | |
547 TEST_F(NavigationControllerTest, Back_NewPending) { | |
548 TestNotificationTracker notifications; | |
549 RegisterForAllNavNotifications(¬ifications, &controller()); | |
550 | |
551 const GURL kUrl1("http://foo1"); | |
552 const GURL kUrl2("http://foo2"); | |
553 const GURL kUrl3("http://foo3"); | |
554 | |
555 // First navigate two places so we have some back history. | |
556 rvh()->SendNavigate(0, kUrl1); | |
557 EXPECT_TRUE(notifications.Check1AndReset( | |
558 NotificationType::NAV_ENTRY_COMMITTED)); | |
559 | |
560 // controller().LoadURL(kUrl2, PageTransition::TYPED); | |
561 rvh()->SendNavigate(1, kUrl2); | |
562 EXPECT_TRUE(notifications.Check1AndReset( | |
563 NotificationType::NAV_ENTRY_COMMITTED)); | |
564 | |
565 // Now start a new pending navigation and go back before it commits. | |
566 controller().LoadURL(kUrl3, GURL(), PageTransition::TYPED); | |
567 EXPECT_EQ(-1, controller().pending_entry_index()); | |
568 EXPECT_EQ(kUrl3, controller().pending_entry()->url()); | |
569 controller().GoBack(); | |
570 | |
571 // The pending navigation should now be the "back" item and the new one | |
572 // should be gone. | |
573 EXPECT_EQ(0, controller().pending_entry_index()); | |
574 EXPECT_EQ(kUrl1, controller().pending_entry()->url()); | |
575 } | |
576 | |
577 // Receives a back message when there is a different renavigation already | |
578 // pending. | |
579 TEST_F(NavigationControllerTest, Back_OtherBackPending) { | |
580 const GURL kUrl1("http://foo/1"); | |
581 const GURL kUrl2("http://foo/2"); | |
582 const GURL kUrl3("http://foo/3"); | |
583 | |
584 // First navigate three places so we have some back history. | |
585 rvh()->SendNavigate(0, kUrl1); | |
586 rvh()->SendNavigate(1, kUrl2); | |
587 rvh()->SendNavigate(2, kUrl3); | |
588 | |
589 // With nothing pending, say we get a navigation to the second entry. | |
590 rvh()->SendNavigate(1, kUrl2); | |
591 | |
592 // We know all the entries have the same site instance, so we can just grab | |
593 // a random one for looking up other entries. | |
594 SiteInstance* site_instance = | |
595 controller().GetLastCommittedEntry()->site_instance(); | |
596 | |
597 // That second URL should be the last committed and it should have gotten the | |
598 // new title. | |
599 EXPECT_EQ(kUrl2, controller().GetEntryWithPageID(site_instance, 1)->url()); | |
600 EXPECT_EQ(1, controller().last_committed_entry_index()); | |
601 EXPECT_EQ(-1, controller().pending_entry_index()); | |
602 | |
603 // Now go forward to the last item again and say it was committed. | |
604 controller().GoForward(); | |
605 rvh()->SendNavigate(2, kUrl3); | |
606 | |
607 // Now start going back one to the second page. It will be pending. | |
608 controller().GoBack(); | |
609 EXPECT_EQ(1, controller().pending_entry_index()); | |
610 EXPECT_EQ(2, controller().last_committed_entry_index()); | |
611 | |
612 // Not synthesize a totally new back event to the first page. This will not | |
613 // match the pending one. | |
614 rvh()->SendNavigate(0, kUrl1); | |
615 | |
616 // The navigation should not have affected the pending entry. | |
617 EXPECT_EQ(1, controller().pending_entry_index()); | |
618 | |
619 // But the navigated entry should be the last committed. | |
620 EXPECT_EQ(0, controller().last_committed_entry_index()); | |
621 EXPECT_EQ(kUrl1, controller().GetLastCommittedEntry()->url()); | |
622 } | |
623 | |
624 // Tests what happens when we navigate forward successfully. | |
625 TEST_F(NavigationControllerTest, Forward) { | |
626 TestNotificationTracker notifications; | |
627 RegisterForAllNavNotifications(¬ifications, &controller()); | |
628 | |
629 const GURL url1("http://foo1"); | |
630 const GURL url2("http://foo2"); | |
631 | |
632 rvh()->SendNavigate(0, url1); | |
633 EXPECT_TRUE(notifications.Check1AndReset( | |
634 NotificationType::NAV_ENTRY_COMMITTED)); | |
635 | |
636 rvh()->SendNavigate(1, url2); | |
637 EXPECT_TRUE(notifications.Check1AndReset( | |
638 NotificationType::NAV_ENTRY_COMMITTED)); | |
639 | |
640 controller().GoBack(); | |
641 rvh()->SendNavigate(0, url1); | |
642 EXPECT_TRUE(notifications.Check1AndReset( | |
643 NotificationType::NAV_ENTRY_COMMITTED)); | |
644 | |
645 controller().GoForward(); | |
646 | |
647 // We should now have a pending navigation to go forward. | |
648 EXPECT_EQ(controller().entry_count(), 2); | |
649 EXPECT_EQ(controller().last_committed_entry_index(), 0); | |
650 EXPECT_EQ(controller().pending_entry_index(), 1); | |
651 EXPECT_TRUE(controller().GetLastCommittedEntry()); | |
652 EXPECT_TRUE(controller().pending_entry()); | |
653 EXPECT_TRUE(controller().CanGoBack()); | |
654 EXPECT_FALSE(controller().CanGoForward()); | |
655 | |
656 rvh()->SendNavigate(1, url2); | |
657 EXPECT_TRUE(notifications.Check1AndReset( | |
658 NotificationType::NAV_ENTRY_COMMITTED)); | |
659 | |
660 // The forward navigation completed successfully. | |
661 EXPECT_EQ(controller().entry_count(), 2); | |
662 EXPECT_EQ(controller().last_committed_entry_index(), 1); | |
663 EXPECT_EQ(controller().pending_entry_index(), -1); | |
664 EXPECT_TRUE(controller().GetLastCommittedEntry()); | |
665 EXPECT_FALSE(controller().pending_entry()); | |
666 EXPECT_TRUE(controller().CanGoBack()); | |
667 EXPECT_FALSE(controller().CanGoForward()); | |
668 } | |
669 | |
670 // Tests what happens when a forward navigation produces a new page. | |
671 TEST_F(NavigationControllerTest, Forward_GeneratesNewPage) { | |
672 TestNotificationTracker notifications; | |
673 RegisterForAllNavNotifications(¬ifications, &controller()); | |
674 | |
675 const GURL url1("http://foo1"); | |
676 const GURL url2("http://foo2"); | |
677 const GURL url3("http://foo3"); | |
678 | |
679 rvh()->SendNavigate(0, url1); | |
680 EXPECT_TRUE(notifications.Check1AndReset( | |
681 NotificationType::NAV_ENTRY_COMMITTED)); | |
682 rvh()->SendNavigate(1, url2); | |
683 EXPECT_TRUE(notifications.Check1AndReset( | |
684 NotificationType::NAV_ENTRY_COMMITTED)); | |
685 | |
686 controller().GoBack(); | |
687 rvh()->SendNavigate(0, url1); | |
688 EXPECT_TRUE(notifications.Check1AndReset( | |
689 NotificationType::NAV_ENTRY_COMMITTED)); | |
690 | |
691 controller().GoForward(); | |
692 EXPECT_EQ(0U, notifications.size()); | |
693 | |
694 // Should now have a pending navigation to go forward. | |
695 EXPECT_EQ(controller().entry_count(), 2); | |
696 EXPECT_EQ(controller().last_committed_entry_index(), 0); | |
697 EXPECT_EQ(controller().pending_entry_index(), 1); | |
698 EXPECT_TRUE(controller().GetLastCommittedEntry()); | |
699 EXPECT_TRUE(controller().pending_entry()); | |
700 EXPECT_TRUE(controller().CanGoBack()); | |
701 EXPECT_FALSE(controller().CanGoForward()); | |
702 | |
703 rvh()->SendNavigate(2, url3); | |
704 EXPECT_TRUE(notifications.Check2AndReset( | |
705 NotificationType::NAV_LIST_PRUNED, | |
706 NotificationType::NAV_ENTRY_COMMITTED)); | |
707 | |
708 EXPECT_EQ(controller().entry_count(), 2); | |
709 EXPECT_EQ(controller().last_committed_entry_index(), 1); | |
710 EXPECT_EQ(controller().pending_entry_index(), -1); | |
711 EXPECT_TRUE(controller().GetLastCommittedEntry()); | |
712 EXPECT_FALSE(controller().pending_entry()); | |
713 EXPECT_TRUE(controller().CanGoBack()); | |
714 EXPECT_FALSE(controller().CanGoForward()); | |
715 } | |
716 | |
717 // Two consequent navigation for the same URL entered in should be considered | |
718 // as SAME_PAGE navigation even when we are redirected to some other page. | |
719 TEST_F(NavigationControllerTest, Redirect) { | |
720 TestNotificationTracker notifications; | |
721 RegisterForAllNavNotifications(¬ifications, &controller()); | |
722 | |
723 const GURL url1("http://foo1"); | |
724 const GURL url2("http://foo2"); // Redirection target | |
725 | |
726 // First request | |
727 controller().LoadURL(url1, GURL(), PageTransition::TYPED); | |
728 | |
729 EXPECT_EQ(0U, notifications.size()); | |
730 rvh()->SendNavigate(0, url2); | |
731 EXPECT_TRUE(notifications.Check1AndReset( | |
732 NotificationType::NAV_ENTRY_COMMITTED)); | |
733 | |
734 // Second request | |
735 controller().LoadURL(url1, GURL(), PageTransition::TYPED); | |
736 | |
737 EXPECT_TRUE(controller().pending_entry()); | |
738 EXPECT_EQ(controller().pending_entry_index(), -1); | |
739 EXPECT_EQ(url1, controller().GetActiveEntry()->url()); | |
740 | |
741 ViewHostMsg_FrameNavigate_Params params; | |
742 params.page_id = 0; | |
743 params.url = url2; | |
744 params.transition = PageTransition::SERVER_REDIRECT; | |
745 params.redirects.push_back(GURL("http://foo1")); | |
746 params.redirects.push_back(GURL("http://foo2")); | |
747 params.should_update_history = false; | |
748 params.gesture = NavigationGestureAuto; | |
749 params.is_post = false; | |
750 | |
751 NavigationController::LoadCommittedDetails details; | |
752 | |
753 EXPECT_EQ(0U, notifications.size()); | |
754 EXPECT_TRUE(controller().RendererDidNavigate(params, 0, &details)); | |
755 EXPECT_TRUE(notifications.Check1AndReset( | |
756 NotificationType::NAV_ENTRY_COMMITTED)); | |
757 | |
758 EXPECT_TRUE(details.type == NavigationType::SAME_PAGE); | |
759 EXPECT_EQ(controller().entry_count(), 1); | |
760 EXPECT_EQ(controller().last_committed_entry_index(), 0); | |
761 EXPECT_TRUE(controller().GetLastCommittedEntry()); | |
762 EXPECT_EQ(controller().pending_entry_index(), -1); | |
763 EXPECT_FALSE(controller().pending_entry()); | |
764 EXPECT_EQ(url2, controller().GetActiveEntry()->url()); | |
765 | |
766 EXPECT_FALSE(controller().CanGoBack()); | |
767 EXPECT_FALSE(controller().CanGoForward()); | |
768 } | |
769 | |
770 // Similar to Redirect above, but the first URL is requested by POST, | |
771 // the second URL is requested by GET. NavigationEntry::has_post_data_ | |
772 // must be cleared. http://crbug.com/21245 | |
773 TEST_F(NavigationControllerTest, PostThenRedirect) { | |
774 TestNotificationTracker notifications; | |
775 RegisterForAllNavNotifications(¬ifications, &controller()); | |
776 | |
777 const GURL url1("http://foo1"); | |
778 const GURL url2("http://foo2"); // Redirection target | |
779 | |
780 // First request as POST | |
781 controller().LoadURL(url1, GURL(), PageTransition::TYPED); | |
782 controller().GetActiveEntry()->set_has_post_data(true); | |
783 | |
784 EXPECT_EQ(0U, notifications.size()); | |
785 rvh()->SendNavigate(0, url2); | |
786 EXPECT_TRUE(notifications.Check1AndReset( | |
787 NotificationType::NAV_ENTRY_COMMITTED)); | |
788 | |
789 // Second request | |
790 controller().LoadURL(url1, GURL(), PageTransition::TYPED); | |
791 | |
792 EXPECT_TRUE(controller().pending_entry()); | |
793 EXPECT_EQ(controller().pending_entry_index(), -1); | |
794 EXPECT_EQ(url1, controller().GetActiveEntry()->url()); | |
795 | |
796 ViewHostMsg_FrameNavigate_Params params; | |
797 params.page_id = 0; | |
798 params.url = url2; | |
799 params.transition = PageTransition::SERVER_REDIRECT; | |
800 params.redirects.push_back(GURL("http://foo1")); | |
801 params.redirects.push_back(GURL("http://foo2")); | |
802 params.should_update_history = false; | |
803 params.gesture = NavigationGestureAuto; | |
804 params.is_post = false; | |
805 | |
806 NavigationController::LoadCommittedDetails details; | |
807 | |
808 EXPECT_EQ(0U, notifications.size()); | |
809 EXPECT_TRUE(controller().RendererDidNavigate(params, 0, &details)); | |
810 EXPECT_TRUE(notifications.Check1AndReset( | |
811 NotificationType::NAV_ENTRY_COMMITTED)); | |
812 | |
813 EXPECT_TRUE(details.type == NavigationType::SAME_PAGE); | |
814 EXPECT_EQ(controller().entry_count(), 1); | |
815 EXPECT_EQ(controller().last_committed_entry_index(), 0); | |
816 EXPECT_TRUE(controller().GetLastCommittedEntry()); | |
817 EXPECT_EQ(controller().pending_entry_index(), -1); | |
818 EXPECT_FALSE(controller().pending_entry()); | |
819 EXPECT_EQ(url2, controller().GetActiveEntry()->url()); | |
820 EXPECT_FALSE(controller().GetActiveEntry()->has_post_data()); | |
821 | |
822 EXPECT_FALSE(controller().CanGoBack()); | |
823 EXPECT_FALSE(controller().CanGoForward()); | |
824 } | |
825 | |
826 // A redirect right off the bat should be a NEW_PAGE. | |
827 TEST_F(NavigationControllerTest, ImmediateRedirect) { | |
828 TestNotificationTracker notifications; | |
829 RegisterForAllNavNotifications(¬ifications, &controller()); | |
830 | |
831 const GURL url1("http://foo1"); | |
832 const GURL url2("http://foo2"); // Redirection target | |
833 | |
834 // First request | |
835 controller().LoadURL(url1, GURL(), PageTransition::TYPED); | |
836 | |
837 EXPECT_TRUE(controller().pending_entry()); | |
838 EXPECT_EQ(controller().pending_entry_index(), -1); | |
839 EXPECT_EQ(url1, controller().GetActiveEntry()->url()); | |
840 | |
841 ViewHostMsg_FrameNavigate_Params params; | |
842 params.page_id = 0; | |
843 params.url = url2; | |
844 params.transition = PageTransition::SERVER_REDIRECT; | |
845 params.redirects.push_back(GURL("http://foo1")); | |
846 params.redirects.push_back(GURL("http://foo2")); | |
847 params.should_update_history = false; | |
848 params.gesture = NavigationGestureAuto; | |
849 params.is_post = false; | |
850 | |
851 NavigationController::LoadCommittedDetails details; | |
852 | |
853 EXPECT_EQ(0U, notifications.size()); | |
854 EXPECT_TRUE(controller().RendererDidNavigate(params, 0, &details)); | |
855 EXPECT_TRUE(notifications.Check1AndReset( | |
856 NotificationType::NAV_ENTRY_COMMITTED)); | |
857 | |
858 EXPECT_TRUE(details.type == NavigationType::NEW_PAGE); | |
859 EXPECT_EQ(controller().entry_count(), 1); | |
860 EXPECT_EQ(controller().last_committed_entry_index(), 0); | |
861 EXPECT_TRUE(controller().GetLastCommittedEntry()); | |
862 EXPECT_EQ(controller().pending_entry_index(), -1); | |
863 EXPECT_FALSE(controller().pending_entry()); | |
864 EXPECT_EQ(url2, controller().GetActiveEntry()->url()); | |
865 | |
866 EXPECT_FALSE(controller().CanGoBack()); | |
867 EXPECT_FALSE(controller().CanGoForward()); | |
868 } | |
869 | |
870 // Tests navigation via link click within a subframe. A new navigation entry | |
871 // should be created. | |
872 TEST_F(NavigationControllerTest, NewSubframe) { | |
873 TestNotificationTracker notifications; | |
874 RegisterForAllNavNotifications(¬ifications, &controller()); | |
875 | |
876 const GURL url1("http://foo1"); | |
877 rvh()->SendNavigate(0, url1); | |
878 EXPECT_TRUE(notifications.Check1AndReset( | |
879 NotificationType::NAV_ENTRY_COMMITTED)); | |
880 | |
881 const GURL url2("http://foo2"); | |
882 ViewHostMsg_FrameNavigate_Params params; | |
883 params.page_id = 1; | |
884 params.url = url2; | |
885 params.transition = PageTransition::MANUAL_SUBFRAME; | |
886 params.should_update_history = false; | |
887 params.gesture = NavigationGestureUser; | |
888 params.is_post = false; | |
889 | |
890 NavigationController::LoadCommittedDetails details; | |
891 EXPECT_TRUE(controller().RendererDidNavigate(params, 0, &details)); | |
892 EXPECT_TRUE(notifications.Check1AndReset( | |
893 NotificationType::NAV_ENTRY_COMMITTED)); | |
894 EXPECT_EQ(url1, details.previous_url); | |
895 EXPECT_FALSE(details.is_auto); | |
896 EXPECT_FALSE(details.is_in_page); | |
897 EXPECT_FALSE(details.is_main_frame); | |
898 | |
899 // The new entry should be appended. | |
900 EXPECT_EQ(2, controller().entry_count()); | |
901 | |
902 // New entry should refer to the new page, but the old URL (entries only | |
903 // reflect the toplevel URL). | |
904 EXPECT_EQ(url1, details.entry->url()); | |
905 EXPECT_EQ(params.page_id, details.entry->page_id()); | |
906 } | |
907 | |
908 // Some pages create a popup, then write an iframe into it. This causes a | |
909 // subframe navigation without having any committed entry. Such navigations | |
910 // just get thrown on the ground, but we shouldn't crash. | |
911 TEST_F(NavigationControllerTest, SubframeOnEmptyPage) { | |
912 TestNotificationTracker notifications; | |
913 RegisterForAllNavNotifications(¬ifications, &controller()); | |
914 | |
915 // Navigation controller currently has no entries. | |
916 const GURL url("http://foo2"); | |
917 ViewHostMsg_FrameNavigate_Params params; | |
918 params.page_id = 1; | |
919 params.url = url; | |
920 params.transition = PageTransition::AUTO_SUBFRAME; | |
921 params.should_update_history = false; | |
922 params.gesture = NavigationGestureAuto; | |
923 params.is_post = false; | |
924 | |
925 NavigationController::LoadCommittedDetails details; | |
926 EXPECT_FALSE(controller().RendererDidNavigate(params, 0, &details)); | |
927 EXPECT_EQ(0U, notifications.size()); | |
928 } | |
929 | |
930 // Auto subframes are ones the page loads automatically like ads. They should | |
931 // not create new navigation entries. | |
932 TEST_F(NavigationControllerTest, AutoSubframe) { | |
933 TestNotificationTracker notifications; | |
934 RegisterForAllNavNotifications(¬ifications, &controller()); | |
935 | |
936 const GURL url1("http://foo1"); | |
937 rvh()->SendNavigate(0, url1); | |
938 EXPECT_TRUE(notifications.Check1AndReset( | |
939 NotificationType::NAV_ENTRY_COMMITTED)); | |
940 | |
941 const GURL url2("http://foo2"); | |
942 ViewHostMsg_FrameNavigate_Params params; | |
943 params.page_id = 0; | |
944 params.url = url2; | |
945 params.transition = PageTransition::AUTO_SUBFRAME; | |
946 params.should_update_history = false; | |
947 params.gesture = NavigationGestureUser; | |
948 params.is_post = false; | |
949 | |
950 // Navigating should do nothing. | |
951 NavigationController::LoadCommittedDetails details; | |
952 EXPECT_FALSE(controller().RendererDidNavigate(params, 0, &details)); | |
953 EXPECT_EQ(0U, notifications.size()); | |
954 | |
955 // There should still be only one entry. | |
956 EXPECT_EQ(1, controller().entry_count()); | |
957 } | |
958 | |
959 // Tests navigation and then going back to a subframe navigation. | |
960 TEST_F(NavigationControllerTest, BackSubframe) { | |
961 TestNotificationTracker notifications; | |
962 RegisterForAllNavNotifications(¬ifications, &controller()); | |
963 | |
964 // Main page. | |
965 const GURL url1("http://foo1"); | |
966 rvh()->SendNavigate(0, url1); | |
967 EXPECT_TRUE(notifications.Check1AndReset( | |
968 NotificationType::NAV_ENTRY_COMMITTED)); | |
969 | |
970 // First manual subframe navigation. | |
971 const GURL url2("http://foo2"); | |
972 ViewHostMsg_FrameNavigate_Params params; | |
973 params.page_id = 1; | |
974 params.url = url2; | |
975 params.transition = PageTransition::MANUAL_SUBFRAME; | |
976 params.should_update_history = false; | |
977 params.gesture = NavigationGestureUser; | |
978 params.is_post = false; | |
979 | |
980 // This should generate a new entry. | |
981 NavigationController::LoadCommittedDetails details; | |
982 EXPECT_TRUE(controller().RendererDidNavigate(params, 0, &details)); | |
983 EXPECT_TRUE(notifications.Check1AndReset( | |
984 NotificationType::NAV_ENTRY_COMMITTED)); | |
985 EXPECT_EQ(2, controller().entry_count()); | |
986 | |
987 // Second manual subframe navigation should also make a new entry. | |
988 const GURL url3("http://foo3"); | |
989 params.page_id = 2; | |
990 params.url = url3; | |
991 EXPECT_TRUE(controller().RendererDidNavigate(params, 0, &details)); | |
992 EXPECT_TRUE(notifications.Check1AndReset( | |
993 NotificationType::NAV_ENTRY_COMMITTED)); | |
994 EXPECT_EQ(3, controller().entry_count()); | |
995 EXPECT_EQ(2, controller().GetCurrentEntryIndex()); | |
996 | |
997 // Go back one. | |
998 controller().GoBack(); | |
999 params.url = url2; | |
1000 params.page_id = 1; | |
1001 EXPECT_TRUE(controller().RendererDidNavigate(params, 0, &details)); | |
1002 EXPECT_TRUE(notifications.Check1AndReset( | |
1003 NotificationType::NAV_ENTRY_COMMITTED)); | |
1004 EXPECT_EQ(3, controller().entry_count()); | |
1005 EXPECT_EQ(1, controller().GetCurrentEntryIndex()); | |
1006 | |
1007 // Go back one more. | |
1008 controller().GoBack(); | |
1009 params.url = url1; | |
1010 params.page_id = 0; | |
1011 EXPECT_TRUE(controller().RendererDidNavigate(params, 0, &details)); | |
1012 EXPECT_TRUE(notifications.Check1AndReset( | |
1013 NotificationType::NAV_ENTRY_COMMITTED)); | |
1014 EXPECT_EQ(3, controller().entry_count()); | |
1015 EXPECT_EQ(0, controller().GetCurrentEntryIndex()); | |
1016 } | |
1017 | |
1018 TEST_F(NavigationControllerTest, LinkClick) { | |
1019 TestNotificationTracker notifications; | |
1020 RegisterForAllNavNotifications(¬ifications, &controller()); | |
1021 | |
1022 const GURL url1("http://foo1"); | |
1023 const GURL url2("http://foo2"); | |
1024 | |
1025 rvh()->SendNavigate(0, url1); | |
1026 EXPECT_TRUE(notifications.Check1AndReset( | |
1027 NotificationType::NAV_ENTRY_COMMITTED)); | |
1028 | |
1029 rvh()->SendNavigate(1, url2); | |
1030 EXPECT_TRUE(notifications.Check1AndReset( | |
1031 NotificationType::NAV_ENTRY_COMMITTED)); | |
1032 | |
1033 // Should not have produced a new session history entry. | |
1034 EXPECT_EQ(controller().entry_count(), 2); | |
1035 EXPECT_EQ(controller().last_committed_entry_index(), 1); | |
1036 EXPECT_EQ(controller().pending_entry_index(), -1); | |
1037 EXPECT_TRUE(controller().GetLastCommittedEntry()); | |
1038 EXPECT_FALSE(controller().pending_entry()); | |
1039 EXPECT_TRUE(controller().CanGoBack()); | |
1040 EXPECT_FALSE(controller().CanGoForward()); | |
1041 } | |
1042 | |
1043 TEST_F(NavigationControllerTest, InPage) { | |
1044 TestNotificationTracker notifications; | |
1045 RegisterForAllNavNotifications(¬ifications, &controller()); | |
1046 | |
1047 // Main page. | |
1048 const GURL url1("http://foo"); | |
1049 rvh()->SendNavigate(0, url1); | |
1050 EXPECT_TRUE(notifications.Check1AndReset( | |
1051 NotificationType::NAV_ENTRY_COMMITTED)); | |
1052 | |
1053 // First navigation. | |
1054 const GURL url2("http://foo#a"); | |
1055 ViewHostMsg_FrameNavigate_Params params; | |
1056 params.page_id = 1; | |
1057 params.url = url2; | |
1058 params.transition = PageTransition::LINK; | |
1059 params.should_update_history = false; | |
1060 params.gesture = NavigationGestureUser; | |
1061 params.is_post = false; | |
1062 | |
1063 // This should generate a new entry. | |
1064 NavigationController::LoadCommittedDetails details; | |
1065 EXPECT_TRUE(controller().RendererDidNavigate(params, 0, &details)); | |
1066 EXPECT_TRUE(notifications.Check1AndReset( | |
1067 NotificationType::NAV_ENTRY_COMMITTED)); | |
1068 EXPECT_TRUE(details.is_in_page); | |
1069 EXPECT_FALSE(details.did_replace_entry); | |
1070 EXPECT_EQ(2, controller().entry_count()); | |
1071 | |
1072 // Go back one. | |
1073 ViewHostMsg_FrameNavigate_Params back_params(params); | |
1074 controller().GoBack(); | |
1075 back_params.url = url1; | |
1076 back_params.page_id = 0; | |
1077 EXPECT_TRUE(controller().RendererDidNavigate(back_params, 0, &details)); | |
1078 EXPECT_TRUE(notifications.Check1AndReset( | |
1079 NotificationType::NAV_ENTRY_COMMITTED)); | |
1080 // is_in_page is false in that case but should be true. | |
1081 // See comment in AreURLsInPageNavigation() in navigation_controller.cc | |
1082 // EXPECT_TRUE(details.is_in_page); | |
1083 EXPECT_EQ(2, controller().entry_count()); | |
1084 EXPECT_EQ(0, controller().GetCurrentEntryIndex()); | |
1085 EXPECT_EQ(back_params.url, controller().GetActiveEntry()->url()); | |
1086 | |
1087 // Go forward | |
1088 ViewHostMsg_FrameNavigate_Params forward_params(params); | |
1089 controller().GoForward(); | |
1090 forward_params.url = url2; | |
1091 forward_params.page_id = 1; | |
1092 EXPECT_TRUE(controller().RendererDidNavigate(forward_params, 0, &details)); | |
1093 EXPECT_TRUE(notifications.Check1AndReset( | |
1094 NotificationType::NAV_ENTRY_COMMITTED)); | |
1095 EXPECT_TRUE(details.is_in_page); | |
1096 EXPECT_EQ(2, controller().entry_count()); | |
1097 EXPECT_EQ(1, controller().GetCurrentEntryIndex()); | |
1098 EXPECT_EQ(forward_params.url, | |
1099 controller().GetActiveEntry()->url()); | |
1100 | |
1101 // Now go back and forward again. This is to work around a bug where we would | |
1102 // compare the incoming URL with the last committed entry rather than the | |
1103 // one identified by an existing page ID. This would result in the second URL | |
1104 // losing the reference fragment when you navigate away from it and then back. | |
1105 controller().GoBack(); | |
1106 EXPECT_TRUE(controller().RendererDidNavigate(back_params, 0, &details)); | |
1107 controller().GoForward(); | |
1108 EXPECT_TRUE(controller().RendererDidNavigate(forward_params, 0, &details)); | |
1109 EXPECT_EQ(forward_params.url, | |
1110 controller().GetActiveEntry()->url()); | |
1111 | |
1112 // Finally, navigate to an unrelated URL to make sure in_page is not sticky. | |
1113 const GURL url3("http://bar"); | |
1114 params.page_id = 2; | |
1115 params.url = url3; | |
1116 notifications.Reset(); | |
1117 EXPECT_TRUE(controller().RendererDidNavigate(params, 0, &details)); | |
1118 EXPECT_TRUE(notifications.Check1AndReset( | |
1119 NotificationType::NAV_ENTRY_COMMITTED)); | |
1120 EXPECT_FALSE(details.is_in_page); | |
1121 } | |
1122 | |
1123 TEST_F(NavigationControllerTest, InPage_Replace) { | |
1124 TestNotificationTracker notifications; | |
1125 RegisterForAllNavNotifications(¬ifications, &controller()); | |
1126 | |
1127 // Main page. | |
1128 const GURL url1("http://foo"); | |
1129 rvh()->SendNavigate(0, url1); | |
1130 EXPECT_TRUE(notifications.Check1AndReset( | |
1131 NotificationType::NAV_ENTRY_COMMITTED)); | |
1132 | |
1133 // First navigation. | |
1134 const GURL url2("http://foo#a"); | |
1135 ViewHostMsg_FrameNavigate_Params params; | |
1136 params.page_id = 0; // Same page_id | |
1137 params.url = url2; | |
1138 params.transition = PageTransition::LINK; | |
1139 params.should_update_history = false; | |
1140 params.gesture = NavigationGestureUser; | |
1141 params.is_post = false; | |
1142 | |
1143 // This should NOT generate a new entry. | |
1144 NavigationController::LoadCommittedDetails details; | |
1145 EXPECT_TRUE(controller().RendererDidNavigate(params, 0, &details)); | |
1146 EXPECT_TRUE(notifications.Check2AndReset( | |
1147 NotificationType::NAV_LIST_PRUNED, | |
1148 NotificationType::NAV_ENTRY_COMMITTED)); | |
1149 EXPECT_TRUE(details.is_in_page); | |
1150 EXPECT_TRUE(details.did_replace_entry); | |
1151 EXPECT_EQ(1, controller().entry_count()); | |
1152 } | |
1153 | |
1154 // Tests for http://crbug.com/40395 | |
1155 // Simulates this: | |
1156 // <script> | |
1157 // window.location.replace("#a"); | |
1158 // window.location='http://foo3/'; | |
1159 // </script> | |
1160 TEST_F(NavigationControllerTest, ClientRedirectAfterInPageNavigation) { | |
1161 TestNotificationTracker notifications; | |
1162 RegisterForAllNavNotifications(¬ifications, &controller()); | |
1163 | |
1164 // Load an initial page. | |
1165 { | |
1166 const GURL url("http://foo/"); | |
1167 rvh()->SendNavigate(0, url); | |
1168 EXPECT_TRUE(notifications.Check1AndReset( | |
1169 NotificationType::NAV_ENTRY_COMMITTED)); | |
1170 } | |
1171 | |
1172 // Navigate to a new page. | |
1173 { | |
1174 const GURL url("http://foo2/"); | |
1175 rvh()->SendNavigate(1, url); | |
1176 controller().DocumentLoadedInFrame(); | |
1177 EXPECT_TRUE(notifications.Check1AndReset( | |
1178 NotificationType::NAV_ENTRY_COMMITTED)); | |
1179 } | |
1180 | |
1181 // Navigate within the page. | |
1182 { | |
1183 const GURL url("http://foo2/#a"); | |
1184 ViewHostMsg_FrameNavigate_Params params; | |
1185 params.page_id = 1; // Same page_id | |
1186 params.url = url; | |
1187 params.transition = PageTransition::LINK; | |
1188 params.redirects.push_back(url); | |
1189 params.should_update_history = true; | |
1190 params.gesture = NavigationGestureUnknown; | |
1191 params.is_post = false; | |
1192 | |
1193 // This should NOT generate a new entry. | |
1194 NavigationController::LoadCommittedDetails details; | |
1195 EXPECT_TRUE(controller().RendererDidNavigate(params, 0, &details)); | |
1196 EXPECT_TRUE(notifications.Check2AndReset( | |
1197 NotificationType::NAV_LIST_PRUNED, | |
1198 NotificationType::NAV_ENTRY_COMMITTED)); | |
1199 EXPECT_TRUE(details.is_in_page); | |
1200 EXPECT_TRUE(details.did_replace_entry); | |
1201 EXPECT_EQ(2, controller().entry_count()); | |
1202 } | |
1203 | |
1204 // Perform a client redirect to a new page. | |
1205 { | |
1206 const GURL url("http://foo3/"); | |
1207 ViewHostMsg_FrameNavigate_Params params; | |
1208 params.page_id = 2; // New page_id | |
1209 params.url = url; | |
1210 params.transition = PageTransition::CLIENT_REDIRECT; | |
1211 params.redirects.push_back(GURL("http://foo2/#a")); | |
1212 params.redirects.push_back(url); | |
1213 params.should_update_history = true; | |
1214 params.gesture = NavigationGestureUnknown; | |
1215 params.is_post = false; | |
1216 | |
1217 // This SHOULD generate a new entry. | |
1218 NavigationController::LoadCommittedDetails details; | |
1219 EXPECT_TRUE(controller().RendererDidNavigate(params, 0, &details)); | |
1220 EXPECT_TRUE(notifications.Check1AndReset( | |
1221 NotificationType::NAV_ENTRY_COMMITTED)); | |
1222 EXPECT_FALSE(details.is_in_page); | |
1223 EXPECT_EQ(3, controller().entry_count()); | |
1224 } | |
1225 | |
1226 // Verify that BACK brings us back to http://foo2/. | |
1227 { | |
1228 const GURL url("http://foo2/"); | |
1229 controller().GoBack(); | |
1230 rvh()->SendNavigate(1, url); | |
1231 EXPECT_TRUE(notifications.Check1AndReset( | |
1232 NotificationType::NAV_ENTRY_COMMITTED)); | |
1233 EXPECT_EQ(url, controller().GetActiveEntry()->url()); | |
1234 } | |
1235 } | |
1236 | |
1237 // NotificationObserver implementation used in verifying we've received the | |
1238 // NotificationType::NAV_LIST_PRUNED method. | |
1239 class PrunedListener : public NotificationObserver { | |
1240 public: | |
1241 explicit PrunedListener(NavigationController* controller) | |
1242 : notification_count_(0) { | |
1243 registrar_.Add(this, NotificationType::NAV_LIST_PRUNED, | |
1244 Source<NavigationController>(controller)); | |
1245 } | |
1246 | |
1247 virtual void Observe(NotificationType type, | |
1248 const NotificationSource& source, | |
1249 const NotificationDetails& details) { | |
1250 if (type == NotificationType::NAV_LIST_PRUNED) { | |
1251 notification_count_++; | |
1252 details_ = *(Details<NavigationController::PrunedDetails>(details).ptr()); | |
1253 } | |
1254 } | |
1255 | |
1256 // Number of times NAV_LIST_PRUNED has been observed. | |
1257 int notification_count_; | |
1258 | |
1259 // Details from the last NAV_LIST_PRUNED. | |
1260 NavigationController::PrunedDetails details_; | |
1261 | |
1262 private: | |
1263 NotificationRegistrar registrar_; | |
1264 | |
1265 DISALLOW_COPY_AND_ASSIGN(PrunedListener); | |
1266 }; | |
1267 | |
1268 // Tests that we limit the number of navigation entries created correctly. | |
1269 TEST_F(NavigationControllerTest, EnforceMaxNavigationCount) { | |
1270 size_t original_count = NavigationController::max_entry_count(); | |
1271 const int kMaxEntryCount = 5; | |
1272 | |
1273 NavigationController::set_max_entry_count(kMaxEntryCount); | |
1274 | |
1275 int url_index; | |
1276 // Load up to the max count, all entries should be there. | |
1277 for (url_index = 0; url_index < kMaxEntryCount; url_index++) { | |
1278 GURL url(StringPrintf("http://www.a.com/%d", url_index)); | |
1279 controller().LoadURL(url, GURL(), PageTransition::TYPED); | |
1280 rvh()->SendNavigate(url_index, url); | |
1281 } | |
1282 | |
1283 EXPECT_EQ(controller().entry_count(), kMaxEntryCount); | |
1284 | |
1285 // Created a PrunedListener to observe prune notifications. | |
1286 PrunedListener listener(&controller()); | |
1287 | |
1288 // Navigate some more. | |
1289 GURL url(StringPrintf("http://www.a.com/%d", url_index)); | |
1290 controller().LoadURL(url, GURL(), PageTransition::TYPED); | |
1291 rvh()->SendNavigate(url_index, url); | |
1292 url_index++; | |
1293 | |
1294 // We should have got a pruned navigation. | |
1295 EXPECT_EQ(1, listener.notification_count_); | |
1296 EXPECT_TRUE(listener.details_.from_front); | |
1297 EXPECT_EQ(1, listener.details_.count); | |
1298 | |
1299 // We expect http://www.a.com/0 to be gone. | |
1300 EXPECT_EQ(controller().entry_count(), kMaxEntryCount); | |
1301 EXPECT_EQ(controller().GetEntryAtIndex(0)->url(), | |
1302 GURL("http:////www.a.com/1")); | |
1303 | |
1304 // More navigations. | |
1305 for (int i = 0; i < 3; i++) { | |
1306 url = GURL(StringPrintf("http:////www.a.com/%d", url_index)); | |
1307 controller().LoadURL(url, GURL(), PageTransition::TYPED); | |
1308 rvh()->SendNavigate(url_index, url); | |
1309 url_index++; | |
1310 } | |
1311 EXPECT_EQ(controller().entry_count(), kMaxEntryCount); | |
1312 EXPECT_EQ(controller().GetEntryAtIndex(0)->url(), | |
1313 GURL("http:////www.a.com/4")); | |
1314 | |
1315 NavigationController::set_max_entry_count(original_count); | |
1316 } | |
1317 | |
1318 // Tests that we can do a restore and navigate to the restored entries and | |
1319 // everything is updated properly. This can be tricky since there is no | |
1320 // SiteInstance for the entries created initially. | |
1321 TEST_F(NavigationControllerTest, RestoreNavigate) { | |
1322 // Create a NavigationController with a restored set of tabs. | |
1323 GURL url("http://foo"); | |
1324 std::vector<TabNavigation> navigations; | |
1325 navigations.push_back(TabNavigation(0, url, GURL(), | |
1326 ASCIIToUTF16("Title"), "state", | |
1327 PageTransition::LINK)); | |
1328 TabContents our_contents(profile(), NULL, MSG_ROUTING_NONE, NULL, NULL); | |
1329 NavigationController& our_controller = our_contents.controller(); | |
1330 our_controller.RestoreFromState(navigations, 0, true); | |
1331 our_controller.GoToIndex(0); | |
1332 | |
1333 // We should now have one entry, and it should be "pending". | |
1334 EXPECT_EQ(1, our_controller.entry_count()); | |
1335 EXPECT_EQ(our_controller.GetEntryAtIndex(0), | |
1336 our_controller.pending_entry()); | |
1337 EXPECT_EQ(0, our_controller.GetEntryAtIndex(0)->page_id()); | |
1338 EXPECT_EQ(NavigationEntry::RESTORE_LAST_SESSION, | |
1339 our_controller.GetEntryAtIndex(0)->restore_type()); | |
1340 | |
1341 // Say we navigated to that entry. | |
1342 ViewHostMsg_FrameNavigate_Params params; | |
1343 params.page_id = 0; | |
1344 params.url = url; | |
1345 params.transition = PageTransition::LINK; | |
1346 params.should_update_history = false; | |
1347 params.gesture = NavigationGestureUser; | |
1348 params.is_post = false; | |
1349 NavigationController::LoadCommittedDetails details; | |
1350 our_controller.RendererDidNavigate(params, 0, &details); | |
1351 | |
1352 // There should be no longer any pending entry and one committed one. This | |
1353 // means that we were able to locate the entry, assign its site instance, and | |
1354 // commit it properly. | |
1355 EXPECT_EQ(1, our_controller.entry_count()); | |
1356 EXPECT_EQ(0, our_controller.last_committed_entry_index()); | |
1357 EXPECT_FALSE(our_controller.pending_entry()); | |
1358 EXPECT_EQ(url, | |
1359 our_controller.GetLastCommittedEntry()->site_instance()->site()); | |
1360 EXPECT_EQ(NavigationEntry::RESTORE_NONE, | |
1361 our_controller.GetEntryAtIndex(0)->restore_type()); | |
1362 } | |
1363 | |
1364 // Make sure that the page type and stuff is correct after an interstitial. | |
1365 TEST_F(NavigationControllerTest, Interstitial) { | |
1366 // First navigate somewhere normal. | |
1367 const GURL url1("http://foo"); | |
1368 controller().LoadURL(url1, GURL(), PageTransition::TYPED); | |
1369 rvh()->SendNavigate(0, url1); | |
1370 | |
1371 // Now navigate somewhere with an interstitial. | |
1372 const GURL url2("http://bar"); | |
1373 controller().LoadURL(url1, GURL(), PageTransition::TYPED); | |
1374 controller().pending_entry()->set_page_type(INTERSTITIAL_PAGE); | |
1375 | |
1376 // At this point the interstitial will be displayed and the load will still | |
1377 // be pending. If the user continues, the load will commit. | |
1378 rvh()->SendNavigate(1, url2); | |
1379 | |
1380 // The page should be a normal page again. | |
1381 EXPECT_EQ(url2, controller().GetLastCommittedEntry()->url()); | |
1382 EXPECT_EQ(NORMAL_PAGE, controller().GetLastCommittedEntry()->page_type()); | |
1383 } | |
1384 | |
1385 TEST_F(NavigationControllerTest, RemoveEntry) { | |
1386 const GURL url1("http://foo1"); | |
1387 const GURL url2("http://foo2"); | |
1388 const GURL url3("http://foo3"); | |
1389 const GURL url4("http://foo4"); | |
1390 const GURL url5("http://foo5"); | |
1391 const GURL pending_url("http://pending"); | |
1392 const GURL default_url("http://default"); | |
1393 | |
1394 controller().LoadURL(url1, GURL(), PageTransition::TYPED); | |
1395 rvh()->SendNavigate(0, url1); | |
1396 controller().LoadURL(url2, GURL(), PageTransition::TYPED); | |
1397 rvh()->SendNavigate(1, url2); | |
1398 controller().LoadURL(url3, GURL(), PageTransition::TYPED); | |
1399 rvh()->SendNavigate(2, url3); | |
1400 controller().LoadURL(url4, GURL(), PageTransition::TYPED); | |
1401 rvh()->SendNavigate(3, url4); | |
1402 controller().LoadURL(url5, GURL(), PageTransition::TYPED); | |
1403 rvh()->SendNavigate(4, url5); | |
1404 | |
1405 // Remove the last entry. | |
1406 controller().RemoveEntryAtIndex( | |
1407 controller().entry_count() - 1, default_url); | |
1408 EXPECT_EQ(4, controller().entry_count()); | |
1409 EXPECT_EQ(3, controller().last_committed_entry_index()); | |
1410 NavigationEntry* pending_entry = controller().pending_entry(); | |
1411 EXPECT_TRUE(pending_entry && pending_entry->url() == url4); | |
1412 | |
1413 // Add a pending entry. | |
1414 controller().LoadURL(pending_url, GURL(), PageTransition::TYPED); | |
1415 // Now remove the last entry. | |
1416 controller().RemoveEntryAtIndex( | |
1417 controller().entry_count() - 1, default_url); | |
1418 // The pending entry should have been discarded and the last committed entry | |
1419 // removed. | |
1420 EXPECT_EQ(3, controller().entry_count()); | |
1421 EXPECT_EQ(2, controller().last_committed_entry_index()); | |
1422 pending_entry = controller().pending_entry(); | |
1423 EXPECT_TRUE(pending_entry && pending_entry->url() == url3); | |
1424 | |
1425 // Remove an entry which is not the last committed one. | |
1426 controller().RemoveEntryAtIndex(0, default_url); | |
1427 EXPECT_EQ(2, controller().entry_count()); | |
1428 EXPECT_EQ(1, controller().last_committed_entry_index()); | |
1429 // No navigation should have been initiated since we did not remove the | |
1430 // current entry. | |
1431 EXPECT_FALSE(controller().pending_entry()); | |
1432 | |
1433 // Remove the 2 remaining entries. | |
1434 controller().RemoveEntryAtIndex(1, default_url); | |
1435 controller().RemoveEntryAtIndex(0, default_url); | |
1436 | |
1437 // This should have created a pending default entry. | |
1438 EXPECT_EQ(0, controller().entry_count()); | |
1439 EXPECT_EQ(-1, controller().last_committed_entry_index()); | |
1440 pending_entry = controller().pending_entry(); | |
1441 EXPECT_TRUE(pending_entry && pending_entry->url() == default_url); | |
1442 } | |
1443 | |
1444 // Tests the transient entry, making sure it goes away with all navigations. | |
1445 TEST_F(NavigationControllerTest, TransientEntry) { | |
1446 TestNotificationTracker notifications; | |
1447 RegisterForAllNavNotifications(¬ifications, &controller()); | |
1448 | |
1449 const GURL url0("http://foo0"); | |
1450 const GURL url1("http://foo1"); | |
1451 const GURL url2("http://foo2"); | |
1452 const GURL url3("http://foo3"); | |
1453 const GURL url4("http://foo4"); | |
1454 const GURL transient_url("http://transient"); | |
1455 | |
1456 controller().LoadURL(url0, GURL(), PageTransition::TYPED); | |
1457 rvh()->SendNavigate(0, url0); | |
1458 controller().LoadURL(url1, GURL(), PageTransition::TYPED); | |
1459 rvh()->SendNavigate(1, url1); | |
1460 | |
1461 notifications.Reset(); | |
1462 | |
1463 // Adding a transient with no pending entry. | |
1464 NavigationEntry* transient_entry = new NavigationEntry; | |
1465 transient_entry->set_url(transient_url); | |
1466 controller().AddTransientEntry(transient_entry); | |
1467 | |
1468 // We should not have received any notifications. | |
1469 EXPECT_EQ(0U, notifications.size()); | |
1470 | |
1471 // Check our state. | |
1472 EXPECT_EQ(transient_url, controller().GetActiveEntry()->url()); | |
1473 EXPECT_EQ(controller().entry_count(), 3); | |
1474 EXPECT_EQ(controller().last_committed_entry_index(), 1); | |
1475 EXPECT_EQ(controller().pending_entry_index(), -1); | |
1476 EXPECT_TRUE(controller().GetLastCommittedEntry()); | |
1477 EXPECT_FALSE(controller().pending_entry()); | |
1478 EXPECT_TRUE(controller().CanGoBack()); | |
1479 EXPECT_FALSE(controller().CanGoForward()); | |
1480 EXPECT_EQ(contents()->GetMaxPageID(), 1); | |
1481 | |
1482 // Navigate. | |
1483 controller().LoadURL(url2, GURL(), PageTransition::TYPED); | |
1484 rvh()->SendNavigate(2, url2); | |
1485 | |
1486 // We should have navigated, transient entry should be gone. | |
1487 EXPECT_EQ(url2, controller().GetActiveEntry()->url()); | |
1488 EXPECT_EQ(controller().entry_count(), 3); | |
1489 | |
1490 // Add a transient again, then navigate with no pending entry this time. | |
1491 transient_entry = new NavigationEntry; | |
1492 transient_entry->set_url(transient_url); | |
1493 controller().AddTransientEntry(transient_entry); | |
1494 EXPECT_EQ(transient_url, controller().GetActiveEntry()->url()); | |
1495 rvh()->SendNavigate(3, url3); | |
1496 // Transient entry should be gone. | |
1497 EXPECT_EQ(url3, controller().GetActiveEntry()->url()); | |
1498 EXPECT_EQ(controller().entry_count(), 4); | |
1499 | |
1500 // Initiate a navigation, add a transient then commit navigation. | |
1501 controller().LoadURL(url4, GURL(), PageTransition::TYPED); | |
1502 transient_entry = new NavigationEntry; | |
1503 transient_entry->set_url(transient_url); | |
1504 controller().AddTransientEntry(transient_entry); | |
1505 EXPECT_EQ(transient_url, controller().GetActiveEntry()->url()); | |
1506 rvh()->SendNavigate(4, url4); | |
1507 EXPECT_EQ(url4, controller().GetActiveEntry()->url()); | |
1508 EXPECT_EQ(controller().entry_count(), 5); | |
1509 | |
1510 // Add a transient and go back. This should simply remove the transient. | |
1511 transient_entry = new NavigationEntry; | |
1512 transient_entry->set_url(transient_url); | |
1513 controller().AddTransientEntry(transient_entry); | |
1514 EXPECT_EQ(transient_url, controller().GetActiveEntry()->url()); | |
1515 EXPECT_TRUE(controller().CanGoBack()); | |
1516 EXPECT_FALSE(controller().CanGoForward()); | |
1517 controller().GoBack(); | |
1518 // Transient entry should be gone. | |
1519 EXPECT_EQ(url4, controller().GetActiveEntry()->url()); | |
1520 EXPECT_EQ(controller().entry_count(), 5); | |
1521 rvh()->SendNavigate(3, url3); | |
1522 | |
1523 // Add a transient and go to an entry before the current one. | |
1524 transient_entry = new NavigationEntry; | |
1525 transient_entry->set_url(transient_url); | |
1526 controller().AddTransientEntry(transient_entry); | |
1527 EXPECT_EQ(transient_url, controller().GetActiveEntry()->url()); | |
1528 controller().GoToIndex(1); | |
1529 // The navigation should have been initiated, transient entry should be gone. | |
1530 EXPECT_EQ(url1, controller().GetActiveEntry()->url()); | |
1531 rvh()->SendNavigate(1, url1); | |
1532 | |
1533 // Add a transient and go to an entry after the current one. | |
1534 transient_entry = new NavigationEntry; | |
1535 transient_entry->set_url(transient_url); | |
1536 controller().AddTransientEntry(transient_entry); | |
1537 EXPECT_EQ(transient_url, controller().GetActiveEntry()->url()); | |
1538 controller().GoToIndex(3); | |
1539 // The navigation should have been initiated, transient entry should be gone. | |
1540 // Because of the transient entry that is removed, going to index 3 makes us | |
1541 // land on url2. | |
1542 EXPECT_EQ(url2, controller().GetActiveEntry()->url()); | |
1543 rvh()->SendNavigate(2, url2); | |
1544 | |
1545 // Add a transient and go forward. | |
1546 transient_entry = new NavigationEntry; | |
1547 transient_entry->set_url(transient_url); | |
1548 controller().AddTransientEntry(transient_entry); | |
1549 EXPECT_EQ(transient_url, controller().GetActiveEntry()->url()); | |
1550 EXPECT_TRUE(controller().CanGoForward()); | |
1551 controller().GoForward(); | |
1552 // We should have navigated, transient entry should be gone. | |
1553 EXPECT_EQ(url3, controller().GetActiveEntry()->url()); | |
1554 rvh()->SendNavigate(3, url3); | |
1555 | |
1556 // Ensure the URLS are correct. | |
1557 EXPECT_EQ(controller().entry_count(), 5); | |
1558 EXPECT_EQ(controller().GetEntryAtIndex(0)->url(), url0); | |
1559 EXPECT_EQ(controller().GetEntryAtIndex(1)->url(), url1); | |
1560 EXPECT_EQ(controller().GetEntryAtIndex(2)->url(), url2); | |
1561 EXPECT_EQ(controller().GetEntryAtIndex(3)->url(), url3); | |
1562 EXPECT_EQ(controller().GetEntryAtIndex(4)->url(), url4); | |
1563 } | |
1564 | |
1565 // Tests that IsInPageNavigation returns appropriate results. Prevents | |
1566 // regression for bug 1126349. | |
1567 TEST_F(NavigationControllerTest, IsInPageNavigation) { | |
1568 // Navigate to URL with no refs. | |
1569 const GURL url("http://www.google.com/home.html"); | |
1570 rvh()->SendNavigate(0, url); | |
1571 | |
1572 // Reloading the page is not an in-page navigation. | |
1573 EXPECT_FALSE(controller().IsURLInPageNavigation(url)); | |
1574 const GURL other_url("http://www.google.com/add.html"); | |
1575 EXPECT_FALSE(controller().IsURLInPageNavigation(other_url)); | |
1576 const GURL url_with_ref("http://www.google.com/home.html#my_ref"); | |
1577 EXPECT_TRUE(controller().IsURLInPageNavigation(url_with_ref)); | |
1578 | |
1579 // Navigate to URL with refs. | |
1580 rvh()->SendNavigate(1, url_with_ref); | |
1581 | |
1582 // Reloading the page is not an in-page navigation. | |
1583 EXPECT_FALSE(controller().IsURLInPageNavigation(url_with_ref)); | |
1584 EXPECT_FALSE(controller().IsURLInPageNavigation(url)); | |
1585 EXPECT_FALSE(controller().IsURLInPageNavigation(other_url)); | |
1586 const GURL other_url_with_ref("http://www.google.com/home.html#my_other_ref"); | |
1587 EXPECT_TRUE(controller().IsURLInPageNavigation( | |
1588 other_url_with_ref)); | |
1589 } | |
1590 | |
1591 // Some pages can have subframes with the same base URL (minus the reference) as | |
1592 // the main page. Even though this is hard, it can happen, and we don't want | |
1593 // these subframe navigations to affect the toplevel document. They should | |
1594 // instead be ignored. http://crbug.com/5585 | |
1595 TEST_F(NavigationControllerTest, SameSubframe) { | |
1596 // Navigate the main frame. | |
1597 const GURL url("http://www.google.com/"); | |
1598 rvh()->SendNavigate(0, url); | |
1599 | |
1600 // We should be at the first navigation entry. | |
1601 EXPECT_EQ(controller().entry_count(), 1); | |
1602 EXPECT_EQ(controller().last_committed_entry_index(), 0); | |
1603 | |
1604 // Navigate a subframe that would normally count as in-page. | |
1605 const GURL subframe("http://www.google.com/#"); | |
1606 ViewHostMsg_FrameNavigate_Params params; | |
1607 params.page_id = 0; | |
1608 params.url = subframe; | |
1609 params.transition = PageTransition::AUTO_SUBFRAME; | |
1610 params.should_update_history = false; | |
1611 params.gesture = NavigationGestureAuto; | |
1612 params.is_post = false; | |
1613 NavigationController::LoadCommittedDetails details; | |
1614 EXPECT_FALSE(controller().RendererDidNavigate(params, 0, &details)); | |
1615 | |
1616 // Nothing should have changed. | |
1617 EXPECT_EQ(controller().entry_count(), 1); | |
1618 EXPECT_EQ(controller().last_committed_entry_index(), 0); | |
1619 } | |
1620 | |
1621 // Test view source redirection is reflected in title bar. | |
1622 TEST_F(NavigationControllerTest, ViewSourceRedirect) { | |
1623 const char kUrl[] = "view-source:http://redirect.to/google.com"; | |
1624 const char kResult[] = "http://google.com"; | |
1625 const char kExpected[] = "view-source:google.com"; | |
1626 const GURL url(kUrl); | |
1627 const GURL result_url(kResult); | |
1628 | |
1629 controller().LoadURL(url, GURL(), PageTransition::TYPED); | |
1630 | |
1631 ViewHostMsg_FrameNavigate_Params params; | |
1632 params.page_id = 0; | |
1633 params.url = result_url; | |
1634 params.transition = PageTransition::SERVER_REDIRECT; | |
1635 params.should_update_history = false; | |
1636 params.gesture = NavigationGestureAuto; | |
1637 params.is_post = false; | |
1638 NavigationController::LoadCommittedDetails details; | |
1639 controller().RendererDidNavigate(params, 0, &details); | |
1640 | |
1641 EXPECT_EQ(ASCIIToUTF16(kExpected), contents()->GetTitle()); | |
1642 EXPECT_TRUE(contents()->ShouldDisplayURL()); | |
1643 } | |
1644 | |
1645 // Make sure that on cloning a tabcontents and going back needs_reload is false. | |
1646 TEST_F(NavigationControllerTest, CloneAndGoBack) { | |
1647 const GURL url1("http://foo1"); | |
1648 const GURL url2("http://foo2"); | |
1649 | |
1650 NavigateAndCommit(url1); | |
1651 NavigateAndCommit(url2); | |
1652 | |
1653 scoped_ptr<TabContents> clone(controller().tab_contents()->Clone()); | |
1654 | |
1655 ASSERT_EQ(2, clone->controller().entry_count()); | |
1656 EXPECT_TRUE(clone->controller().needs_reload()); | |
1657 clone->controller().GoBack(); | |
1658 // Navigating back should have triggered needs_reload_ to go false. | |
1659 EXPECT_FALSE(clone->controller().needs_reload()); | |
1660 } | |
1661 | |
1662 // Make sure that cloning a tabcontents doesn't copy interstitials. | |
1663 TEST_F(NavigationControllerTest, CloneOmitsInterstitials) { | |
1664 const GURL url1("http://foo1"); | |
1665 const GURL url2("http://foo2"); | |
1666 | |
1667 NavigateAndCommit(url1); | |
1668 NavigateAndCommit(url2); | |
1669 | |
1670 // Add an interstitial entry. Should be deleted with controller. | |
1671 NavigationEntry* interstitial_entry = new NavigationEntry(); | |
1672 interstitial_entry->set_page_type(INTERSTITIAL_PAGE); | |
1673 controller().AddTransientEntry(interstitial_entry); | |
1674 | |
1675 scoped_ptr<TabContents> clone(controller().tab_contents()->Clone()); | |
1676 | |
1677 ASSERT_EQ(2, clone->controller().entry_count()); | |
1678 } | |
1679 | |
1680 // Tests a subframe navigation while a toplevel navigation is pending. | |
1681 // http://crbug.com/43967 | |
1682 TEST_F(NavigationControllerTest, SubframeWhilePending) { | |
1683 // Load the first page. | |
1684 const GURL url1("http://foo/"); | |
1685 NavigateAndCommit(url1); | |
1686 | |
1687 // Now start a pending load to a totally different page, but don't commit it. | |
1688 const GURL url2("http://bar/"); | |
1689 controller().LoadURL(url2, GURL(), PageTransition::TYPED); | |
1690 | |
1691 // Send a subframe update from the first page, as if one had just | |
1692 // automatically loaded. Auto subframes don't increment the page ID. | |
1693 const GURL url1_sub("http://foo/subframe"); | |
1694 ViewHostMsg_FrameNavigate_Params params; | |
1695 params.page_id = controller().GetLastCommittedEntry()->page_id(); | |
1696 params.url = url1_sub; | |
1697 params.transition = PageTransition::AUTO_SUBFRAME; | |
1698 params.should_update_history = false; | |
1699 params.gesture = NavigationGestureAuto; | |
1700 params.is_post = false; | |
1701 NavigationController::LoadCommittedDetails details; | |
1702 | |
1703 // This should return false meaning that nothing was actually updated. | |
1704 EXPECT_FALSE(controller().RendererDidNavigate(params, 0, &details)); | |
1705 | |
1706 // The notification should have updated the last committed one, and not | |
1707 // the pending load. | |
1708 EXPECT_EQ(url1, controller().GetLastCommittedEntry()->url()); | |
1709 | |
1710 // The active entry should be unchanged by the subframe load. | |
1711 EXPECT_EQ(url2, controller().GetActiveEntry()->url()); | |
1712 } | |
1713 | |
1714 // Tests CopyStateFromAndPrune with 2 urls in source, 1 in dest. | |
1715 TEST_F(NavigationControllerTest, CopyStateFromAndPrune) { | |
1716 SessionID id(controller().session_id()); | |
1717 const GURL url1("http://foo1"); | |
1718 const GURL url2("http://foo2"); | |
1719 const GURL url3("http://foo3"); | |
1720 | |
1721 NavigateAndCommit(url1); | |
1722 NavigateAndCommit(url2); | |
1723 | |
1724 scoped_ptr<TestTabContents> other_contents(CreateTestTabContents()); | |
1725 NavigationController& other_controller = other_contents->controller(); | |
1726 SessionID other_id(other_controller.session_id()); | |
1727 other_contents->NavigateAndCommit(url3); | |
1728 other_controller.CopyStateFromAndPrune(&controller()); | |
1729 | |
1730 // other_controller should now contain the 3 urls: url1, url2 and url3. | |
1731 | |
1732 ASSERT_EQ(3, other_controller.entry_count()); | |
1733 | |
1734 ASSERT_EQ(2, other_controller.GetCurrentEntryIndex()); | |
1735 | |
1736 EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->url()); | |
1737 EXPECT_EQ(url2, other_controller.GetEntryAtIndex(1)->url()); | |
1738 EXPECT_EQ(url3, other_controller.GetEntryAtIndex(2)->url()); | |
1739 | |
1740 // Make sure session ids didn't change. | |
1741 EXPECT_EQ(id.id(), controller().session_id().id()); | |
1742 EXPECT_EQ(other_id.id(), other_controller.session_id().id()); | |
1743 } | |
1744 | |
1745 // Test CopyStateFromAndPrune with 2 urls, the first selected and nothing in | |
1746 // the target. | |
1747 TEST_F(NavigationControllerTest, CopyStateFromAndPrune2) { | |
1748 SessionID id(controller().session_id()); | |
1749 const GURL url1("http://foo1"); | |
1750 const GURL url2("http://foo2"); | |
1751 const GURL url3("http://foo3"); | |
1752 | |
1753 NavigateAndCommit(url1); | |
1754 NavigateAndCommit(url2); | |
1755 controller().GoBack(); | |
1756 | |
1757 scoped_ptr<TestTabContents> other_contents(CreateTestTabContents()); | |
1758 NavigationController& other_controller = other_contents->controller(); | |
1759 SessionID other_id(other_controller.session_id()); | |
1760 other_controller.CopyStateFromAndPrune(&controller()); | |
1761 | |
1762 // other_controller should now contain the 1 url: url1. | |
1763 | |
1764 ASSERT_EQ(1, other_controller.entry_count()); | |
1765 | |
1766 ASSERT_EQ(0, other_controller.GetCurrentEntryIndex()); | |
1767 | |
1768 EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->url()); | |
1769 | |
1770 // Make sure session ids didn't change. | |
1771 EXPECT_EQ(id.id(), controller().session_id().id()); | |
1772 EXPECT_EQ(other_id.id(), other_controller.session_id().id()); | |
1773 } | |
1774 | |
1775 // Test CopyStateFromAndPrune with 2 urls, the first selected and nothing in | |
1776 // the target. | |
1777 TEST_F(NavigationControllerTest, CopyStateFromAndPrune3) { | |
1778 SessionID id(controller().session_id()); | |
1779 const GURL url1("http://foo1"); | |
1780 const GURL url2("http://foo2"); | |
1781 const GURL url3("http://foo3"); | |
1782 | |
1783 NavigateAndCommit(url1); | |
1784 NavigateAndCommit(url2); | |
1785 controller().GoBack(); | |
1786 | |
1787 scoped_ptr<TestTabContents> other_contents(CreateTestTabContents()); | |
1788 NavigationController& other_controller = other_contents->controller(); | |
1789 SessionID other_id(other_controller.session_id()); | |
1790 other_controller.LoadURL(url3, GURL(), PageTransition::TYPED); | |
1791 other_controller.CopyStateFromAndPrune(&controller()); | |
1792 | |
1793 // other_controller should now contain 1 entry for url1, and a pending entry | |
1794 // for url3. | |
1795 | |
1796 ASSERT_EQ(1, other_controller.entry_count()); | |
1797 | |
1798 EXPECT_EQ(0, other_controller.GetCurrentEntryIndex()); | |
1799 | |
1800 EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->url()); | |
1801 | |
1802 // And there should be a pending entry for url3. | |
1803 ASSERT_TRUE(other_controller.pending_entry()); | |
1804 | |
1805 EXPECT_EQ(url3, other_controller.pending_entry()->url()); | |
1806 | |
1807 // Make sure session ids didn't change. | |
1808 EXPECT_EQ(id.id(), controller().session_id().id()); | |
1809 EXPECT_EQ(other_id.id(), other_controller.session_id().id()); | |
1810 } | |
1811 | |
1812 // Tests that navigations initiated from the page (with the history object) | |
1813 // work as expected without navigation entries. | |
1814 TEST_F(NavigationControllerTest, HistoryNavigate) { | |
1815 const GURL url1("http://foo1"); | |
1816 const GURL url2("http://foo2"); | |
1817 const GURL url3("http://foo3"); | |
1818 | |
1819 NavigateAndCommit(url1); | |
1820 NavigateAndCommit(url2); | |
1821 NavigateAndCommit(url3); | |
1822 controller().GoBack(); | |
1823 contents()->CommitPendingNavigation(); | |
1824 | |
1825 // Simulate the page calling history.back(), it should not create a pending | |
1826 // entry. | |
1827 contents()->OnGoToEntryAtOffset(-1); | |
1828 EXPECT_EQ(-1, controller().pending_entry_index()); | |
1829 // The actual cross-navigation is suspended until the current RVH tells us | |
1830 // it unloaded, simulate that. | |
1831 contents()->ProceedWithCrossSiteNavigation(); | |
1832 // Also make sure we told the page to navigate. | |
1833 const IPC::Message* message = | |
1834 process()->sink().GetFirstMessageMatching(ViewMsg_Navigate::ID); | |
1835 ASSERT_TRUE(message != NULL); | |
1836 Tuple1<ViewMsg_Navigate_Params> nav_params; | |
1837 ViewMsg_Navigate::Read(message, &nav_params); | |
1838 EXPECT_EQ(url1, nav_params.a.url); | |
1839 process()->sink().ClearMessages(); | |
1840 | |
1841 // Now test history.forward() | |
1842 contents()->OnGoToEntryAtOffset(1); | |
1843 EXPECT_EQ(-1, controller().pending_entry_index()); | |
1844 // The actual cross-navigation is suspended until the current RVH tells us | |
1845 // it unloaded, simulate that. | |
1846 contents()->ProceedWithCrossSiteNavigation(); | |
1847 message = process()->sink().GetFirstMessageMatching(ViewMsg_Navigate::ID); | |
1848 ASSERT_TRUE(message != NULL); | |
1849 ViewMsg_Navigate::Read(message, &nav_params); | |
1850 EXPECT_EQ(url3, nav_params.a.url); | |
1851 process()->sink().ClearMessages(); | |
1852 | |
1853 // Make sure an extravagant history.go() doesn't break. | |
1854 contents()->OnGoToEntryAtOffset(120); // Out of bounds. | |
1855 EXPECT_EQ(-1, controller().pending_entry_index()); | |
1856 message = process()->sink().GetFirstMessageMatching(ViewMsg_Navigate::ID); | |
1857 EXPECT_TRUE(message == NULL); | |
1858 } | |
1859 | |
1860 // Test call to PruneAllButActive for the only entry. | |
1861 TEST_F(NavigationControllerTest, PruneAllButActiveForSingle) { | |
1862 const GURL url1("http://foo1"); | |
1863 NavigateAndCommit(url1); | |
1864 controller().PruneAllButActive(); | |
1865 | |
1866 EXPECT_EQ(-1, controller().pending_entry_index()); | |
1867 EXPECT_EQ(controller().GetEntryAtIndex(0)->url(), url1); | |
1868 } | |
1869 | |
1870 // Test call to PruneAllButActive for last entry. | |
1871 TEST_F(NavigationControllerTest, PruneAllButActiveForLast) { | |
1872 const GURL url1("http://foo1"); | |
1873 const GURL url2("http://foo2"); | |
1874 const GURL url3("http://foo3"); | |
1875 | |
1876 NavigateAndCommit(url1); | |
1877 NavigateAndCommit(url2); | |
1878 NavigateAndCommit(url3); | |
1879 controller().GoBack(); | |
1880 controller().GoBack(); | |
1881 contents()->CommitPendingNavigation(); | |
1882 | |
1883 controller().PruneAllButActive(); | |
1884 | |
1885 EXPECT_EQ(-1, controller().pending_entry_index()); | |
1886 EXPECT_EQ(controller().GetEntryAtIndex(0)->url(), url1); | |
1887 } | |
1888 | |
1889 // Test call to PruneAllButActive for intermediate entry. | |
1890 TEST_F(NavigationControllerTest, PruneAllButActiveForIntermediate) { | |
1891 const GURL url1("http://foo1"); | |
1892 const GURL url2("http://foo2"); | |
1893 const GURL url3("http://foo3"); | |
1894 | |
1895 NavigateAndCommit(url1); | |
1896 NavigateAndCommit(url2); | |
1897 NavigateAndCommit(url3); | |
1898 controller().GoBack(); | |
1899 contents()->CommitPendingNavigation(); | |
1900 | |
1901 controller().PruneAllButActive(); | |
1902 | |
1903 EXPECT_EQ(-1, controller().pending_entry_index()); | |
1904 EXPECT_EQ(controller().GetEntryAtIndex(0)->url(), url2); | |
1905 } | |
1906 | |
1907 // Test call to PruneAllButActive for intermediate entry. | |
1908 TEST_F(NavigationControllerTest, PruneAllButActiveForPending) { | |
1909 const GURL url1("http://foo1"); | |
1910 const GURL url2("http://foo2"); | |
1911 const GURL url3("http://foo3"); | |
1912 | |
1913 NavigateAndCommit(url1); | |
1914 NavigateAndCommit(url2); | |
1915 NavigateAndCommit(url3); | |
1916 controller().GoBack(); | |
1917 | |
1918 controller().PruneAllButActive(); | |
1919 | |
1920 EXPECT_EQ(0, controller().pending_entry_index()); | |
1921 } | |
1922 | |
1923 // Test call to PruneAllButActive for transient entry. | |
1924 TEST_F(NavigationControllerTest, PruneAllButActiveForTransient) { | |
1925 const GURL url0("http://foo0"); | |
1926 const GURL url1("http://foo1"); | |
1927 const GURL transient_url("http://transient"); | |
1928 | |
1929 controller().LoadURL(url0, GURL(), PageTransition::TYPED); | |
1930 rvh()->SendNavigate(0, url0); | |
1931 controller().LoadURL(url1, GURL(), PageTransition::TYPED); | |
1932 rvh()->SendNavigate(1, url1); | |
1933 | |
1934 // Adding a transient with no pending entry. | |
1935 NavigationEntry* transient_entry = new NavigationEntry; | |
1936 transient_entry->set_url(transient_url); | |
1937 controller().AddTransientEntry(transient_entry); | |
1938 | |
1939 controller().PruneAllButActive(); | |
1940 | |
1941 EXPECT_EQ(-1, controller().pending_entry_index()); | |
1942 EXPECT_EQ(-1, controller().pending_entry_index()); | |
1943 EXPECT_EQ(controller().GetTransientEntry()->url(), transient_url); | |
1944 } | |
1945 | |
1946 /* TODO(brettw) These test pass on my local machine but fail on the XP buildbot | |
1947 (but not Vista) cleaning up the directory after they run. | |
1948 This should be fixed. | |
1949 | |
1950 // A basic test case. Navigates to a single url, and make sure the history | |
1951 // db matches. | |
1952 TEST_F(NavigationControllerHistoryTest, Basic) { | |
1953 controller().LoadURL(url0, GURL(), PageTransition::LINK); | |
1954 rvh()->SendNavigate(0, url0); | |
1955 | |
1956 GetLastSession(); | |
1957 | |
1958 session_helper_.AssertSingleWindowWithSingleTab(windows_, 1); | |
1959 session_helper_.AssertTabEquals(0, 0, 1, *(windows_[0]->tabs[0])); | |
1960 TabNavigation nav1(0, url0, GURL(), string16(), | |
1961 webkit_glue::CreateHistoryStateForURL(url0), | |
1962 PageTransition::LINK); | |
1963 session_helper_.AssertNavigationEquals(nav1, | |
1964 windows_[0]->tabs[0]->navigations[0]); | |
1965 } | |
1966 | |
1967 // Navigates to three urls, then goes back and make sure the history database | |
1968 // is in sync. | |
1969 TEST_F(NavigationControllerHistoryTest, NavigationThenBack) { | |
1970 rvh()->SendNavigate(0, url0); | |
1971 rvh()->SendNavigate(1, url1); | |
1972 rvh()->SendNavigate(2, url2); | |
1973 | |
1974 controller().GoBack(); | |
1975 rvh()->SendNavigate(1, url1); | |
1976 | |
1977 GetLastSession(); | |
1978 | |
1979 session_helper_.AssertSingleWindowWithSingleTab(windows_, 3); | |
1980 session_helper_.AssertTabEquals(0, 1, 3, *(windows_[0]->tabs[0])); | |
1981 | |
1982 TabNavigation nav(0, url0, GURL(), string16(), | |
1983 webkit_glue::CreateHistoryStateForURL(url0), | |
1984 PageTransition::LINK); | |
1985 session_helper_.AssertNavigationEquals(nav, | |
1986 windows_[0]->tabs[0]->navigations[0]); | |
1987 nav.set_url(url1); | |
1988 session_helper_.AssertNavigationEquals(nav, | |
1989 windows_[0]->tabs[0]->navigations[1]); | |
1990 nav.set_url(url2); | |
1991 session_helper_.AssertNavigationEquals(nav, | |
1992 windows_[0]->tabs[0]->navigations[2]); | |
1993 } | |
1994 | |
1995 // Navigates to three urls, then goes back twice, then loads a new url. | |
1996 TEST_F(NavigationControllerHistoryTest, NavigationPruning) { | |
1997 rvh()->SendNavigate(0, url0); | |
1998 rvh()->SendNavigate(1, url1); | |
1999 rvh()->SendNavigate(2, url2); | |
2000 | |
2001 controller().GoBack(); | |
2002 rvh()->SendNavigate(1, url1); | |
2003 | |
2004 controller().GoBack(); | |
2005 rvh()->SendNavigate(0, url0); | |
2006 | |
2007 rvh()->SendNavigate(3, url2); | |
2008 | |
2009 // Now have url0, and url2. | |
2010 | |
2011 GetLastSession(); | |
2012 | |
2013 session_helper_.AssertSingleWindowWithSingleTab(windows_, 2); | |
2014 session_helper_.AssertTabEquals(0, 1, 2, *(windows_[0]->tabs[0])); | |
2015 | |
2016 TabNavigation nav(0, url0, GURL(), string16(), | |
2017 webkit_glue::CreateHistoryStateForURL(url0), | |
2018 PageTransition::LINK); | |
2019 session_helper_.AssertNavigationEquals(nav, | |
2020 windows_[0]->tabs[0]->navigations[0]); | |
2021 nav.set_url(url2); | |
2022 session_helper_.AssertNavigationEquals(nav, | |
2023 windows_[0]->tabs[0]->navigations[1]); | |
2024 } | |
2025 */ | |
OLD | NEW |