blob: 4047524bdfa39a2c07f80f2bce6ac6f8deae5c17 [file] [log] [blame]
[email protected]a1feae52010-10-11 22:14:451// 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 "chrome/browser/browser.h"
6#include "chrome/browser/browser_list.h"
7#include "chrome/browser/browser_navigator.h"
8#include "chrome/browser/browser_window.h"
9#include "chrome/browser/profile.h"
10#include "chrome/browser/tab_contents/tab_contents.h"
11#include "chrome/browser/tab_contents/tab_contents_view.h"
12#include "chrome/browser/tabs/tab_strip_model.h"
13#include "chrome/test/in_process_browser_test.h"
14#include "chrome/test/ui_test_utils.h"
15#include "ipc/ipc_message.h"
16
17namespace {
18
[email protected]19d9f3a2010-10-14 21:49:3619class BrowserNavigatorTest : public InProcessBrowserTest {
[email protected]a1feae52010-10-11 22:14:4520 protected:
21 GURL GetGoogleURL() const {
22 return GURL("http://www.google.com/");
23 }
24
25 browser::NavigateParams MakeNavigateParams() const {
26 return MakeNavigateParams(browser());
27 }
28 browser::NavigateParams MakeNavigateParams(Browser* browser) const {
29 browser::NavigateParams params(browser, GetGoogleURL(),
30 PageTransition::LINK);
31 params.show_window = true;
32 return params;
33 }
34
35 Browser* CreateEmptyBrowserForType(Browser::Type type, Profile* profile) {
36 Browser* browser = Browser::CreateForType(type, profile);
37 browser->AddBlankTab(true);
38 return browser;
39 }
40
41 TabContents* CreateTabContents() {
42 return new TabContents(browser()->profile(),
43 NULL,
44 MSG_ROUTING_NONE,
45 browser()->GetSelectedTabContents(),
46 NULL);
47 }
48
49 void RunSuppressTest(WindowOpenDisposition disposition) {
50 GURL old_url = browser()->GetSelectedTabContents()->GetURL();
51 browser::NavigateParams p(MakeNavigateParams());
52 p.disposition = disposition;
[email protected]19d9f3a2010-10-14 21:49:3653 browser::Navigate(&p);
[email protected]a1feae52010-10-11 22:14:4554
55 // Nothing should have happened as a result of Navigate();
56 EXPECT_EQ(1, browser()->tab_count());
57 EXPECT_EQ(1u, BrowserList::size());
58 EXPECT_EQ(old_url, browser()->GetSelectedTabContents()->GetURL());
59 }
60};
61
[email protected]a1feae52010-10-11 22:14:4562// This test verifies that when a navigation occurs within a tab, the tab count
63// of the Browser remains the same and the current tab bears the loaded URL.
64IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_CurrentTab) {
65 browser::NavigateParams p(MakeNavigateParams());
[email protected]19d9f3a2010-10-14 21:49:3666 browser::Navigate(&p);
[email protected]a1feae52010-10-11 22:14:4567 ui_test_utils::WaitForNavigationInCurrentTab(browser());
68 EXPECT_EQ(GetGoogleURL(), browser()->GetSelectedTabContents()->GetURL());
69 // We should have one window with one tab.
70 EXPECT_EQ(1u, BrowserList::size());
71 EXPECT_EQ(1, browser()->tab_count());
72}
73
[email protected]19d9f3a2010-10-14 21:49:3674// This test verifies that a singleton tab is refocused if one is already open
75// in another or an existing window, or added if it is not.
76IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_SingletonTabExisting) {
77 GURL url("http://www.google.com/");
78 GURL singleton_url1("http://maps.google.com/");
79 browser()->AddSelectedTabWithURL(singleton_url1, PageTransition::LINK);
80 browser()->AddSelectedTabWithURL(url, PageTransition::LINK);
81
82 // We should have one browser with 3 tabs, the 3rd selected.
83 EXPECT_EQ(1u, BrowserList::size());
84 EXPECT_EQ(2, browser()->selected_index());
85
86 // Navigate to singleton_url1.
87 browser::NavigateParams p(MakeNavigateParams());
88 p.disposition = SINGLETON_TAB;
89 p.url = singleton_url1;
90 browser::Navigate(&p);
91
92 // The middle tab should now be selected.
93 EXPECT_EQ(browser(), p.browser);
94 EXPECT_EQ(1, browser()->selected_index());
95}
96
97IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
98 Disposition_SingletonTabNoneExisting) {
99 GURL url("http://www.google.com/");
100 GURL singleton_url1("http://maps.google.com/");
101
102 // We should have one browser with 3 tabs, the 3rd selected.
103 EXPECT_EQ(1u, BrowserList::size());
104 EXPECT_EQ(0, browser()->selected_index());
105
106 // Navigate to singleton_url1.
107 browser::NavigateParams p(MakeNavigateParams());
108 p.disposition = SINGLETON_TAB;
109 p.url = singleton_url1;
110 browser::Navigate(&p);
111
112 // We should now have 2 tabs, the 2nd one selected.
113 EXPECT_EQ(browser(), p.browser);
114 EXPECT_EQ(2, browser()->tab_count());
115 EXPECT_EQ(1, browser()->selected_index());
[email protected]a1feae52010-10-11 22:14:45116}
117
118// This test verifies that when a navigation results in a foreground tab, the
119// tab count of the Browser increases and the selected tab shifts to the new
120// foreground tab.
121IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewForegroundTab) {
122 TabContents* old_contents = browser()->GetSelectedTabContents();
123 browser::NavigateParams p(MakeNavigateParams());
124 p.disposition = NEW_FOREGROUND_TAB;
[email protected]19d9f3a2010-10-14 21:49:36125 browser::Navigate(&p);
[email protected]a1feae52010-10-11 22:14:45126 EXPECT_NE(old_contents, browser()->GetSelectedTabContents());
127 EXPECT_EQ(browser()->GetSelectedTabContents(), p.target_contents);
128 EXPECT_EQ(2, browser()->tab_count());
129}
130
131// This test verifies that when a navigation results in a background tab, the
132// tab count of the Browser increases but the selected tab remains the same.
133IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewBackgroundTab) {
134 TabContents* old_contents = browser()->GetSelectedTabContents();
135 browser::NavigateParams p(MakeNavigateParams());
136 p.disposition = NEW_BACKGROUND_TAB;
[email protected]19d9f3a2010-10-14 21:49:36137 browser::Navigate(&p);
[email protected]a1feae52010-10-11 22:14:45138 TabContents* new_contents = browser()->GetSelectedTabContents();
139 // The selected tab should have remained unchanged, since the new tab was
140 // opened in the background.
141 EXPECT_EQ(old_contents, new_contents);
142 EXPECT_EQ(2, browser()->tab_count());
143}
144
145// This test verifies that when a navigation requiring a new foreground tab
146// occurs in a Browser that cannot host multiple tabs, the new foreground tab
147// is created in an existing compatible Browser.
148IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
149 Disposition_IncompatibleWindow_Existing) {
150 // Open a foreground tab in a window that cannot open popups when there is an
151 // existing compatible window somewhere else that they can be opened within.
152 Browser* popup = CreateEmptyBrowserForType(Browser::TYPE_POPUP,
153 browser()->profile());
154 browser::NavigateParams p(MakeNavigateParams(popup));
155 p.disposition = NEW_FOREGROUND_TAB;
[email protected]19d9f3a2010-10-14 21:49:36156 browser::Navigate(&p);
[email protected]a1feae52010-10-11 22:14:45157
158 // Navigate() should have opened the tab in a different browser since the
159 // one we supplied didn't support additional tabs.
160 EXPECT_NE(popup, p.browser);
161
162 // Since browser() is an existing compatible tabbed browser, it should have
163 // opened the tab there.
164 EXPECT_EQ(browser(), p.browser);
165
166 // We should be left with 2 windows, the popup with one tab and the browser()
167 // provided by the framework with two.
168 EXPECT_EQ(2u, BrowserList::size());
169 EXPECT_EQ(1, popup->tab_count());
170 EXPECT_EQ(2, browser()->tab_count());
171}
172
173// This test verifies that when a navigation requiring a new foreground tab
174// occurs in a Browser that cannot host multiple tabs and no compatible Browser
175// that can is open, a compatible Browser is created.
176IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
177 Disposition_IncompatibleWindow_NoExisting) {
178 // We want to simulate not being able to find an existing window compatible
179 // with our non-tabbed browser window so Navigate() is forced to create a
180 // new compatible window. Because browser() supplied by the in-process
181 // browser testing framework is compatible with browser()->profile(), we
182 // need a different profile, and creating a popup window with an incognito
183 // profile is a quick and dirty way of achieving this.
184 Browser* popup = CreateEmptyBrowserForType(
185 Browser::TYPE_POPUP, browser()->profile()->GetOffTheRecordProfile());
186 browser::NavigateParams p(MakeNavigateParams(popup));
187 p.disposition = NEW_FOREGROUND_TAB;
[email protected]19d9f3a2010-10-14 21:49:36188 browser::Navigate(&p);
[email protected]a1feae52010-10-11 22:14:45189
190 // Navigate() should have opened the tab in a different browser since the
191 // one we supplied didn't support additional tabs.
192 EXPECT_NE(popup, p.browser);
193
194 // This time, browser() is _not_ compatible with popup since it is not an
195 // incognito window.
196 EXPECT_NE(browser(), p.browser);
197
198 // We should have three windows, each with one tab:
199 // 1. the browser() provided by the framework (unchanged in this test)
200 // 2. the incognito popup we created originally
201 // 3. the new incognito tabbed browser that was created by Navigate().
202 EXPECT_EQ(3u, BrowserList::size());
203 EXPECT_EQ(1, browser()->tab_count());
204 EXPECT_EQ(1, popup->tab_count());
205 EXPECT_EQ(1, p.browser->tab_count());
206 EXPECT_EQ(Browser::TYPE_NORMAL, p.browser->type());
207}
208
209// This test verifies that navigating with WindowOpenDisposition = NEW_POPUP
210// from a normal Browser results in a new Browser with TYPE_POPUP.
211IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewPopup) {
212 browser::NavigateParams p(MakeNavigateParams());
213 p.disposition = NEW_POPUP;
[email protected]19d9f3a2010-10-14 21:49:36214 browser::Navigate(&p);
[email protected]a1feae52010-10-11 22:14:45215
216 // Navigate() should have opened a new popup window.
217 EXPECT_NE(browser(), p.browser);
218 EXPECT_EQ(Browser::TYPE_POPUP, p.browser->type());
219
220 // We should have two windows, the browser() provided by the framework and the
221 // new popup window.
222 EXPECT_EQ(2u, BrowserList::size());
223 EXPECT_EQ(1, browser()->tab_count());
224 EXPECT_EQ(1, p.browser->tab_count());
225}
226
227// This test verifies that navigating with WindowOpenDisposition = NEW_POPUP
228// from an app frame results in a new Browser with TYPE_APP_POPUP.
229IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
230 Disposition_NewPopupFromAppWindow) {
231 Browser* app_browser = CreateEmptyBrowserForType(Browser::TYPE_APP,
232 browser()->profile());
233 browser::NavigateParams p(MakeNavigateParams(app_browser));
234 p.disposition = NEW_POPUP;
[email protected]19d9f3a2010-10-14 21:49:36235 browser::Navigate(&p);
[email protected]a1feae52010-10-11 22:14:45236
237 // Navigate() should have opened a new popup app window.
238 EXPECT_NE(app_browser, p.browser);
239 EXPECT_NE(browser(), p.browser);
240 EXPECT_EQ(Browser::TYPE_APP_POPUP, p.browser->type());
241
242 // We should now have three windows, the app window, the app popup it created,
243 // and the original browser() provided by the framework.
244 EXPECT_EQ(3u, BrowserList::size());
245 EXPECT_EQ(1, browser()->tab_count());
246 EXPECT_EQ(1, app_browser->tab_count());
247 EXPECT_EQ(1, p.browser->tab_count());
248}
249
250// This test verifies that navigating with WindowOpenDisposition = NEW_POPUP
251// from an extension app tab results in a new Browser with TYPE_APP_POPUP.
252IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
253 Disposition_NewPopupFromExtensionApp) {
254 // TODO(beng): TBD.
255}
256
257// This test verifies that navigating with WindowOpenDisposition = NEW_WINDOW
258// always opens a new window.
259IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewWindow) {
260 browser::NavigateParams p(MakeNavigateParams());
261 p.disposition = NEW_WINDOW;
[email protected]19d9f3a2010-10-14 21:49:36262 browser::Navigate(&p);
[email protected]a1feae52010-10-11 22:14:45263
264 // Navigate() should have opened a new toplevel window.
265 EXPECT_NE(browser(), p.browser);
266 EXPECT_EQ(Browser::TYPE_NORMAL, p.browser->type());
267
268 // We should now have two windows, the browser() provided by the framework and
269 // the new normal window.
270 EXPECT_EQ(2u, BrowserList::size());
271 EXPECT_EQ(1, browser()->tab_count());
272 EXPECT_EQ(1, p.browser->tab_count());
273}
274
275// This test verifies that navigating with WindowOpenDisposition = INCOGNITO
276// opens a new incognito window if no existing incognito window is present.
277IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_Incognito) {
278 browser::NavigateParams p(MakeNavigateParams());
279 p.disposition = OFF_THE_RECORD;
[email protected]19d9f3a2010-10-14 21:49:36280 browser::Navigate(&p);
[email protected]a1feae52010-10-11 22:14:45281
282 // Navigate() should have opened a new toplevel incognito window.
283 EXPECT_NE(browser(), p.browser);
284 EXPECT_EQ(browser()->profile()->GetOffTheRecordProfile(),
285 p.browser->profile());
286
287 // We should now have two windows, the browser() provided by the framework and
288 // the new incognito window.
289 EXPECT_EQ(2u, BrowserList::size());
290 EXPECT_EQ(1, browser()->tab_count());
291 EXPECT_EQ(1, p.browser->tab_count());
292}
293
294// This test verifies that navigating with WindowOpenDisposition = INCOGNITO
295// reuses an existing incognito window when possible.
296IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_IncognitoRefocus) {
297 Browser* incognito_browser =
298 CreateEmptyBrowserForType(Browser::TYPE_NORMAL,
299 browser()->profile()->GetOffTheRecordProfile());
300 browser::NavigateParams p(MakeNavigateParams());
301 p.disposition = OFF_THE_RECORD;
[email protected]19d9f3a2010-10-14 21:49:36302 browser::Navigate(&p);
[email protected]a1feae52010-10-11 22:14:45303
304 // Navigate() should have opened a new tab in the existing incognito window.
305 EXPECT_NE(browser(), p.browser);
306 EXPECT_EQ(p.browser, incognito_browser);
307
308 // We should now have two windows, the browser() provided by the framework and
309 // the incognito window we opened earlier.
310 EXPECT_EQ(2u, BrowserList::size());
311 EXPECT_EQ(1, browser()->tab_count());
312 EXPECT_EQ(2, incognito_browser->tab_count());
313}
314
315// This test verifies that no navigation action occurs when
316// WindowOpenDisposition = SUPPRESS_OPEN.
317IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_SuppressOpen) {
318 RunSuppressTest(SUPPRESS_OPEN);
319}
320
321// This test verifies that no navigation action occurs when
322// WindowOpenDisposition = SAVE_TO_DISK.
323IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_SaveToDisk) {
324 RunSuppressTest(SAVE_TO_DISK);
325}
326
327// This test verifies that no navigation action occurs when
328// WindowOpenDisposition = IGNORE_ACTION.
329IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_IgnoreAction) {
330 RunSuppressTest(IGNORE_ACTION);
331}
332
333// This tests adding a foreground tab with a predefined TabContents.
334IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, TargetContents_ForegroundTab) {
335 browser::NavigateParams p(MakeNavigateParams());
336 p.disposition = NEW_FOREGROUND_TAB;
337 p.target_contents = CreateTabContents();
[email protected]19d9f3a2010-10-14 21:49:36338 browser::Navigate(&p);
[email protected]a1feae52010-10-11 22:14:45339
340 // Navigate() should have opened the contents in a new foreground in the
341 // current Browser.
342 EXPECT_EQ(browser(), p.browser);
343 EXPECT_EQ(browser()->GetSelectedTabContents(), p.target_contents);
344
345 // We should have one window, with two tabs.
346 EXPECT_EQ(1u, BrowserList::size());
347 EXPECT_EQ(2, browser()->tab_count());
348}
349
350#if defined(OS_WIN)
351// This tests adding a popup with a predefined TabContents.
352IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, TargetContents_Popup) {
353 browser::NavigateParams p(MakeNavigateParams());
354 p.disposition = NEW_POPUP;
355 p.target_contents = CreateTabContents();
356 p.window_bounds = gfx::Rect(10, 10, 500, 500);
[email protected]19d9f3a2010-10-14 21:49:36357 browser::Navigate(&p);
[email protected]a1feae52010-10-11 22:14:45358
359 // Navigate() should have opened a new popup window.
360 EXPECT_NE(browser(), p.browser);
361 EXPECT_EQ(Browser::TYPE_POPUP, p.browser->type());
362
363 // The web platform is weird. The window bounds specified in
364 // |p.window_bounds| are used as follows:
365 // - the origin is used to position the window
366 // - the size is used to size the TabContents of the window.
367 // As such the position of the resulting window will always match
368 // p.window_bounds.origin(), but its size will not. We need to match
369 // the size against the selected tab's view's container size.
370 // Only Windows positions the window according to |p.window_bounds.origin()| -
371 // on Mac the window is offset from the opener and on Linux it always opens
372 // at 0,0.
373 EXPECT_EQ(p.window_bounds.origin(),
374 p.browser->window()->GetRestoredBounds().origin());
375 // All platforms should respect size however provided width > 400 (Mac has a
376 // minimum window width of 400).
377 EXPECT_EQ(p.window_bounds.size(),
378 p.target_contents->view()->GetContainerSize());
379
380 // We should have two windows, the new popup and the browser() provided by the
381 // framework.
382 EXPECT_EQ(2u, BrowserList::size());
383 EXPECT_EQ(1, browser()->tab_count());
384 EXPECT_EQ(1, p.browser->tab_count());
385}
386#endif
387
388// This tests adding a tab at a specific index.
389IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Tabstrip_InsertAtIndex) {
390 // This is not meant to be a comprehensive test of whether or not the tab
391 // implementation of the browser observes the insertion index. That is
392 // covered by the unit tests for TabStripModel. This merely verifies that
393 // insertion index preference is reflected in common cases.
394 browser::NavigateParams p(MakeNavigateParams());
395 p.disposition = NEW_FOREGROUND_TAB;
396 p.tabstrip_index = 0;
397 p.tabstrip_add_types = TabStripModel::ADD_FORCE_INDEX;
[email protected]19d9f3a2010-10-14 21:49:36398 browser::Navigate(&p);
[email protected]a1feae52010-10-11 22:14:45399
400 // Navigate() should have inserted a new tab at slot 0 in the tabstrip.
401 EXPECT_EQ(browser(), p.browser);
402 EXPECT_EQ(0, browser()->tabstrip_model()->GetIndexOfTabContents(
403 static_cast<const TabContents*>(p.target_contents)));
404
405 // We should have one window - the browser() provided by the framework.
406 EXPECT_EQ(1u, BrowserList::size());
407 EXPECT_EQ(2, browser()->tab_count());
408}
409
[email protected]83de85e2010-10-12 23:05:16410} // namespace