blob: 7b03e594b24c377257f06e03c40aaff30d7a2255 [file] [log] [blame]
[email protected]fc44f242012-02-14 16:54:391// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]66791aff2014-04-29 09:45:385#import <Carbon/Carbon.h>
[email protected]fc44f242012-02-14 16:54:396#import <Cocoa/Cocoa.h>
[email protected]66791aff2014-04-29 09:45:387#import <Foundation/Foundation.h>
8#import <Foundation/NSAppleEventDescriptor.h>
9#import <objc/message.h>
10#import <objc/runtime.h>
avie4d7b6f2015-12-26 00:59:1811#include <stddef.h>
[email protected]fc44f242012-02-14 16:54:3912
Sebastien Marchandf1349f52019-01-25 03:16:4113#include "base/bind.h"
David Roger51797642018-03-20 13:29:1614#include "base/bind_helpers.h"
[email protected]fc44f242012-02-14 16:54:3915#include "base/command_line.h"
[email protected]66791aff2014-04-29 09:45:3816#include "base/mac/foundation_util.h"
[email protected]a8522032013-06-24 22:51:4617#include "base/mac/scoped_nsobject.h"
thestigaf7f4152014-10-31 23:19:1518#include "base/run_loop.h"
lgarron9e6dee22014-11-18 01:03:3919#include "base/strings/sys_string_conversions.h"
20#include "base/strings/utf_string_conversions.h"
jam3f2d3932017-04-26 20:28:5121#include "base/threading/thread_restrictions.h"
[email protected]fc44f242012-02-14 16:54:3922#include "chrome/app/chrome_command_ids.h"
23#import "chrome/browser/app_controller_mac.h"
Dominick Ng6ff51052018-07-06 05:30:2024#include "chrome/browser/apps/platform_apps/app_browsertest_util.h"
lgarron9e6dee22014-11-18 01:03:3925#include "chrome/browser/bookmarks/bookmark_model_factory.h"
[email protected]dbb03fb2014-02-15 05:36:3326#include "chrome/browser/browser_process.h"
mlerman8ae56aa2015-04-24 13:56:2727#include "chrome/browser/history/history_service_factory.h"
Trent Apted45d9ae22017-11-09 23:12:3228#include "chrome/browser/lifetime/application_lifetime.h"
lwchkg498e92492016-04-23 11:04:1229#include "chrome/browser/profiles/profile_attributes_entry.h"
30#include "chrome/browser/profiles/profile_attributes_storage.h"
[email protected]7108d912014-01-30 08:10:4531#include "chrome/browser/profiles/profile_manager.h"
[email protected]52877dbc62012-06-29 22:22:0332#include "chrome/browser/ui/browser.h"
Trent Apted45d9ae22017-11-09 23:12:3233#include "chrome/browser/ui/browser_finder.h"
[email protected]52877dbc62012-06-29 22:22:0334#include "chrome/browser/ui/browser_list.h"
thestige80821242015-09-30 23:46:0835#include "chrome/browser/ui/browser_navigator_params.h"
[email protected]ee9ccfd42013-07-23 02:31:4736#include "chrome/browser/ui/browser_window.h"
lgarron9e6dee22014-11-18 01:03:3937#include "chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.h"
mlerman8ae56aa2015-04-24 13:56:2738#include "chrome/browser/ui/cocoa/history_menu_bridge.h"
Christian Dullweber820ee5f2018-04-26 13:24:3139#include "chrome/browser/ui/cocoa/last_active_browser_cocoa.h"
lgrey92aad3c2016-12-10 01:22:1840#include "chrome/browser/ui/cocoa/test/run_loop_testing.h"
kristiparka34b247a2018-03-09 19:05:3441#include "chrome/browser/ui/search/local_ntp_test_utils.h"
[email protected]617ee962013-01-29 20:49:1242#include "chrome/browser/ui/tabs/tab_strip_model.h"
mlermane29d0032014-09-24 19:31:2643#include "chrome/browser/ui/user_manager.h"
Hector Carmonad6664a02019-08-01 01:58:4844#include "chrome/browser/ui/webui/welcome/helpers.h"
[email protected]7108d912014-01-30 08:10:4545#include "chrome/common/chrome_constants.h"
46#include "chrome/common/chrome_switches.h"
47#include "chrome/common/pref_names.h"
[email protected]66791aff2014-04-29 09:45:3848#include "chrome/common/url_constants.h"
[email protected]fc44f242012-02-14 16:54:3949#include "chrome/test/base/in_process_browser_test.h"
erikchen600f7962014-12-12 00:17:3850#include "chrome/test/base/ui_test_utils.h"
tapted574f09c2015-05-19 13:08:0851#include "components/bookmarks/browser/bookmark_model.h"
lgarron9e6dee22014-11-18 01:03:3952#include "components/bookmarks/test/bookmark_test_helpers.h"
brettwb1fc1b82016-02-02 00:19:0853#include "components/prefs/pref_service.h"
tmartino82e55782017-01-10 22:30:1754#include "content/public/browser/navigation_controller.h"
[email protected]fc44f242012-02-14 16:54:3955#include "content/public/browser/web_contents.h"
erikchen600f7962014-12-12 00:17:3856#include "content/public/test/browser_test_utils.h"
erikchen19ee3922014-10-31 19:14:2257#include "content/public/test/test_navigation_observer.h"
hashimotoad3c6872014-08-29 09:46:5758#include "extensions/browser/app_window/app_window_registry.h"
[email protected]e4452d32013-11-15 23:07:4159#include "extensions/common/extension.h"
lfg910f2f92014-09-19 05:31:0960#include "extensions/test/extension_test_message_listener.h"
[email protected]66791aff2014-04-29 09:45:3861#include "net/test/embedded_test_server/embedded_test_server.h"
Trent Apted45d9ae22017-11-09 23:12:3262#import "ui/events/test/cocoa_test_event_utils.h"
[email protected]66791aff2014-04-29 09:45:3863
Adam Riceff26dcf2017-08-14 05:01:5264using base::SysUTF16ToNSString;
65
Elly Fong-Jones3ef60b752019-11-12 19:02:0366@interface AppController (ForTesting)
67- (void)getUrl:(NSAppleEventDescriptor*)event
68 withReply:(NSAppleEventDescriptor*)reply;
69@end
70
[email protected]66791aff2014-04-29 09:45:3871namespace {
72
Scott Violet1f106b582017-07-12 15:49:5873GURL g_open_shortcut_url = GURL::EmptyGURL();
[email protected]66791aff2014-04-29 09:45:3874
erikchen19ee3922014-10-31 19:14:2275// Returns an Apple Event that instructs the application to open |url|.
76NSAppleEventDescriptor* AppleEventToOpenUrl(const GURL& url) {
77 NSAppleEventDescriptor* shortcut_event = [[[NSAppleEventDescriptor alloc]
78 initWithEventClass:kASAppleScriptSuite
79 eventID:kASSubroutineEvent
80 targetDescriptor:nil
81 returnID:kAutoGenerateReturnID
82 transactionID:kAnyTransactionID] autorelease];
83 NSString* url_string = [NSString stringWithUTF8String:url.spec().c_str()];
84 [shortcut_event setParamDescriptor:[NSAppleEventDescriptor
85 descriptorWithString:url_string]
86 forKeyword:keyDirectObject];
87 return shortcut_event;
88}
89
90// Instructs the NSApp's delegate to open |url|.
91void SendAppleEventToOpenUrlToAppController(const GURL& url) {
92 AppController* controller =
93 base::mac::ObjCCast<AppController>([NSApp delegate]);
Elly Fong-Jones3ef60b752019-11-12 19:02:0394 [controller getUrl:AppleEventToOpenUrl(url) withReply:nullptr];
erikchen19ee3922014-10-31 19:14:2295}
96
mlerman8ae56aa2015-04-24 13:56:2797void RunClosureWhenProfileInitialized(const base::Closure& closure,
98 Profile* profile,
99 Profile::CreateStatus status) {
100 if (status == Profile::CREATE_STATUS_INITIALIZED)
101 closure.Run();
102}
103
[email protected]66791aff2014-04-29 09:45:38104} // namespace
105
106@interface TestOpenShortcutOnStartup : NSObject
107- (void)applicationWillFinishLaunching:(NSNotification*)notification;
108@end
109
110@implementation TestOpenShortcutOnStartup
111
112- (void)applicationWillFinishLaunching:(NSNotification*)notification {
Scott Violet1f106b582017-07-12 15:49:58113 if (!g_open_shortcut_url.is_valid())
114 return;
115
erikchen19ee3922014-10-31 19:14:22116 SendAppleEventToOpenUrlToAppController(g_open_shortcut_url);
[email protected]66791aff2014-04-29 09:45:38117}
118
119@end
[email protected]fc44f242012-02-14 16:54:39120
121namespace {
122
Trent Apted45d9ae22017-11-09 23:12:32123using AppControllerBrowserTest = InProcessBrowserTest;
124
Elly Fong-Jones85046032018-04-19 19:15:28125// Returns whether a window's pixels are actually on the screen, which is the
126// case when it and all of its parents are marked visible.
127bool IsReallyVisible(NSWindow* window) {
128 while (window) {
129 if (!window.visible)
130 return false;
131 window = [window parentWindow];
132 }
133 return true;
134}
135
Trent Apted45d9ae22017-11-09 23:12:32136size_t CountVisibleWindows() {
137 size_t count = 0;
138 for (NSWindow* w in [NSApp windows])
Elly Fong-Jones85046032018-04-19 19:15:28139 count = count + (IsReallyVisible(w) ? 1 : 0);
Trent Apted45d9ae22017-11-09 23:12:32140 return count;
141}
142
Elly Fong-Jones85046032018-04-19 19:15:28143// Returns how many visible NSWindows are expected for a given count of browser
Sidney San Martínb247d53f2018-05-23 02:31:21144// windows.
Elly Fong-Jones85046032018-04-19 19:15:28145size_t ExpectedWindowCountForBrowserCount(size_t browsers) {
Elly Fong-Jones85046032018-04-19 19:15:28146 return browsers;
147}
148
Trent Apted45d9ae22017-11-09 23:12:32149// Test browser shutdown with a command in the message queue.
150IN_PROC_BROWSER_TEST_F(AppControllerBrowserTest, CommandDuringShutdown) {
151 EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
Elly Fong-Jones85046032018-04-19 19:15:28152 EXPECT_EQ(ExpectedWindowCountForBrowserCount(1), CountVisibleWindows());
Trent Apted45d9ae22017-11-09 23:12:32153
154 chrome::AttemptExit(); // Set chrome::IsTryingToQuit and close all windows.
155
156 // Opening a new window here is fine (unload handlers can also interrupt
157 // exit). But closing the window posts an autorelease on
158 // BrowserWindowController, which calls ~Browser() and, if that was the last
159 // Browser, it invokes applicationWillTerminate: (because IsTryingToQuit is
160 // set). So, verify assumptions then process that autorelease.
161
162 EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
Elly Fong-Jones85046032018-04-19 19:15:28163 EXPECT_EQ(ExpectedWindowCountForBrowserCount(0), CountVisibleWindows());
Trent Apted45d9ae22017-11-09 23:12:32164
165 base::RunLoop().RunUntilIdle();
166
167 EXPECT_EQ(0u, chrome::GetTotalBrowserCount());
Elly Fong-Jones85046032018-04-19 19:15:28168 EXPECT_EQ(ExpectedWindowCountForBrowserCount(0), CountVisibleWindows());
Trent Apted45d9ae22017-11-09 23:12:32169
170 NSEvent* cmd_n = cocoa_test_event_utils::KeyEventWithKeyCode(
171 'n', 'n', NSKeyDown, NSCommandKeyMask);
172 [[NSApp mainMenu] performSelector:@selector(performKeyEquivalent:)
173 withObject:cmd_n
174 afterDelay:0];
175 // Let the run loop get flushed, during process cleanup and try not to crash.
176}
177
[email protected]ee9ccfd42013-07-23 02:31:47178class AppControllerPlatformAppBrowserTest
179 : public extensions::PlatformAppBrowserTest {
[email protected]fc44f242012-02-14 16:54:39180 protected:
[email protected]b4207c42013-02-12 06:44:20181 AppControllerPlatformAppBrowserTest()
scottmg0d8e4ab2016-01-28 00:34:55182 : active_browser_list_(BrowserList::GetInstance()) {}
[email protected]fc44f242012-02-14 16:54:39183
avi3ef9ec9e2014-12-22 22:50:17184 void SetUpCommandLine(base::CommandLine* command_line) override {
[email protected]ee9ccfd42013-07-23 02:31:47185 PlatformAppBrowserTest::SetUpCommandLine(command_line);
[email protected]fc44f242012-02-14 16:54:39186 command_line->AppendSwitchASCII(switches::kAppId,
187 "1234");
188 }
[email protected]b4207c42013-02-12 06:44:20189
[email protected]7d1a810b2013-06-26 19:51:59190 const BrowserList* active_browser_list_;
[email protected]fc44f242012-02-14 16:54:39191};
192
193// Test that if only a platform app window is open and no browser windows are
194// open then a reopen event does nothing.
195IN_PROC_BROWSER_TEST_F(AppControllerPlatformAppBrowserTest,
196 PlatformAppReopenWithWindows) {
Owen Minb6e1bf292018-03-15 18:31:52197 AppController* ac = base::mac::ObjCCast<AppController>(
198 [[NSApplication sharedApplication] delegate]);
199 ASSERT_TRUE(ac);
200
[email protected]fc44f242012-02-14 16:54:39201 NSUInteger old_window_count = [[NSApp windows] count];
[email protected]7d1a810b2013-06-26 19:51:59202 EXPECT_EQ(1u, active_browser_list_->size());
[email protected]a25920ee2013-09-05 19:38:49203 [ac applicationShouldHandleReopen:NSApp hasVisibleWindows:YES];
204 // We do not EXPECT_TRUE the result here because the method
205 // deminiaturizes windows manually rather than return YES and have
206 // AppKit do it.
[email protected]fc44f242012-02-14 16:54:39207
[email protected]fc44f242012-02-14 16:54:39208 EXPECT_EQ(old_window_count, [[NSApp windows] count]);
[email protected]7d1a810b2013-06-26 19:51:59209 EXPECT_EQ(1u, active_browser_list_->size());
[email protected]fc44f242012-02-14 16:54:39210}
211
[email protected]2e29e2232013-07-26 10:40:59212IN_PROC_BROWSER_TEST_F(AppControllerPlatformAppBrowserTest,
213 ActivationFocusesBrowserWindow) {
Owen Minb6e1bf292018-03-15 18:31:52214 AppController* app_controller = base::mac::ObjCCast<AppController>(
215 [[NSApplication sharedApplication] delegate]);
216 ASSERT_TRUE(app_controller);
[email protected]2e29e2232013-07-26 10:40:59217
218 ExtensionTestMessageListener listener("Launched", false);
219 const extensions::Extension* app =
220 InstallAndLaunchPlatformApp("minimal");
221 ASSERT_TRUE(listener.WaitUntilSatisfied());
222
hashimotoad3c6872014-08-29 09:46:57223 NSWindow* app_window = extensions::AppWindowRegistry::Get(profile())
[email protected]dbb03fb2014-02-15 05:36:33224 ->GetAppWindowsForApp(app->id())
225 .front()
Christopher Cameron359c61e22018-10-18 08:06:20226 ->GetNativeWindow()
227 .GetNativeNSWindow();
228 NSWindow* browser_window =
229 browser()->window()->GetNativeWindow().GetNativeNSWindow();
[email protected]2e29e2232013-07-26 10:40:59230
andybons346c7c62015-08-13 15:18:03231 chrome::testing::NSRunLoopRunAllPending();
[email protected]2e29e2232013-07-26 10:40:59232 EXPECT_LE([[NSApp orderedWindows] indexOfObject:app_window],
233 [[NSApp orderedWindows] indexOfObject:browser_window]);
234 [app_controller applicationShouldHandleReopen:NSApp
235 hasVisibleWindows:YES];
andybons346c7c62015-08-13 15:18:03236 chrome::testing::NSRunLoopRunAllPending();
[email protected]2e29e2232013-07-26 10:40:59237 EXPECT_LE([[NSApp orderedWindows] indexOfObject:browser_window],
238 [[NSApp orderedWindows] indexOfObject:app_window]);
239}
240
[email protected]fc44f242012-02-14 16:54:39241class AppControllerWebAppBrowserTest : public InProcessBrowserTest {
242 protected:
[email protected]b4207c42013-02-12 06:44:20243 AppControllerWebAppBrowserTest()
scottmg0d8e4ab2016-01-28 00:34:55244 : active_browser_list_(BrowserList::GetInstance()) {}
[email protected]fc44f242012-02-14 16:54:39245
avi3ef9ec9e2014-12-22 22:50:17246 void SetUpCommandLine(base::CommandLine* command_line) override {
[email protected]90ca44272012-07-18 18:15:48247 command_line->AppendSwitchASCII(switches::kApp, GetAppURL());
[email protected]fc44f242012-02-14 16:54:39248 }
249
250 std::string GetAppURL() const {
251 return "http://example.com/";
252 }
[email protected]b4207c42013-02-12 06:44:20253
[email protected]7d1a810b2013-06-26 19:51:59254 const BrowserList* active_browser_list_;
[email protected]fc44f242012-02-14 16:54:39255};
256
257// Test that in web app mode a reopen event opens the app URL.
258IN_PROC_BROWSER_TEST_F(AppControllerWebAppBrowserTest,
259 WebAppReopenWithNoWindows) {
Owen Minb6e1bf292018-03-15 18:31:52260 AppController* ac = base::mac::ObjCCast<AppController>(
261 [[NSApplication sharedApplication] delegate]);
262 ASSERT_TRUE(ac);
263
[email protected]7d1a810b2013-06-26 19:51:59264 EXPECT_EQ(1u, active_browser_list_->size());
[email protected]fc44f242012-02-14 16:54:39265 BOOL result = [ac applicationShouldHandleReopen:NSApp hasVisibleWindows:NO];
266
267 EXPECT_FALSE(result);
[email protected]7d1a810b2013-06-26 19:51:59268 EXPECT_EQ(2u, active_browser_list_->size());
[email protected]fc44f242012-02-14 16:54:39269
[email protected]7d1a810b2013-06-26 19:51:59270 Browser* browser = active_browser_list_->get(0);
[email protected]617ee962013-01-29 20:49:12271 GURL current_url =
272 browser->tab_strip_model()->GetActiveWebContents()->GetURL();
[email protected]fc44f242012-02-14 16:54:39273 EXPECT_EQ(GetAppURL(), current_url.spec());
274}
275
[email protected]7108d912014-01-30 08:10:45276// Called when the ProfileManager has created a profile.
277void CreateProfileCallback(const base::Closure& quit_closure,
278 Profile* profile,
279 Profile::CreateStatus status) {
280 EXPECT_TRUE(profile);
281 EXPECT_NE(Profile::CREATE_STATUS_LOCAL_FAIL, status);
282 EXPECT_NE(Profile::CREATE_STATUS_REMOTE_FAIL, status);
283 // This will be called multiple times. Wait until the profile is initialized
284 // fully to quit the loop.
285 if (status == Profile::CREATE_STATUS_INITIALIZED)
286 quit_closure.Run();
287}
288
mlermanb8df6e82015-01-23 19:55:34289void CreateAndWaitForSystemProfile() {
[email protected]7108d912014-01-30 08:10:45290 ProfileManager::CreateCallback create_callback =
291 base::Bind(&CreateProfileCallback,
Gabriel Charette87f2bef72018-05-17 20:37:53292 base::RunLoop::QuitCurrentWhenIdleClosureDeprecated());
[email protected]7108d912014-01-30 08:10:45293 g_browser_process->profile_manager()->CreateProfileAsync(
mlermanb8df6e82015-01-23 19:55:34294 ProfileManager::GetSystemProfilePath(),
[email protected]7108d912014-01-30 08:10:45295 create_callback,
296 base::string16(),
[email protected]7108d912014-01-30 08:10:45297 std::string());
298 base::RunLoop().Run();
299}
300
301class AppControllerNewProfileManagementBrowserTest
302 : public InProcessBrowserTest {
303 protected:
304 AppControllerNewProfileManagementBrowserTest()
scottmg0d8e4ab2016-01-28 00:34:55305 : active_browser_list_(BrowserList::GetInstance()) {}
[email protected]7108d912014-01-30 08:10:45306
[email protected]7108d912014-01-30 08:10:45307 const BrowserList* active_browser_list_;
308};
309
310// Test that for a regular last profile, a reopen event opens a browser.
311IN_PROC_BROWSER_TEST_F(AppControllerNewProfileManagementBrowserTest,
312 RegularProfileReopenWithNoWindows) {
Owen Minb6e1bf292018-03-15 18:31:52313 AppController* ac = base::mac::ObjCCast<AppController>(
314 [[NSApplication sharedApplication] delegate]);
315 ASSERT_TRUE(ac);
316
[email protected]7108d912014-01-30 08:10:45317 EXPECT_EQ(1u, active_browser_list_->size());
318 BOOL result = [ac applicationShouldHandleReopen:NSApp hasVisibleWindows:NO];
319
320 EXPECT_FALSE(result);
321 EXPECT_EQ(2u, active_browser_list_->size());
mlermane29d0032014-09-24 19:31:26322 EXPECT_FALSE(UserManager::IsShowing());
[email protected]7108d912014-01-30 08:10:45323}
324
325// Test that for a locked last profile, a reopen event opens the User Manager.
326IN_PROC_BROWSER_TEST_F(AppControllerNewProfileManagementBrowserTest,
327 LockedProfileReopenWithNoWindows) {
mlermanb8df6e82015-01-23 19:55:34328 // The User Manager uses the system profile as its underlying profile. To
[email protected]7108d912014-01-30 08:10:45329 // minimize flakiness due to the scheduling/descheduling of tasks on the
330 // different threads, pre-initialize the guest profile before it is needed.
mlermanb8df6e82015-01-23 19:55:34331 CreateAndWaitForSystemProfile();
Owen Minb6e1bf292018-03-15 18:31:52332 AppController* ac = base::mac::ObjCCast<AppController>(
333 [[NSApplication sharedApplication] delegate]);
334 ASSERT_TRUE(ac);
[email protected]7108d912014-01-30 08:10:45335
336 // Lock the active profile.
Francois Doraye6fb2d02017-10-18 21:29:13337 base::ScopedAllowBlockingForTesting allow_blocking;
[email protected]7108d912014-01-30 08:10:45338 Profile* profile = [ac lastProfile];
lwchkg9c183942016-03-13 06:29:54339 ProfileAttributesEntry* entry;
340 ASSERT_TRUE(g_browser_process->profile_manager()->
341 GetProfileAttributesStorage().
342 GetProfileAttributesWithPath(profile->GetPath(), &entry));
343 entry->SetIsSigninRequired(true);
344 EXPECT_TRUE(entry->IsSigninRequired());
[email protected]7108d912014-01-30 08:10:45345
346 EXPECT_EQ(1u, active_browser_list_->size());
347 BOOL result = [ac applicationShouldHandleReopen:NSApp hasVisibleWindows:NO];
348 EXPECT_FALSE(result);
349
350 base::RunLoop().RunUntilIdle();
351 EXPECT_EQ(1u, active_browser_list_->size());
mlermane29d0032014-09-24 19:31:26352 EXPECT_TRUE(UserManager::IsShowing());
353 UserManager::Hide();
[email protected]7108d912014-01-30 08:10:45354}
355
Owen Minb6e1bf292018-03-15 18:31:52356// Test that for a guest last profile, commandDispatch should open UserManager
357// if guest mode is disabled. Note that this test might be flaky under ASAN
358// due to https://crbug.com/674475. Please disable this test under ASAN
359// as the tests below if that happened.
360IN_PROC_BROWSER_TEST_F(AppControllerNewProfileManagementBrowserTest,
361 OpenGuestProfileOnlyIfGuestModeIsEnabled) {
362 CreateAndWaitForSystemProfile();
363 PrefService* local_state = g_browser_process->local_state();
364 local_state->SetString(prefs::kProfileLastUsed, chrome::kGuestProfileDir);
365 local_state->SetBoolean(prefs::kBrowserGuestModeEnabled, false);
366
367 AppController* ac = base::mac::ObjCCast<AppController>(
368 [[NSApplication sharedApplication] delegate]);
369 ASSERT_TRUE(ac);
370
371 base::ScopedAllowBlockingForTesting allow_blocking;
372 Profile* profile = [ac lastProfile];
373 EXPECT_TRUE(profile->IsGuestSession());
374
375 NSMenu* menu = [ac applicationDockMenu:NSApp];
376 ASSERT_TRUE(menu);
377 NSMenuItem* item = [menu itemWithTag:IDC_NEW_WINDOW];
378 ASSERT_TRUE(item);
379 EXPECT_EQ(1u, active_browser_list_->size());
380
381 [ac commandDispatch:item];
382
383 base::RunLoop().RunUntilIdle();
384
385 EXPECT_EQ(1u, active_browser_list_->size());
386 EXPECT_TRUE(UserManager::IsShowing());
387 UserManager::Hide();
388
389 local_state->SetBoolean(prefs::kBrowserGuestModeEnabled, true);
390 [ac commandDispatch:item];
391 base::RunLoop().RunUntilIdle();
392 EXPECT_EQ(2u, active_browser_list_->size());
393 EXPECT_FALSE(UserManager::IsShowing());
394}
395
[email protected]7108d912014-01-30 08:10:45396// Test that for a guest last profile, a reopen event opens the User Manager.
397IN_PROC_BROWSER_TEST_F(AppControllerNewProfileManagementBrowserTest,
Elly Fong-Jones76aa43c2019-08-20 18:19:31398 GuestProfileReopenWithNoWindows) {
mlermanb8df6e82015-01-23 19:55:34399 // Create the system profile. Set the guest as the last used profile so the
[email protected]7108d912014-01-30 08:10:45400 // app controller can use it on init.
mlermanb8df6e82015-01-23 19:55:34401 CreateAndWaitForSystemProfile();
[email protected]7108d912014-01-30 08:10:45402 PrefService* local_state = g_browser_process->local_state();
403 local_state->SetString(prefs::kProfileLastUsed, chrome::kGuestProfileDir);
404
Owen Minb6e1bf292018-03-15 18:31:52405 AppController* ac = base::mac::ObjCCast<AppController>(
406 [[NSApplication sharedApplication] delegate]);
407 ASSERT_TRUE(ac);
[email protected]7108d912014-01-30 08:10:45408
Francois Doraye6fb2d02017-10-18 21:29:13409 base::ScopedAllowBlockingForTesting allow_blocking;
[email protected]7108d912014-01-30 08:10:45410 Profile* profile = [ac lastProfile];
411 EXPECT_EQ(ProfileManager::GetGuestProfilePath(), profile->GetPath());
412 EXPECT_TRUE(profile->IsGuestSession());
413
414 EXPECT_EQ(1u, active_browser_list_->size());
415 BOOL result = [ac applicationShouldHandleReopen:NSApp hasVisibleWindows:NO];
416 EXPECT_FALSE(result);
417
418 base::RunLoop().RunUntilIdle();
419
420 EXPECT_EQ(1u, active_browser_list_->size());
mlermane29d0032014-09-24 19:31:26421 EXPECT_TRUE(UserManager::IsShowing());
422 UserManager::Hide();
[email protected]7108d912014-01-30 08:10:45423}
424
mlermane6e040a2014-10-31 00:53:21425IN_PROC_BROWSER_TEST_F(AppControllerNewProfileManagementBrowserTest,
Elly Fong-Joneseb853802019-08-21 17:09:56426 AboutChromeForcesUserManager) {
Owen Minb6e1bf292018-03-15 18:31:52427 AppController* ac = base::mac::ObjCCast<AppController>(
428 [[NSApplication sharedApplication] delegate]);
429 ASSERT_TRUE(ac);
mlermane6e040a2014-10-31 00:53:21430
431 // Create the guest profile, and set it as the last used profile so the
432 // app controller can use it on init.
mlermanb8df6e82015-01-23 19:55:34433 CreateAndWaitForSystemProfile();
mlermane6e040a2014-10-31 00:53:21434 PrefService* local_state = g_browser_process->local_state();
435 local_state->SetString(prefs::kProfileLastUsed, chrome::kGuestProfileDir);
436
437 // Prohibiting guest mode forces the user manager flow for About Chrome.
438 local_state->SetBoolean(prefs::kBrowserGuestModeEnabled, false);
439
Francois Doraye6fb2d02017-10-18 21:29:13440 base::ScopedAllowBlockingForTesting allow_blocking;
mlermane6e040a2014-10-31 00:53:21441 Profile* guest_profile = [ac lastProfile];
442 EXPECT_EQ(ProfileManager::GetGuestProfilePath(), guest_profile->GetPath());
443 EXPECT_TRUE(guest_profile->IsGuestSession());
444
445 // Tell the browser to open About Chrome.
446 EXPECT_EQ(1u, active_browser_list_->size());
447 [ac orderFrontStandardAboutPanel:NSApp];
448
449 base::RunLoop().RunUntilIdle();
450
451 // No new browser is opened; the User Manager opens instead.
452 EXPECT_EQ(1u, active_browser_list_->size());
453 EXPECT_TRUE(UserManager::IsShowing());
454
455 UserManager::Hide();
456}
457
[email protected]66791aff2014-04-29 09:45:38458class AppControllerOpenShortcutBrowserTest : public InProcessBrowserTest {
459 protected:
460 AppControllerOpenShortcutBrowserTest() {
Hector Carmona9797cc62019-08-09 20:35:35461 scoped_feature_list_.InitWithFeatures({welcome::kForceEnabled}, {});
[email protected]66791aff2014-04-29 09:45:38462 }
463
Daniel Chenga542fca2014-10-21 09:51:29464 void SetUpInProcessBrowserTestFixture() override {
[email protected]66791aff2014-04-29 09:45:38465 // In order to mimic opening shortcut during browser startup, we need to
466 // send the event before -applicationDidFinishLaunching is called, but
467 // after AppController is loaded.
468 //
469 // Since -applicationWillFinishLaunching does nothing now, we swizzle it to
470 // our function to send the event. We need to do this early before running
471 // the main message loop.
472 //
473 // NSApp does not exist yet. We need to get the AppController using
474 // reflection.
475 Class appControllerClass = NSClassFromString(@"AppController");
476 Class openShortcutClass = NSClassFromString(@"TestOpenShortcutOnStartup");
477
478 ASSERT_TRUE(appControllerClass != nil);
479 ASSERT_TRUE(openShortcutClass != nil);
480
481 SEL targetMethod = @selector(applicationWillFinishLaunching:);
482 Method original = class_getInstanceMethod(appControllerClass,
483 targetMethod);
484 Method destination = class_getInstanceMethod(openShortcutClass,
485 targetMethod);
486
487 ASSERT_TRUE(original != NULL);
488 ASSERT_TRUE(destination != NULL);
489
490 method_exchangeImplementations(original, destination);
Scott Violet1f106b582017-07-12 15:49:58491
492 ASSERT_TRUE(embedded_test_server()->Start());
493 g_open_shortcut_url = embedded_test_server()->GetURL("/simple.html");
[email protected]66791aff2014-04-29 09:45:38494 }
495
avi3ef9ec9e2014-12-22 22:50:17496 void SetUpCommandLine(base::CommandLine* command_line) override {
[email protected]66791aff2014-04-29 09:45:38497 // If the arg is empty, PrepareTestCommandLine() after this function will
498 // append about:blank as default url.
499 command_line->AppendArg(chrome::kChromeUINewTabURL);
500 }
Hector Carmona1e62e352019-06-24 19:18:17501
502 private:
503 base::test::ScopedFeatureList scoped_feature_list_;
[email protected]66791aff2014-04-29 09:45:38504};
505
506IN_PROC_BROWSER_TEST_F(AppControllerOpenShortcutBrowserTest,
507 OpenShortcutOnStartup) {
tmartino82e55782017-01-10 22:30:17508 // The two tabs expected are the Welcome page and the desired URL.
509 EXPECT_EQ(2, browser()->tab_strip_model()->count());
[email protected]66791aff2014-04-29 09:45:38510 EXPECT_EQ(g_open_shortcut_url,
511 browser()->tab_strip_model()->GetActiveWebContents()
512 ->GetLastCommittedURL());
513}
514
erikchen19ee3922014-10-31 19:14:22515class AppControllerReplaceNTPBrowserTest : public InProcessBrowserTest {
516 protected:
517 AppControllerReplaceNTPBrowserTest() {}
518
519 void SetUpInProcessBrowserTestFixture() override {
svaldeza01f7d92015-11-18 17:47:56520 ASSERT_TRUE(embedded_test_server()->Start());
erikchen19ee3922014-10-31 19:14:22521 }
522
avi3ef9ec9e2014-12-22 22:50:17523 void SetUpCommandLine(base::CommandLine* command_line) override {
erikchen19ee3922014-10-31 19:14:22524 // If the arg is empty, PrepareTestCommandLine() after this function will
525 // append about:blank as default url.
526 command_line->AppendArg(chrome::kChromeUINewTabURL);
527 }
528};
529
530// Tests that when a GURL is opened after startup, it replaces the NTP.
531IN_PROC_BROWSER_TEST_F(AppControllerReplaceNTPBrowserTest,
532 ReplaceNTPAfterStartup) {
kristiparka34b247a2018-03-09 19:05:34533 // Depending on network connectivity, the NTP URL can either be
534 // chrome://newtab/ or chrome-search://local-ntp/local-ntp.html. See
535 // local_ntp_test_utils::GetFinalNtpUrl for more details.
536 std::string expected_url =
537 local_ntp_test_utils::GetFinalNtpUrl(browser()->profile()).spec();
538
erikchen19ee3922014-10-31 19:14:22539 // Ensure that there is exactly 1 tab showing, and the tab is the NTP.
kristiparka34b247a2018-03-09 19:05:34540 GURL ntp(expected_url);
erikchen19ee3922014-10-31 19:14:22541 EXPECT_EQ(1, browser()->tab_strip_model()->count());
tmartino82e55782017-01-10 22:30:17542 browser()->tab_strip_model()->GetActiveWebContents()->GetController().LoadURL(
kristiparka34b247a2018-03-09 19:05:34543 GURL(expected_url), content::Referrer(),
tmartino82e55782017-01-10 22:30:17544 ui::PageTransition::PAGE_TRANSITION_LINK, std::string());
545
546 // Wait for one navigation on the active web contents.
547 content::TestNavigationObserver ntp_navigation_observer(
548 browser()->tab_strip_model()->GetActiveWebContents());
549 ntp_navigation_observer.Wait();
550
erikchen19ee3922014-10-31 19:14:22551 EXPECT_EQ(ntp,
552 browser()
553 ->tab_strip_model()
554 ->GetActiveWebContents()
555 ->GetLastCommittedURL());
556
557 GURL simple(embedded_test_server()->GetURL("/simple.html"));
558 SendAppleEventToOpenUrlToAppController(simple);
559
erikchen19ee3922014-10-31 19:14:22560 EXPECT_EQ(1, browser()->tab_strip_model()->count());
tmartino82e55782017-01-10 22:30:17561 content::TestNavigationObserver event_navigation_observer(
562 browser()->tab_strip_model()->GetActiveWebContents());
563 event_navigation_observer.Wait();
erikchen19ee3922014-10-31 19:14:22564
565 EXPECT_EQ(simple,
566 browser()
567 ->tab_strip_model()
568 ->GetActiveWebContents()
569 ->GetLastCommittedURL());
570}
571
Christian Dullweber820ee5f2018-04-26 13:24:31572// Tests that when a GURL is opened, it is not opened in incognito mode.
573IN_PROC_BROWSER_TEST_F(AppControllerBrowserTest, OpenInRegularBrowser) {
574 ASSERT_TRUE(embedded_test_server()->Start());
575 // Create an incognito browser.
576 Browser* incognito_browser = CreateIncognitoBrowser(browser()->profile());
577 EXPECT_EQ(incognito_browser, chrome::GetLastActiveBrowser());
578 EXPECT_EQ(1, browser()->tab_strip_model()->count());
579 EXPECT_EQ(1, incognito_browser->tab_strip_model()->count());
580 // Open a url.
581 GURL simple(embedded_test_server()->GetURL("/simple.html"));
582 SendAppleEventToOpenUrlToAppController(simple);
583 // It should be opened in the regular browser.
584 content::TestNavigationObserver event_navigation_observer(
585 browser()->tab_strip_model()->GetActiveWebContents());
586 event_navigation_observer.Wait();
587 EXPECT_EQ(2, browser()->tab_strip_model()->count());
588 EXPECT_EQ(1, incognito_browser->tab_strip_model()->count());
589 EXPECT_EQ(simple, browser()
590 ->tab_strip_model()
591 ->GetActiveWebContents()
592 ->GetLastCommittedURL());
593}
594
lgarron9e6dee22014-11-18 01:03:39595class AppControllerMainMenuBrowserTest : public InProcessBrowserTest {
596 protected:
597 AppControllerMainMenuBrowserTest() {
598 }
599};
600
601IN_PROC_BROWSER_TEST_F(AppControllerMainMenuBrowserTest,
mlerman8ae56aa2015-04-24 13:56:27602 HistoryMenuResetAfterProfileDeletion) {
603 ProfileManager* profile_manager = g_browser_process->profile_manager();
tapted676995d2016-04-18 11:32:29604 AppController* ac =
605 base::mac::ObjCCastStrict<AppController>([NSApp delegate]);
mlerman8ae56aa2015-04-24 13:56:27606
607 // Use the existing profile as profile 1.
608 Profile* profile1 = browser()->profile();
609
610 // Create profile 2.
611 base::FilePath profile2_path =
612 profile_manager->GenerateNextProfileDirectoryPath();
613 base::RunLoop run_loop;
614 profile_manager->CreateProfileAsync(
615 profile2_path,
616 base::Bind(&RunClosureWhenProfileInitialized,
617 run_loop.QuitClosure()),
lwchkg1f62d242015-10-29 00:50:43618 base::string16(),
lwchkg1f62d242015-10-29 00:50:43619 std::string());
mlerman8ae56aa2015-04-24 13:56:27620 run_loop.Run();
621 Profile* profile2 = profile_manager->GetProfileByPath(profile2_path);
622 ASSERT_TRUE(profile2);
623
Sidney San Martínaa3b48f2018-06-03 08:10:05624 // Load profile1's History Service backend so it will be assigned to the
625 // HistoryMenuBridge when windowChangedToProfile is called, or else this test
626 // will fail flaky.
627 ui_test_utils::WaitForHistoryToLoad(HistoryServiceFactory::GetForProfile(
628 profile1, ServiceAccessType::EXPLICIT_ACCESS));
mlerman8ae56aa2015-04-24 13:56:27629 // Switch the controller to profile1.
630 [ac windowChangedToProfile:profile1];
631 base::RunLoop().RunUntilIdle();
632
633 // Verify the controller's History Menu corresponds to profile1.
634 EXPECT_TRUE([ac historyMenuBridge]->service());
635 EXPECT_EQ([ac historyMenuBridge]->service(),
636 HistoryServiceFactory::GetForProfile(profile1,
637 ServiceAccessType::EXPLICIT_ACCESS));
638
639 // Load profile2's History Service backend so it will be assigned to the
640 // HistoryMenuBridge when windowChangedToProfile is called, or else this test
641 // will fail flaky.
642 ui_test_utils::WaitForHistoryToLoad(
643 HistoryServiceFactory::GetForProfile(profile2,
644 ServiceAccessType::EXPLICIT_ACCESS));
645 // Switch the controller to profile2.
646 [ac windowChangedToProfile:profile2];
647 base::RunLoop().RunUntilIdle();
648
649 // Verify the controller's History Menu has changed.
650 EXPECT_TRUE([ac historyMenuBridge]->service());
651 EXPECT_EQ([ac historyMenuBridge]->service(),
652 HistoryServiceFactory::GetForProfile(profile2,
653 ServiceAccessType::EXPLICIT_ACCESS));
654 EXPECT_NE(
655 HistoryServiceFactory::GetForProfile(profile1,
656 ServiceAccessType::EXPLICIT_ACCESS),
657 HistoryServiceFactory::GetForProfile(profile2,
658 ServiceAccessType::EXPLICIT_ACCESS));
659
660 // Delete profile2.
David Roger51797642018-03-20 13:29:16661 profile_manager->ScheduleProfileForDeletion(profile2->GetPath(),
662 base::DoNothing());
mlerman8ae56aa2015-04-24 13:56:27663 base::RunLoop().RunUntilIdle();
664
665 // Verify the controller's history is back to profile1.
666 EXPECT_EQ([ac historyMenuBridge]->service(),
667 HistoryServiceFactory::GetForProfile(profile1,
668 ServiceAccessType::EXPLICIT_ACCESS));
669}
670
671IN_PROC_BROWSER_TEST_F(AppControllerMainMenuBrowserTest,
lgarron9e6dee22014-11-18 01:03:39672 BookmarksMenuIsRestoredAfterProfileSwitch) {
673 ProfileManager* profile_manager = g_browser_process->profile_manager();
Owen Minb6e1bf292018-03-15 18:31:52674 AppController* ac = base::mac::ObjCCast<AppController>(
675 [[NSApplication sharedApplication] delegate]);
676 ASSERT_TRUE(ac);
677
Robert Sesek124f80f92018-07-24 20:31:29678 [ac mainMenuCreated];
lgarron9e6dee22014-11-18 01:03:39679
680 // Constants for bookmarks that we will create later.
681 const base::string16 title1(base::ASCIIToUTF16("Dinosaur Comics"));
682 const GURL url1("http://qwantz.com//");
683
684 const base::string16 title2(base::ASCIIToUTF16("XKCD"));
685 const GURL url2("https://www.xkcd.com/");
686
687 // Use the existing profile as profile 1.
688 Profile* profile1 = browser()->profile();
689 bookmarks::test::WaitForBookmarkModelToLoad(
pke3e0d5c92016-08-08 09:07:30690 BookmarkModelFactory::GetForBrowserContext(profile1));
lgarron9e6dee22014-11-18 01:03:39691
692 // Create profile 2.
Francois Doraye6fb2d02017-10-18 21:29:13693 base::ScopedAllowBlockingForTesting allow_blocking;
lgarron9e6dee22014-11-18 01:03:39694 base::FilePath path2 = profile_manager->GenerateNextProfileDirectoryPath();
Daniel Hosseinian8f0b7482019-06-07 18:21:04695 std::unique_ptr<Profile> profile2 =
696 Profile::CreateProfile(path2, NULL, Profile::CREATE_MODE_SYNCHRONOUS);
697 Profile* profile2_ptr = profile2.get();
698 profile_manager->RegisterTestingProfile(std::move(profile2), false, true);
lgarron9e6dee22014-11-18 01:03:39699 bookmarks::test::WaitForBookmarkModelToLoad(
Daniel Hosseinian8f0b7482019-06-07 18:21:04700 BookmarkModelFactory::GetForBrowserContext(profile2_ptr));
lgarron9e6dee22014-11-18 01:03:39701
702 // Switch to profile 1, create bookmark 1 and force the menu to build.
703 [ac windowChangedToProfile:profile1];
704 [ac bookmarkMenuBridge]->GetBookmarkModel()->AddURL(
705 [ac bookmarkMenuBridge]->GetBookmarkModel()->bookmark_bar_node(),
706 0, title1, url1);
Trent Aptedcf95689a2017-11-22 00:01:10707 NSMenu* profile1_submenu = [ac bookmarkMenuBridge]->BookmarkMenu();
708 [[profile1_submenu delegate] menuNeedsUpdate:profile1_submenu];
lgarron9e6dee22014-11-18 01:03:39709
710 // Switch to profile 2, create bookmark 2 and force the menu to build.
Daniel Hosseinian8f0b7482019-06-07 18:21:04711 [ac windowChangedToProfile:profile2_ptr];
lgarron9e6dee22014-11-18 01:03:39712 [ac bookmarkMenuBridge]->GetBookmarkModel()->AddURL(
713 [ac bookmarkMenuBridge]->GetBookmarkModel()->bookmark_bar_node(),
714 0, title2, url2);
Trent Aptedcf95689a2017-11-22 00:01:10715 NSMenu* profile2_submenu = [ac bookmarkMenuBridge]->BookmarkMenu();
716 [[profile2_submenu delegate] menuNeedsUpdate:profile2_submenu];
717 EXPECT_NE(profile1_submenu, profile2_submenu);
lgarron9e6dee22014-11-18 01:03:39718
719 // Test that only bookmark 2 is shown.
720 EXPECT_FALSE([[ac bookmarkMenuBridge]->BookmarkMenu() itemWithTitle:
721 SysUTF16ToNSString(title1)]);
722 EXPECT_TRUE([[ac bookmarkMenuBridge]->BookmarkMenu() itemWithTitle:
723 SysUTF16ToNSString(title2)]);
724
725 // Switch *back* to profile 1 and *don't* force the menu to build.
726 [ac windowChangedToProfile:profile1];
727
728 // Test that only bookmark 1 is shown in the restored menu.
729 EXPECT_TRUE([[ac bookmarkMenuBridge]->BookmarkMenu() itemWithTitle:
730 SysUTF16ToNSString(title1)]);
731 EXPECT_FALSE([[ac bookmarkMenuBridge]->BookmarkMenu() itemWithTitle:
732 SysUTF16ToNSString(title2)]);
Trent Aptedcf95689a2017-11-22 00:01:10733
734 // Ensure a cached menu was used.
735 EXPECT_EQ(profile1_submenu, [ac bookmarkMenuBridge]->BookmarkMenu());
lgarron9e6dee22014-11-18 01:03:39736}
737
[email protected]fc44f242012-02-14 16:54:39738} // namespace
erikchen600f7962014-12-12 00:17:38739
740//--------------------------AppControllerHandoffBrowserTest---------------------
741
742static GURL g_handoff_url;
743
744@interface AppController (BrowserTest)
erikchen600f7962014-12-12 00:17:38745- (void)new_passURLToHandoffManager:(const GURL&)handoffURL;
746@end
747
748@implementation AppController (BrowserTest)
erikchen600f7962014-12-12 00:17:38749- (void)new_passURLToHandoffManager:(const GURL&)handoffURL {
750 g_handoff_url = handoffURL;
751}
752@end
753
754namespace {
755
756class AppControllerHandoffBrowserTest : public InProcessBrowserTest {
757 protected:
758 AppControllerHandoffBrowserTest() {}
759
760 // Exchanges the implementations of the two selectors on the class
761 // AppController.
762 void ExchangeSelectors(SEL originalMethod, SEL newMethod) {
763 Class appControllerClass = NSClassFromString(@"AppController");
764
765 ASSERT_TRUE(appControllerClass != nil);
766
767 Method original =
768 class_getInstanceMethod(appControllerClass, originalMethod);
769 Method destination = class_getInstanceMethod(appControllerClass, newMethod);
770
771 ASSERT_TRUE(original != NULL);
772 ASSERT_TRUE(destination != NULL);
773
774 method_exchangeImplementations(original, destination);
775 }
776
777 // Swizzle Handoff related implementations.
778 void SetUpInProcessBrowserTestFixture() override {
erikchen600f7962014-12-12 00:17:38779 // This swizzle intercepts the URL that would be sent to the Handoff
780 // Manager, and instead puts it into a variable accessible to this test.
Avi Drissman438827be2019-06-06 18:46:11781 SEL originalMethod = @selector(passURLToHandoffManager:);
782 SEL newMethod = @selector(new_passURLToHandoffManager:);
erikchen600f7962014-12-12 00:17:38783 ExchangeSelectors(originalMethod, newMethod);
784 }
785
786 // Closes the tab, and waits for the close to finish.
787 void CloseTab(Browser* browser, int index) {
788 content::WebContentsDestroyedWatcher destroyed_watcher(
789 browser->tab_strip_model()->GetWebContentsAt(index));
790 browser->tab_strip_model()->CloseWebContentsAt(
791 index, TabStripModel::CLOSE_CREATE_HISTORICAL_TAB);
792 destroyed_watcher.Wait();
793 }
794};
795
796// Tests that as a user switches between tabs, navigates within a tab, and
797// switches between browser windows, the correct URL is being passed to the
798// Handoff.
799IN_PROC_BROWSER_TEST_F(AppControllerHandoffBrowserTest, TestHandoffURLs) {
svaldeza01f7d92015-11-18 17:47:56800 ASSERT_TRUE(embedded_test_server()->Start());
erikchen600f7962014-12-12 00:17:38801 EXPECT_EQ(g_handoff_url, GURL(url::kAboutBlankURL));
802
803 // Test that navigating to a URL updates the handoff URL.
804 GURL test_url1 = embedded_test_server()->GetURL("/title1.html");
805 ui_test_utils::NavigateToURL(browser(), test_url1);
806 EXPECT_EQ(g_handoff_url, test_url1);
807
808 // Test that opening a new tab updates the handoff URL.
809 GURL test_url2 = embedded_test_server()->GetURL("/title2.html");
cm.sanchi2522bc92017-12-04 08:04:13810 NavigateParams params(browser(), test_url2, ui::PAGE_TRANSITION_LINK);
nick3b04f322016-08-31 19:29:19811 params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
erikchen600f7962014-12-12 00:17:38812 ui_test_utils::NavigateToURL(&params);
813 EXPECT_EQ(g_handoff_url, test_url2);
814
815 // Test that switching tabs updates the handoff URL.
Edwin Joe6f6fc1e2019-02-27 20:00:37816 browser()->tab_strip_model()->ActivateTabAt(
817 0, {TabStripModel::GestureType::kOther});
erikchen600f7962014-12-12 00:17:38818 EXPECT_EQ(g_handoff_url, test_url1);
819
820 // Test that closing the current tab updates the handoff URL.
821 CloseTab(browser(), 0);
822 EXPECT_EQ(g_handoff_url, test_url2);
823
824 // Test that opening a new browser window updates the handoff URL.
825 GURL test_url3 = embedded_test_server()->GetURL("/title3.html");
826 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19827 browser(), GURL(test_url3), WindowOpenDisposition::NEW_WINDOW,
erikchen600f7962014-12-12 00:17:38828 ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER);
829 EXPECT_EQ(g_handoff_url, test_url3);
830
831 // Check that there are exactly 2 browsers.
scottmg0d8e4ab2016-01-28 00:34:55832 BrowserList* active_browser_list = BrowserList::GetInstance();
erikchen600f7962014-12-12 00:17:38833 EXPECT_EQ(2u, active_browser_list->size());
834
erikchen64a6d442015-07-10 19:38:20835 // Close the second browser window (which only has 1 tab left).
erikchen600f7962014-12-12 00:17:38836 Browser* browser2 = active_browser_list->get(1);
erikchen64a6d442015-07-10 19:38:20837 CloseBrowserSynchronously(browser2);
erikchen600f7962014-12-12 00:17:38838 EXPECT_EQ(g_handoff_url, test_url2);
839
840 // The URLs of incognito windows should not be passed to Handoff.
841 GURL test_url4 = embedded_test_server()->GetURL("/simple.html");
842 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19843 browser(), GURL(test_url4), WindowOpenDisposition::OFF_THE_RECORD,
erikchen600f7962014-12-12 00:17:38844 ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER);
845 EXPECT_EQ(g_handoff_url, GURL());
846
847 // Open a new tab in the incognito window.
848 EXPECT_EQ(2u, active_browser_list->size());
849 Browser* browser3 = active_browser_list->get(1);
850 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19851 browser3, test_url4, WindowOpenDisposition::NEW_FOREGROUND_TAB,
erikchen600f7962014-12-12 00:17:38852 ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
853 EXPECT_EQ(g_handoff_url, GURL());
854
855 // Navigate the current tab in the incognito window.
thestig53986dc2014-12-16 06:09:18856 ui_test_utils::NavigateToURL(browser3, test_url1);
erikchen600f7962014-12-12 00:17:38857 EXPECT_EQ(g_handoff_url, GURL());
858
859 // Activate the original browser window.
860 Browser* browser1 = active_browser_list->get(0);
861 browser1->window()->Show();
862 EXPECT_EQ(g_handoff_url, test_url2);
863}
864
865} // namespace