1 // Copyright 2013 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 // Tests for the --load-and-launch-app switch.
6 // The two cases are when chrome is running and another process uses the switch
7 // and when chrome is started from scratch.
9 #include "apps/switches.h"
10 #include "base/process/launch.h"
11 #include "base/stl_util.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/test/test_timeouts.h"
14 #include "chrome/browser/apps/platform_apps/app_browsertest_util.h"
15 #include "chrome/browser/extensions/extension_browsertest.h"
16 #include "chrome/browser/extensions/load_error_reporter.h"
17 #include "chrome/browser/profiles/profile_manager.h"
18 #include "chrome/browser/ui/simple_message_box_internal.h"
19 #include "chrome/common/chrome_switches.h"
20 #include "content/public/common/content_switches.h"
21 #include "content/public/test/test_launcher.h"
22 #include "extensions/browser/extension_registry.h"
23 #include "extensions/test/extension_test_message_listener.h"
24 #include "services/service_manager/sandbox/switches.h"
26 using extensions::PlatformAppBrowserTest;
32 const char* kSwitchesToCopy[] = {
33 service_manager::switches::kNoSandbox, switches::kUserDataDir,
36 constexpr char kTestExtensionId[] = "behllobkkfkfnphdnhnkndlbkcpglgmj";
40 // TODO(jackhou): Enable this test once it works on OSX. It currently does not
41 // work for the same reason --app-id doesn't. See http://crbug.com/148465
42 #if defined(OS_MACOSX)
43 #define MAYBE_LoadAndLaunchAppChromeRunning \
44 DISABLED_LoadAndLaunchAppChromeRunning
46 #define MAYBE_LoadAndLaunchAppChromeRunning LoadAndLaunchAppChromeRunning
49 // Case where Chrome is already running.
50 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,
51 MAYBE_LoadAndLaunchAppChromeRunning) {
52 ExtensionTestMessageListener launched_listener("Launched", false);
54 const base::CommandLine& cmdline = *base::CommandLine::ForCurrentProcess();
55 base::CommandLine new_cmdline(cmdline.GetProgram());
56 new_cmdline.CopySwitchesFrom(cmdline, kSwitchesToCopy,
57 base::size(kSwitchesToCopy));
59 base::FilePath app_path = test_data_dir_
60 .AppendASCII("platform_apps")
61 .AppendASCII("minimal");
63 new_cmdline.AppendSwitchNative(apps::kLoadAndLaunchApp,
66 new_cmdline.AppendSwitch(content::kLaunchAsBrowser);
67 base::Process process =
68 base::LaunchProcess(new_cmdline, base::LaunchOptionsForTest());
69 ASSERT_TRUE(process.IsValid());
71 ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
73 ASSERT_TRUE(process.WaitForExitWithTimeout(TestTimeouts::action_timeout(),
75 ASSERT_EQ(0, exit_code);
78 // TODO(jackhou): Enable this test once it works on OSX. It currently does not
79 // work for the same reason --app-id doesn't. See http://crbug.com/148465
80 #if defined(OS_MACOSX)
81 #define MAYBE_LoadAndLaunchAppWithFile DISABLED_LoadAndLaunchAppWithFile
83 #define MAYBE_LoadAndLaunchAppWithFile LoadAndLaunchAppWithFile
86 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,
87 MAYBE_LoadAndLaunchAppWithFile) {
88 ExtensionTestMessageListener launched_listener("Launched", false);
90 const base::CommandLine& cmdline = *base::CommandLine::ForCurrentProcess();
91 base::CommandLine new_cmdline(cmdline.GetProgram());
92 new_cmdline.CopySwitchesFrom(cmdline, kSwitchesToCopy,
93 base::size(kSwitchesToCopy));
95 base::FilePath app_path = test_data_dir_
96 .AppendASCII("platform_apps")
97 .AppendASCII("load_and_launch_file");
99 base::FilePath test_file_path = test_data_dir_
100 .AppendASCII("platform_apps")
101 .AppendASCII("launch_files")
102 .AppendASCII("test.txt");
104 new_cmdline.AppendSwitchNative(apps::kLoadAndLaunchApp,
106 new_cmdline.AppendSwitch(content::kLaunchAsBrowser);
107 new_cmdline.AppendArgPath(test_file_path);
109 base::Process process =
110 base::LaunchProcess(new_cmdline, base::LaunchOptionsForTest());
111 ASSERT_TRUE(process.IsValid());
113 ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
115 ASSERT_TRUE(process.WaitForExitWithTimeout(TestTimeouts::action_timeout(),
117 ASSERT_EQ(0, exit_code);
122 // TestFixture that appends --load-and-launch-app with an app before calling
124 class LoadAndLaunchPlatformAppBrowserTest : public PlatformAppBrowserTest {
126 LoadAndLaunchPlatformAppBrowserTest() {}
128 void SetUpCommandLine(base::CommandLine* command_line) override {
129 PlatformAppBrowserTest::SetUpCommandLine(command_line);
130 base::FilePath app_path =
131 test_data_dir_.AppendASCII("platform_apps").AppendASCII("minimal");
132 command_line->AppendSwitchNative(apps::kLoadAndLaunchApp, app_path.value());
135 void LoadAndLaunchApp() {
136 ExtensionTestMessageListener launched_listener("Launched", false);
137 ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
139 // Start an actual browser because we can't shut down with just an app
141 CreateBrowser(ProfileManager::GetActiveUserProfile());
145 DISALLOW_COPY_AND_ASSIGN(LoadAndLaunchPlatformAppBrowserTest);
148 // TestFixture that appends --load-and-launch-app with an extension before
149 // calling BrowserMain.
150 class LoadAndLaunchExtensionBrowserTest : public PlatformAppBrowserTest {
152 LoadAndLaunchExtensionBrowserTest() {}
154 void SetUpCommandLine(base::CommandLine* command_line) override {
155 PlatformAppBrowserTest::SetUpCommandLine(command_line);
156 base::FilePath app_path = test_data_dir_.AppendASCII("good")
157 .AppendASCII("Extensions")
158 .AppendASCII(kTestExtensionId)
159 .AppendASCII("1.0.0.0");
160 command_line->AppendSwitchNative(apps::kLoadAndLaunchApp, app_path.value());
163 void SetUpInProcessBrowserTestFixture() override {
164 PlatformAppBrowserTest::SetUpInProcessBrowserTestFixture();
166 // Skip showing the error message box to avoid freezing the main thread.
167 chrome::internal::g_should_skip_message_box_for_test = true;
170 DISALLOW_COPY_AND_ASSIGN(LoadAndLaunchExtensionBrowserTest);
175 // Case where Chrome is not running.
176 IN_PROC_BROWSER_TEST_F(LoadAndLaunchPlatformAppBrowserTest,
177 LoadAndLaunchAppChromeNotRunning) {
181 IN_PROC_BROWSER_TEST_F(LoadAndLaunchExtensionBrowserTest,
182 LoadAndLaunchExtension) {
183 const std::vector<base::string16>* errors =
184 extensions::LoadErrorReporter::GetInstance()->GetErrors();
186 #if defined(GOOGLE_CHROME_BUILD)
187 // The error is skipped on official builds.
188 EXPECT_TRUE(errors->empty());
190 // Expect |extension_instead_of_app_error|.
191 EXPECT_EQ(1u, errors->size());
192 EXPECT_NE(base::string16::npos,
193 errors->at(0).find(base::ASCIIToUTF16(
194 "App loading flags cannot be used to load extensions")));
197 extensions::ExtensionRegistry* registry =
198 extensions::ExtensionRegistry::Get(profile());
200 registry->GetExtensionById(
201 kTestExtensionId, extensions::ExtensionRegistry::EVERYTHING));