Make hitting "Enter" submit the add/change profile dialog.
[chromium-blink-merge.git] / chrome / test / base / in_process_browser_test.cc
blobd32f58cb768322bec25ab6060a1b8f91c8409685
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/test/base/in_process_browser_test.h"
7 #include "base/auto_reset.h"
8 #include "base/bind.h"
9 #include "base/command_line.h"
10 #include "base/file_path.h"
11 #include "base/file_util.h"
12 #include "base/lazy_instance.h"
13 #include "base/path_service.h"
14 #include "base/string_number_conversions.h"
15 #include "base/test/test_file_util.h"
16 #include "chrome/browser/browser_process.h"
17 #include "chrome/browser/google/google_util.h"
18 #include "chrome/browser/io_thread.h"
19 #include "chrome/browser/lifetime/application_lifetime.h"
20 #include "chrome/browser/net/net_error_tab_helper.h"
21 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/browser/profiles/profile_manager.h"
23 #include "chrome/browser/ui/browser.h"
24 #include "chrome/browser/ui/browser_list.h"
25 #include "chrome/browser/ui/browser_navigator.h"
26 #include "chrome/browser/ui/browser_tabstrip.h"
27 #include "chrome/browser/ui/browser_window.h"
28 #include "chrome/browser/ui/tabs/tab_strip_model.h"
29 #include "chrome/common/chrome_constants.h"
30 #include "chrome/common/chrome_paths.h"
31 #include "chrome/common/chrome_switches.h"
32 #include "chrome/common/logging_chrome.h"
33 #include "chrome/common/url_constants.h"
34 #include "chrome/renderer/chrome_content_renderer_client.h"
35 #include "chrome/test/base/chrome_test_suite.h"
36 #include "chrome/test/base/test_launcher_utils.h"
37 #include "chrome/test/base/testing_browser_process.h"
38 #include "chrome/test/base/ui_test_utils.h"
39 #include "content/public/browser/notification_service.h"
40 #include "content/public/browser/notification_types.h"
41 #include "content/public/test/browser_test_utils.h"
42 #include "content/public/test/test_browser_thread.h"
43 #include "content/public/test/test_launcher.h"
44 #include "content/public/test/test_navigation_observer.h"
45 #include "net/base/mock_host_resolver.h"
46 #include "net/test/test_server.h"
47 #include "ui/compositor/compositor_switches.h"
49 #if defined(OS_CHROMEOS)
50 #include "chrome/browser/chromeos/audio/audio_handler.h"
51 #elif defined(OS_MACOSX)
52 #include "base/mac/scoped_nsautorelease_pool.h"
53 #endif
55 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
56 #include "chrome/browser/captive_portal/captive_portal_service.h"
57 #endif
59 namespace {
61 // Passed as value of kTestType.
62 const char kBrowserTestType[] = "browser";
64 // Used when running in single-process mode.
65 base::LazyInstance<chrome::ChromeContentRendererClient>::Leaky
66 g_chrome_content_renderer_client = LAZY_INSTANCE_INITIALIZER;
68 } // namespace
70 InProcessBrowserTest::InProcessBrowserTest()
71 : browser_(NULL)
72 #if defined(OS_MACOSX)
73 , autorelease_pool_(NULL)
74 #endif // OS_MACOSX
76 #if defined(OS_MACOSX)
77 // TODO(phajdan.jr): Make browser_tests self-contained on Mac, remove this.
78 // Before we run the browser, we have to hack the path to the exe to match
79 // what it would be if Chrome was running, because it is used to fork renderer
80 // processes, on Linux at least (failure to do so will cause a browser_test to
81 // be run instead of a renderer).
82 FilePath chrome_path;
83 CHECK(PathService::Get(base::FILE_EXE, &chrome_path));
84 chrome_path = chrome_path.DirName();
85 chrome_path = chrome_path.Append(chrome::kBrowserProcessExecutablePath);
86 CHECK(PathService::Override(base::FILE_EXE, chrome_path));
87 #endif // defined(OS_MACOSX)
88 CreateTestServer(FilePath(FILE_PATH_LITERAL("chrome/test/data")));
91 InProcessBrowserTest::~InProcessBrowserTest() {
94 void InProcessBrowserTest::SetUp() {
95 // Undo TestingBrowserProcess creation in ChromeTestSuite.
96 // TODO(phajdan.jr): Extract a smaller test suite so we don't need this.
97 DCHECK(g_browser_process);
98 delete g_browser_process;
99 g_browser_process = NULL;
101 CommandLine* command_line = CommandLine::ForCurrentProcess();
102 // Allow subclasses to change the command line before running any tests.
103 SetUpCommandLine(command_line);
104 // Add command line arguments that are used by all InProcessBrowserTests.
105 PrepareTestCommandLine(command_line);
107 // Create a temporary user data directory if required.
108 ASSERT_TRUE(CreateUserDataDirectory())
109 << "Could not create user data directory.";
111 // Allow subclasses the opportunity to make changes to the default user data
112 // dir before running any tests.
113 ASSERT_TRUE(SetUpUserDataDirectory())
114 << "Could not set up user data directory.";
116 // Single-process mode is not set in BrowserMain, so process it explicitly,
117 // and set up renderer.
118 if (command_line->HasSwitch(switches::kSingleProcess)) {
119 content::GetContentClient()->set_renderer_for_testing(
120 &g_chrome_content_renderer_client.Get());
123 #if defined(OS_CHROMEOS)
124 // Make sure that the log directory exists.
125 FilePath log_dir = logging::GetSessionLogFile(*command_line).DirName();
126 file_util::CreateDirectory(log_dir);
127 #endif // defined(OS_CHROMEOS)
129 host_resolver_ = new net::RuleBasedHostResolverProc(NULL);
131 // Something inside the browser does this lookup implicitly. Make it fail
132 // to avoid external dependency. It won't break the tests.
133 host_resolver_->AddSimulatedFailure("*.google.com");
135 // See http://en.wikipedia.org/wiki/Web_Proxy_Autodiscovery_Protocol
136 // We don't want the test code to use it.
137 host_resolver_->AddSimulatedFailure("wpad");
139 net::ScopedDefaultHostResolverProc scoped_host_resolver_proc(
140 host_resolver_.get());
142 #if defined(OS_MACOSX)
143 // On Mac, without the following autorelease pool, code which is directly
144 // executed (as opposed to executed inside a message loop) would autorelease
145 // objects into a higher-level pool. This pool is not recycled in-sync with
146 // the message loops' pools and causes problems with code relying on
147 // deallocation via an autorelease pool (such as browser window closure and
148 // browser shutdown). To avoid this, the following pool is recycled after each
149 // time code is directly executed.
150 autorelease_pool_ = new base::mac::ScopedNSAutoreleasePool;
151 #endif
153 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
154 captive_portal::CaptivePortalService::set_state_for_testing(
155 captive_portal::CaptivePortalService::DISABLED_FOR_TESTING);
156 #endif
158 chrome_browser_net::NetErrorTabHelper::set_state_for_testing(
159 chrome_browser_net::NetErrorTabHelper::TESTING_FORCE_DISABLED);
161 google_util::SetMockLinkDoctorBaseURLForTesting();
163 BrowserTestBase::SetUp();
166 void InProcessBrowserTest::PrepareTestCommandLine(CommandLine* command_line) {
167 // Propagate commandline settings from test_launcher_utils.
168 test_launcher_utils::PrepareBrowserCommandLineForTests(command_line);
170 // This is a Browser test.
171 command_line->AppendSwitchASCII(switches::kTestType, kBrowserTestType);
173 #if defined(OS_MACOSX)
174 // Explicitly set the path of the binary used for child processes, otherwise
175 // they'll try to use browser_tests which doesn't contain ChromeMain.
176 FilePath subprocess_path;
177 PathService::Get(base::FILE_EXE, &subprocess_path);
178 // Recreate the real environment, run the helper within the app bundle.
179 subprocess_path = subprocess_path.DirName().DirName();
180 DCHECK_EQ(subprocess_path.BaseName().value(), "Contents");
181 subprocess_path =
182 subprocess_path.Append("Versions").Append(chrome::kChromeVersion);
183 subprocess_path =
184 subprocess_path.Append(chrome::kHelperProcessExecutablePath);
185 command_line->AppendSwitchPath(switches::kBrowserSubprocessPath,
186 subprocess_path);
187 #endif
189 // TODO(pkotwicz): Investigate if we can remove this switch.
190 command_line->AppendSwitch(switches::kDisableZeroBrowsersOpenForTests);
192 if (command_line->GetArgs().empty())
193 command_line->AppendArg(chrome::kAboutBlankURL);
196 bool InProcessBrowserTest::CreateUserDataDirectory() {
197 CommandLine* command_line = CommandLine::ForCurrentProcess();
198 FilePath user_data_dir =
199 command_line->GetSwitchValuePath(switches::kUserDataDir);
200 if (user_data_dir.empty()) {
201 if (temp_user_data_dir_.CreateUniqueTempDir() &&
202 temp_user_data_dir_.IsValid()) {
203 user_data_dir = temp_user_data_dir_.path();
204 } else {
205 LOG(ERROR) << "Could not create temporary user data directory \""
206 << temp_user_data_dir_.path().value() << "\".";
207 return false;
210 return test_launcher_utils::OverrideUserDataDir(user_data_dir);
213 void InProcessBrowserTest::TearDown() {
214 DCHECK(!g_browser_process);
215 BrowserTestBase::TearDown();
218 void InProcessBrowserTest::AddTabAtIndexToBrowser(
219 Browser* browser,
220 int index,
221 const GURL& url,
222 content::PageTransition transition) {
223 content::TestNavigationObserver observer(
224 content::NotificationService::AllSources(), NULL, 1);
226 chrome::NavigateParams params(browser, url, transition);
227 params.tabstrip_index = index;
228 params.disposition = NEW_FOREGROUND_TAB;
229 chrome::Navigate(&params);
231 observer.Wait();
234 void InProcessBrowserTest::AddTabAtIndex(
235 int index,
236 const GURL& url,
237 content::PageTransition transition) {
238 AddTabAtIndexToBrowser(browser(), index, url, transition);
241 bool InProcessBrowserTest::SetUpUserDataDirectory() {
242 return true;
245 // Creates a browser with a single tab (about:blank), waits for the tab to
246 // finish loading and shows the browser.
247 Browser* InProcessBrowserTest::CreateBrowser(Profile* profile) {
248 Browser* browser = new Browser(Browser::CreateParams(profile));
249 AddBlankTabAndShow(browser);
250 return browser;
253 Browser* InProcessBrowserTest::CreateIncognitoBrowser() {
254 // Create a new browser with using the incognito profile.
255 Browser* incognito = new Browser(
256 Browser::CreateParams(browser()->profile()->GetOffTheRecordProfile()));
257 AddBlankTabAndShow(incognito);
258 return incognito;
261 Browser* InProcessBrowserTest::CreateBrowserForPopup(Profile* profile) {
262 Browser* browser =
263 new Browser(Browser::CreateParams(Browser::TYPE_POPUP, profile));
264 AddBlankTabAndShow(browser);
265 return browser;
268 Browser* InProcessBrowserTest::CreateBrowserForApp(
269 const std::string& app_name,
270 Profile* profile) {
271 Browser* browser = new Browser(
272 Browser::CreateParams::CreateForApp(
273 Browser::TYPE_POPUP, app_name, gfx::Rect(), profile));
274 AddBlankTabAndShow(browser);
275 return browser;
278 void InProcessBrowserTest::AddBlankTabAndShow(Browser* browser) {
279 content::WindowedNotificationObserver observer(
280 content::NOTIFICATION_LOAD_STOP,
281 content::NotificationService::AllSources());
282 chrome::AddSelectedTabWithURL(browser, GURL(chrome::kAboutBlankURL),
283 content::PAGE_TRANSITION_AUTO_TOPLEVEL);
284 observer.Wait();
286 browser->window()->Show();
289 #if !defined(OS_MACOSX)
290 CommandLine InProcessBrowserTest::GetCommandLineForRelaunch() {
291 CommandLine new_command_line(CommandLine::ForCurrentProcess()->GetProgram());
292 CommandLine::SwitchMap switches =
293 CommandLine::ForCurrentProcess()->GetSwitches();
294 switches.erase(switches::kUserDataDir);
295 switches.erase(content::kSingleProcessTestsFlag);
296 switches.erase(switches::kSingleProcess);
297 new_command_line.AppendSwitch(content::kLaunchAsBrowser);
299 #if defined(USE_AURA)
300 // Copy what UITestBase::SetLaunchSwitches() does, and also what
301 // ChromeTestSuite does if the process had went into the test path. Otherwise
302 // tests will fail on bots.
303 if (!CommandLine::ForCurrentProcess()->HasSwitch(
304 switches::kDisableTestCompositor)) {
305 new_command_line.AppendSwitch(switches::kTestCompositor);
307 #endif
309 FilePath user_data_dir;
310 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
311 new_command_line.AppendSwitchPath(switches::kUserDataDir, user_data_dir);
313 for (CommandLine::SwitchMap::const_iterator iter = switches.begin();
314 iter != switches.end(); ++iter) {
315 new_command_line.AppendSwitchNative((*iter).first, (*iter).second);
317 return new_command_line;
319 #endif
321 void InProcessBrowserTest::RunTestOnMainThreadLoop() {
322 // Pump startup related events.
323 content::RunAllPendingInMessageLoop();
325 #if defined(OS_MACOSX)
326 autorelease_pool_->Recycle();
327 #endif
329 if (!BrowserList::empty()) {
330 browser_ = *BrowserList::begin();
331 content::WaitForLoadStop(chrome::GetActiveWebContents(browser_));
334 // Pump any pending events that were created as a result of creating a
335 // browser.
336 content::RunAllPendingInMessageLoop();
338 SetUpOnMainThread();
339 #if defined(OS_MACOSX)
340 autorelease_pool_->Recycle();
341 #endif
343 if (!HasFatalFailure())
344 RunTestOnMainThread();
345 #if defined(OS_MACOSX)
346 autorelease_pool_->Recycle();
347 #endif
349 // Invoke cleanup and quit even if there are failures. This is similar to
350 // gtest in that it invokes TearDown even if Setup fails.
351 CleanUpOnMainThread();
352 #if defined(OS_MACOSX)
353 autorelease_pool_->Recycle();
354 #endif
356 // Sometimes tests leave Quit tasks in the MessageLoop (for shame), so let's
357 // run all pending messages here to avoid preempting the QuitBrowsers tasks.
358 // TODO(jbates) Once crbug.com/134753 is fixed, this can be removed because it
359 // will not be possible to post Quit tasks.
360 content::RunAllPendingInMessageLoop();
362 QuitBrowsers();
363 CHECK(BrowserList::empty());
366 void InProcessBrowserTest::QuitBrowsers() {
367 if (BrowserList::empty())
368 return;
370 // Invoke AttemptExit on a running message loop.
371 // AttemptExit exits the message loop after everything has been
372 // shut down properly.
373 MessageLoopForUI::current()->PostTask(FROM_HERE,
374 base::Bind(&browser::AttemptExit));
375 content::RunMessageLoop();
377 #if defined(OS_MACOSX)
378 // browser::AttemptExit() will attempt to close all browsers by deleting
379 // their tab contents. The last tab contents being removed triggers closing of
380 // the browser window.
382 // On the Mac, this eventually reaches
383 // -[BrowserWindowController windowWillClose:], which will post a deferred
384 // -autorelease on itself to ultimately destroy the Browser object. The line
385 // below is necessary to pump these pending messages to ensure all Browsers
386 // get deleted.
387 content::RunAllPendingInMessageLoop();
388 delete autorelease_pool_;
389 autorelease_pool_ = NULL;
390 #endif