load_and_launch_browsertest.cc 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  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.
  4. // Tests for the --load-and-launch-app switch.
  5. // The two cases are when chrome is running and another process uses the switch
  6. // and when chrome is started from scratch.
  7. #include <iterator>
  8. #include "apps/switches.h"
  9. #include "base/command_line.h"
  10. #include "base/process/launch.h"
  11. #include "base/strings/utf_string_conversions.h"
  12. #include "base/test/test_switches.h"
  13. #include "base/test/test_timeouts.h"
  14. #include "build/branding_buildflags.h"
  15. #include "build/build_config.h"
  16. #include "build/chromeos_buildflags.h"
  17. #include "chrome/browser/apps/platform_apps/app_browsertest_util.h"
  18. #include "chrome/browser/extensions/extension_browsertest.h"
  19. #include "chrome/browser/extensions/load_error_reporter.h"
  20. #include "chrome/browser/profiles/profile_manager.h"
  21. #include "chrome/browser/ui/simple_message_box_internal.h"
  22. #include "chrome/common/chrome_result_codes.h"
  23. #include "chrome/common/chrome_switches.h"
  24. #include "content/public/common/content_switches.h"
  25. #include "content/public/test/browser_test.h"
  26. #include "content/public/test/test_launcher.h"
  27. #include "extensions/browser/extension_registry.h"
  28. #include "extensions/test/extension_test_message_listener.h"
  29. #include "sandbox/policy/switches.h"
  30. using extensions::PlatformAppBrowserTest;
  31. namespace apps {
  32. namespace {
  33. constexpr char kTestExtensionId[] = "behllobkkfkfnphdnhnkndlbkcpglgmj";
  34. // Lacros doesn't support launching with chrome already running. See the header
  35. // comment for InProcessBrowserTest::GetCommandLineForRelaunch().
  36. #if !BUILDFLAG(IS_CHROMEOS_LACROS)
  37. const char* kSwitchesToCopy[] = {
  38. sandbox::policy::switches::kNoSandbox,
  39. switches::kUserDataDir,
  40. };
  41. // TODO(jackhou): Enable this test once it works on OSX. It currently does not
  42. // work for the same reason --app-id doesn't. See http://crbug.com/148465
  43. #if BUILDFLAG(IS_MAC)
  44. #define MAYBE_LoadAndLaunchAppChromeRunning \
  45. DISABLED_LoadAndLaunchAppChromeRunning
  46. #else
  47. #define MAYBE_LoadAndLaunchAppChromeRunning LoadAndLaunchAppChromeRunning
  48. #endif
  49. // Case where Chrome is already running.
  50. IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,
  51. MAYBE_LoadAndLaunchAppChromeRunning) {
  52. ExtensionTestMessageListener launched_listener("Launched");
  53. const base::CommandLine& cmdline = *base::CommandLine::ForCurrentProcess();
  54. base::CommandLine new_cmdline(cmdline.GetProgram());
  55. new_cmdline.CopySwitchesFrom(cmdline, kSwitchesToCopy,
  56. std::size(kSwitchesToCopy));
  57. base::FilePath app_path = test_data_dir_
  58. .AppendASCII("platform_apps")
  59. .AppendASCII("minimal");
  60. new_cmdline.AppendSwitchNative(apps::kLoadAndLaunchApp,
  61. app_path.value());
  62. new_cmdline.AppendSwitch(switches::kLaunchAsBrowser);
  63. base::Process process =
  64. base::LaunchProcess(new_cmdline, base::LaunchOptionsForTest());
  65. ASSERT_TRUE(process.IsValid());
  66. ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
  67. int exit_code;
  68. ASSERT_TRUE(process.WaitForExitWithTimeout(TestTimeouts::action_timeout(),
  69. &exit_code));
  70. ASSERT_EQ(chrome::RESULT_CODE_NORMAL_EXIT_PROCESS_NOTIFIED, exit_code);
  71. }
  72. // TODO(jackhou): Enable this test once it works on OSX. It currently does not
  73. // work for the same reason --app-id doesn't. See http://crbug.com/148465.
  74. #if BUILDFLAG(IS_MAC)
  75. #define MAYBE_LoadAndLaunchAppWithFile DISABLED_LoadAndLaunchAppWithFile
  76. #else
  77. #define MAYBE_LoadAndLaunchAppWithFile LoadAndLaunchAppWithFile
  78. #endif
  79. IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,
  80. MAYBE_LoadAndLaunchAppWithFile) {
  81. ExtensionTestMessageListener launched_listener("Launched");
  82. const base::CommandLine& cmdline = *base::CommandLine::ForCurrentProcess();
  83. base::CommandLine new_cmdline(cmdline.GetProgram());
  84. new_cmdline.CopySwitchesFrom(cmdline, kSwitchesToCopy,
  85. std::size(kSwitchesToCopy));
  86. base::FilePath app_path = test_data_dir_
  87. .AppendASCII("platform_apps")
  88. .AppendASCII("load_and_launch_file");
  89. base::FilePath test_file_path = test_data_dir_
  90. .AppendASCII("platform_apps")
  91. .AppendASCII("launch_files")
  92. .AppendASCII("test.txt");
  93. new_cmdline.AppendSwitchNative(apps::kLoadAndLaunchApp,
  94. app_path.value());
  95. new_cmdline.AppendSwitch(switches::kLaunchAsBrowser);
  96. new_cmdline.AppendArgPath(test_file_path);
  97. base::Process process =
  98. base::LaunchProcess(new_cmdline, base::LaunchOptionsForTest());
  99. ASSERT_TRUE(process.IsValid());
  100. ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
  101. int exit_code;
  102. ASSERT_TRUE(process.WaitForExitWithTimeout(TestTimeouts::action_timeout(),
  103. &exit_code));
  104. ASSERT_EQ(chrome::RESULT_CODE_NORMAL_EXIT_PROCESS_NOTIFIED, exit_code);
  105. }
  106. #endif // !BUILDFLAG(IS_CHROMEOS_LACROS)
  107. // TestFixture that appends --load-and-launch-app with an app before calling
  108. // BrowserMain.
  109. class LoadAndLaunchPlatformAppBrowserTest : public PlatformAppBrowserTest {
  110. public:
  111. LoadAndLaunchPlatformAppBrowserTest(
  112. const LoadAndLaunchPlatformAppBrowserTest&) = delete;
  113. LoadAndLaunchPlatformAppBrowserTest& operator=(
  114. const LoadAndLaunchPlatformAppBrowserTest&) = delete;
  115. protected:
  116. LoadAndLaunchPlatformAppBrowserTest() = default;
  117. void SetUpCommandLine(base::CommandLine* command_line) override {
  118. PlatformAppBrowserTest::SetUpCommandLine(command_line);
  119. base::FilePath app_path =
  120. test_data_dir_.AppendASCII("platform_apps").AppendASCII("minimal");
  121. command_line->AppendSwitchNative(apps::kLoadAndLaunchApp, app_path.value());
  122. // |launched_listener_| needs to be instantiated before the app process is
  123. // launched to ensure the test api observer is registered.
  124. launched_listener_ =
  125. std::make_unique<ExtensionTestMessageListener>("Launched");
  126. }
  127. void TearDownOnMainThread() override { launched_listener_.reset(); }
  128. void LoadAndLaunchApp() {
  129. ASSERT_TRUE(launched_listener_->WaitUntilSatisfied());
  130. // Start an actual browser because we can't shut down with just an app
  131. // window.
  132. CreateBrowser(profile());
  133. }
  134. std::unique_ptr<ExtensionTestMessageListener> launched_listener_;
  135. };
  136. // TestFixture that appends --load-and-launch-app with an extension before
  137. // calling BrowserMain.
  138. class LoadAndLaunchExtensionBrowserTest : public PlatformAppBrowserTest {
  139. public:
  140. LoadAndLaunchExtensionBrowserTest(const LoadAndLaunchExtensionBrowserTest&) =
  141. delete;
  142. LoadAndLaunchExtensionBrowserTest& operator=(
  143. const LoadAndLaunchExtensionBrowserTest&) = delete;
  144. protected:
  145. LoadAndLaunchExtensionBrowserTest() = default;
  146. void SetUpCommandLine(base::CommandLine* command_line) override {
  147. PlatformAppBrowserTest::SetUpCommandLine(command_line);
  148. base::FilePath app_path = test_data_dir_.AppendASCII("good")
  149. .AppendASCII("Extensions")
  150. .AppendASCII(kTestExtensionId)
  151. .AppendASCII("1.0.0.0");
  152. command_line->AppendSwitchNative(apps::kLoadAndLaunchApp, app_path.value());
  153. }
  154. void SetUpInProcessBrowserTestFixture() override {
  155. PlatformAppBrowserTest::SetUpInProcessBrowserTestFixture();
  156. // Skip showing the error message box to avoid freezing the main thread.
  157. chrome::internal::g_should_skip_message_box_for_test = true;
  158. }
  159. };
  160. // Case where Chrome is not running.
  161. IN_PROC_BROWSER_TEST_F(LoadAndLaunchPlatformAppBrowserTest,
  162. LoadAndLaunchAppChromeNotRunning) {
  163. LoadAndLaunchApp();
  164. }
  165. IN_PROC_BROWSER_TEST_F(LoadAndLaunchExtensionBrowserTest,
  166. LoadAndLaunchExtension) {
  167. const std::vector<std::u16string>* errors =
  168. extensions::LoadErrorReporter::GetInstance()->GetErrors();
  169. #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
  170. // The error is skipped on official builds.
  171. EXPECT_TRUE(errors->empty());
  172. #else
  173. // Expect |extension_instead_of_app_error|.
  174. EXPECT_EQ(1u, errors->size());
  175. EXPECT_NE(std::u16string::npos,
  176. errors->at(0).find(
  177. u"App loading flags cannot be used to load extensions"));
  178. #endif
  179. extensions::ExtensionRegistry* registry =
  180. extensions::ExtensionRegistry::Get(profile());
  181. EXPECT_EQ(nullptr,
  182. registry->GetExtensionById(
  183. kTestExtensionId, extensions::ExtensionRegistry::EVERYTHING));
  184. }
  185. } // namespace
  186. } // namespace apps