| // Copyright 2018 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "base/run_loop.h" |
| #include "chrome/browser/ui/web_applications/web_app_metrics.h" |
| |
| #include <bitset> |
| #include <vector> |
| |
| #include "base/command_line.h" |
| #include "base/files/file_path.h" |
| #include "base/metrics/statistics_recorder.h" |
| #include "base/test/bind.h" |
| #include "base/test/metrics/histogram_tester.h" |
| #include "chrome/browser/ui/browser.h" |
| #include "chrome/browser/ui/browser_finder.h" |
| #include "chrome/browser/ui/browser_list.h" |
| #include "chrome/browser/ui/startup/startup_browser_creator.h" |
| #include "chrome/browser/ui/startup/startup_types.h" |
| #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| #include "chrome/browser/ui/web_applications/app_browser_controller.h" |
| #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" |
| #include "chrome/browser/ui/web_applications/web_app_controller_browsertest.h" |
| #include "chrome/browser/web_applications/external_install_options.h" |
| #include "chrome/browser/web_applications/externally_managed_app_manager.h" |
| #include "chrome/browser/web_applications/user_display_mode.h" |
| #include "chrome/browser/web_applications/web_app_helpers.h" |
| #include "chrome/browser/web_applications/web_app_install_info.h" |
| #include "chrome/common/chrome_switches.h" |
| #include "chrome/test/base/ui_test_utils.h" |
| #include "components/services/app_service/public/cpp/app_launch_util.h" |
| #include "components/services/app_service/public/mojom/types.mojom-shared.h" |
| #include "components/site_engagement/content/engagement_type.h" |
| #include "components/site_engagement/content/site_engagement_service.h" |
| #include "components/webapps/browser/install_result_code.h" |
| #include "content/public/browser/web_contents.h" |
| #include "content/public/test/browser_test.h" |
| #include "content/public/test/test_navigation_observer.h" |
| #include "content/public/test/test_utils.h" |
| #include "extensions/common/constants.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "ui/views/widget/widget.h" |
| #include "url/gurl.h" |
| |
| namespace { |
| |
| GURL GetUrlForSuffix(const std::string& prefix, int suffix) { |
| return GURL(prefix + base::NumberToString(suffix + 1) + ".html"); |
| } |
| |
| // Must be zero-based as this will be stored in a bitset. |
| enum HistogramIndex { |
| kHistogramInTab = 0, |
| kHistogramInWindow, |
| kHistogramDefaultInstalled_InTab, |
| kHistogramDefaultInstalled_InWindow, |
| kHistogramUserInstalled_InTab, |
| kHistogramUserInstalled_InWindow, |
| kHistogramMoreThanThreeUserInstalledApps, |
| kHistogramUpToThreeUserInstalledApps, |
| kHistogramNoUserInstalledApps, |
| kHistogramMaxValue |
| }; |
| |
| // The order (indices) must match HistogramIndex enum above: |
| const char* kHistogramNames[] = { |
| "WebApp.Engagement.InTab", |
| "WebApp.Engagement.InWindow", |
| "WebApp.Engagement.DefaultInstalled.InTab", |
| "WebApp.Engagement.DefaultInstalled.InWindow", |
| "WebApp.Engagement.UserInstalled.InTab", |
| "WebApp.Engagement.UserInstalled.InWindow", |
| "WebApp.Engagement.MoreThanThreeUserInstalledApps", |
| "WebApp.Engagement.UpToThreeUserInstalledApps", |
| "WebApp.Engagement.NoUserInstalledApps"}; |
| |
| const char* HistogramEnumIndexToStr(int histogram_index) { |
| DCHECK_GE(histogram_index, 0); |
| DCHECK_LT(histogram_index, kHistogramMaxValue); |
| return kHistogramNames[histogram_index]; |
| } |
| |
| using Histograms = std::bitset<kHistogramMaxValue>; |
| |
| void ExpectBucketCounts(const base::HistogramTester& tester, |
| const Histograms& histograms_mask, |
| site_engagement::EngagementType type, |
| base::HistogramBase::Count count) { |
| for (int h = 0; h < kHistogramMaxValue; ++h) { |
| if (histograms_mask[h]) { |
| const char* histogram_name = HistogramEnumIndexToStr(h); |
| tester.ExpectBucketCount(histogram_name, type, count); |
| } |
| } |
| } |
| |
| void ExpectTotalCounts(const base::HistogramTester& tester, |
| const Histograms& histograms_mask, |
| base::HistogramBase::Count count) { |
| for (int h = 0; h < kHistogramMaxValue; ++h) { |
| if (histograms_mask[h]) { |
| const char* histogram_name = HistogramEnumIndexToStr(h); |
| tester.ExpectTotalCount(histogram_name, count); |
| } |
| } |
| } |
| |
| void ExpectLaunchCounts(const base::HistogramTester& tester, |
| base::HistogramBase::Count windowLaunches, |
| base::HistogramBase::Count tabLaunches) { |
| tester.ExpectBucketCount("Extensions.BookmarkAppLaunchContainer", |
| apps::LaunchContainer::kLaunchContainerWindow, |
| windowLaunches); |
| tester.ExpectBucketCount("Extensions.BookmarkAppLaunchContainer", |
| apps::LaunchContainer::kLaunchContainerTab, |
| tabLaunches); |
| tester.ExpectTotalCount("Extensions.BookmarkAppLaunchContainer", |
| windowLaunches + tabLaunches); |
| |
| tester.ExpectUniqueSample("Extensions.BookmarkAppLaunchSource", |
| extensions::AppLaunchSource::kSourceTest, |
| windowLaunches + tabLaunches); |
| } |
| |
| } // namespace |
| |
| namespace web_app { |
| |
| class WebAppEngagementBrowserTest : public WebAppControllerBrowserTest { |
| public: |
| WebAppEngagementBrowserTest() = default; |
| WebAppEngagementBrowserTest(const WebAppEngagementBrowserTest&) = delete; |
| WebAppEngagementBrowserTest& operator=(const WebAppEngagementBrowserTest&) = |
| delete; |
| ~WebAppEngagementBrowserTest() override = default; |
| |
| // Test some other engagement events by directly calling into |
| // SiteEngagementService. |
| void TestEngagementEventsAfterLaunch(const Histograms& histograms, |
| Browser* browser) { |
| base::HistogramTester tester; |
| |
| content::WebContents* web_contents = |
| browser->tab_strip_model()->GetActiveWebContents(); |
| auto* site_engagement_service = |
| site_engagement::SiteEngagementService::Get(browser->profile()); |
| |
| // Simulate 4 events of various types. |
| site_engagement_service->HandleMediaPlaying(web_contents, false); |
| site_engagement_service->HandleMediaPlaying(web_contents, true); |
| site_engagement_service->HandleNavigation(web_contents, |
| ui::PAGE_TRANSITION_TYPED); |
| site_engagement_service->HandleUserInput( |
| web_contents, site_engagement::EngagementType::kMouse); |
| |
| ExpectTotalCounts(tester, histograms, 4); |
| ExpectTotalCounts(tester, ~histograms, 0); |
| |
| ExpectBucketCounts(tester, histograms, |
| site_engagement::EngagementType::kMediaVisible, 1); |
| ExpectBucketCounts(tester, histograms, |
| site_engagement::EngagementType::kMediaHidden, 1); |
| ExpectBucketCounts(tester, histograms, |
| site_engagement::EngagementType::kNavigation, 1); |
| ExpectBucketCounts(tester, histograms, |
| site_engagement::EngagementType::kMouse, 1); |
| } |
| |
| protected: |
| void CountUserInstalledApps() { |
| WebAppMetrics* web_app_metrics = WebAppMetrics::Get(profile()); |
| web_app_metrics->CountUserInstalledAppsForTesting(); |
| } |
| |
| AppId InstallWebAppAndCountApps( |
| std::unique_ptr<WebAppInstallInfo> web_app_info) { |
| AppId app_id = InstallWebApp(std::move(web_app_info)); |
| CountUserInstalledApps(); |
| return app_id; |
| } |
| |
| void InstallDefaultAppAndCountApps(ExternalInstallOptions install_options) { |
| ExternallyManagedAppManager::InstallResult result = |
| ExternallyManagedAppManagerInstall(browser()->profile(), |
| std::move(install_options)); |
| result_code_ = result.code; |
| CountUserInstalledApps(); |
| } |
| |
| absl::optional<webapps::InstallResultCode> result_code_; |
| }; |
| |
| IN_PROC_BROWSER_TEST_F(WebAppEngagementBrowserTest, AppInWindow) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| base::HistogramTester tester; |
| |
| GURL example_url( |
| embedded_test_server()->GetURL("/banners/manifest_test_page.html")); |
| auto web_app_info = std::make_unique<WebAppInstallInfo>(); |
| web_app_info->start_url = example_url; |
| web_app_info->scope = example_url; |
| web_app_info->user_display_mode = UserDisplayMode::kStandalone; |
| AppId app_id = InstallWebAppAndCountApps(std::move(web_app_info)); |
| |
| Browser* app_browser = LaunchWebAppBrowserAndWait(app_id); |
| NavigateToURLAndWait(app_browser, example_url); |
| |
| EXPECT_EQ(GetAppIdFromApplicationName(app_browser->app_name()), app_id); |
| |
| Histograms histograms; |
| histograms[kHistogramInWindow] = true; |
| histograms[kHistogramUserInstalled_InWindow] = true; |
| histograms[kHistogramUpToThreeUserInstalledApps] = true; |
| |
| ExpectBucketCounts(tester, histograms, |
| site_engagement::EngagementType::kWebappShortcutLaunch, 1); |
| ExpectBucketCounts(tester, histograms, |
| site_engagement::EngagementType::kNavigation, 1); |
| ExpectTotalCounts(tester, ~histograms, 0); |
| |
| TestEngagementEventsAfterLaunch(histograms, app_browser); |
| ExpectLaunchCounts(tester, /*windowLaunches=*/1, /*tabLaunches=*/0); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(WebAppEngagementBrowserTest, AppInTab) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| base::HistogramTester tester; |
| |
| GURL example_url( |
| embedded_test_server()->GetURL("/banners/manifest_test_page.html")); |
| |
| auto web_app_info = std::make_unique<WebAppInstallInfo>(); |
| web_app_info->start_url = example_url; |
| web_app_info->scope = example_url; |
| web_app_info->user_display_mode = UserDisplayMode::kBrowser; |
| AppId app_id = InstallWebAppAndCountApps(std::move(web_app_info)); |
| |
| Browser* browser = LaunchBrowserForWebAppInTab(app_id); |
| EXPECT_FALSE(browser->app_controller()); |
| NavigateToURLAndWait(browser, example_url); |
| |
| Histograms histograms; |
| histograms[kHistogramInTab] = true; |
| histograms[kHistogramUserInstalled_InTab] = true; |
| histograms[kHistogramUpToThreeUserInstalledApps] = true; |
| |
| // Note: We explicitly do NOT expect engagement to be recorded in kNavigation. |
| // This is because the open-in-tab behavior only records the launch, and |
| // treats the navigation as a 'link' navigation, so it is not considered by |
| // the engagement service as a navigation. See the `IsEngagementNavigation` |
| // method. |
| ExpectBucketCounts(tester, histograms, |
| site_engagement::EngagementType::kWebappShortcutLaunch, 1); |
| ExpectTotalCounts(tester, ~histograms, 0); |
| TestEngagementEventsAfterLaunch(histograms, browser); |
| ExpectLaunchCounts(tester, /*windowLaunches=*/0, /*tabLaunches=*/1); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(WebAppEngagementBrowserTest, AppWithoutScope) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| base::HistogramTester tester; |
| |
| GURL example_url( |
| embedded_test_server()->GetURL("/banners/manifest_test_page.html")); |
| |
| auto web_app_info = std::make_unique<WebAppInstallInfo>(); |
| web_app_info->start_url = example_url; |
| // If app has no scope then UrlHandlers::GetUrlHandlers are empty. Therefore, |
| // the app is counted as installed via the Create Shortcut button. |
| web_app_info->scope = GURL(); |
| web_app_info->user_display_mode = UserDisplayMode::kStandalone; |
| AppId app_id = InstallWebAppAndCountApps(std::move(web_app_info)); |
| |
| Browser* browser = LaunchWebAppBrowserAndWait(app_id); |
| |
| EXPECT_EQ(GetAppIdFromApplicationName(browser->app_name()), app_id); |
| EXPECT_TRUE(browser->app_controller()); |
| NavigateToURLAndWait(browser, example_url); |
| |
| Histograms histograms; |
| histograms[kHistogramInWindow] = true; |
| histograms[kHistogramUserInstalled_InWindow] = true; |
| histograms[kHistogramUpToThreeUserInstalledApps] = true; |
| |
| ExpectBucketCounts(tester, histograms, |
| site_engagement::EngagementType::kWebappShortcutLaunch, 1); |
| ExpectBucketCounts(tester, histograms, |
| site_engagement::EngagementType::kNavigation, 1); |
| ExpectTotalCounts(tester, ~histograms, 0); |
| TestEngagementEventsAfterLaunch(histograms, browser); |
| ExpectLaunchCounts(tester, /*windowLaunches=*/1, /*tabLaunches=*/0); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(WebAppEngagementBrowserTest, TwoApps) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| base::HistogramTester tester; |
| |
| const GURL example_url1 = |
| embedded_test_server()->GetURL("/banners/no_manifest_test_page.html"); |
| const GURL example_url2 = |
| embedded_test_server()->GetURL("/banners/scope_a/page_1.html"); |
| |
| AppId app_id1, app_id2; |
| |
| // Install two apps. |
| { |
| auto web_app_info = std::make_unique<WebAppInstallInfo>(); |
| web_app_info->start_url = example_url1; |
| web_app_info->scope = example_url1; |
| app_id1 = InstallWebAppAndCountApps(std::move(web_app_info)); |
| } |
| { |
| auto web_app_info = std::make_unique<WebAppInstallInfo>(); |
| web_app_info->start_url = example_url2; |
| web_app_info->scope = example_url2; |
| app_id2 = InstallWebAppAndCountApps(std::move(web_app_info)); |
| } |
| |
| // Launch them three times. This ensures that each launch only logs once. |
| // (Since all apps receive the notification on launch, there is a danger that |
| // we might log too many times.) |
| Browser* app_browser1 = LaunchWebAppBrowserAndWait(app_id1); |
| Browser* app_browser2 = LaunchWebAppBrowserAndWait(app_id1); |
| Browser* app_browser3 = LaunchWebAppBrowserAndWait(app_id2); |
| |
| EXPECT_EQ(GetAppIdFromApplicationName(app_browser1->app_name()), app_id1); |
| EXPECT_EQ(GetAppIdFromApplicationName(app_browser2->app_name()), app_id1); |
| EXPECT_EQ(GetAppIdFromApplicationName(app_browser3->app_name()), app_id2); |
| |
| Histograms histograms; |
| histograms[kHistogramInWindow] = true; |
| histograms[kHistogramUserInstalled_InWindow] = true; |
| histograms[kHistogramUpToThreeUserInstalledApps] = true; |
| |
| ExpectBucketCounts(tester, histograms, |
| site_engagement::EngagementType::kWebappShortcutLaunch, 3); |
| ExpectBucketCounts(tester, histograms, |
| site_engagement::EngagementType::kNavigation, 3); |
| ExpectTotalCounts(tester, ~histograms, 0); |
| ExpectLaunchCounts(tester, /*windowLaunches=*/3, /*tabLaunches=*/0); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(WebAppEngagementBrowserTest, ManyUserApps) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| base::HistogramTester tester; |
| |
| // More than 3 user-installed apps: |
| const int num_user_apps = 4; |
| |
| // A small number of launches, to avoid timeouts. |
| const int num_launches = 2; |
| |
| std::vector<AppId> app_ids; |
| |
| // Install apps. |
| const std::string base_url = |
| embedded_test_server()->GetURL("/banners/many_apps/app").spec(); |
| for (int i = 0; i < num_user_apps; ++i) { |
| const GURL url = GetUrlForSuffix(base_url, i); |
| |
| auto web_app_info = std::make_unique<WebAppInstallInfo>(); |
| web_app_info->start_url = url; |
| web_app_info->scope = url; |
| AppId app_id = InstallWebAppAndCountApps(std::move(web_app_info)); |
| app_ids.push_back(app_id); |
| } |
| |
| // Launch an app in a window. |
| DCHECK_LE(num_launches, num_user_apps); |
| for (int i = 0; i < num_launches; ++i) { |
| Browser* browser = LaunchWebAppBrowserAndWait(app_ids[i]); |
| |
| const GURL url = GetUrlForSuffix(base_url, i); |
| NavigateToURLAndWait(browser, url); |
| } |
| |
| Histograms histograms; |
| histograms[kHistogramInWindow] = true; |
| histograms[kHistogramUserInstalled_InWindow] = true; |
| histograms[kHistogramMoreThanThreeUserInstalledApps] = true; |
| |
| ExpectBucketCounts(tester, histograms, |
| site_engagement::EngagementType::kWebappShortcutLaunch, |
| num_launches); |
| ExpectBucketCounts(tester, histograms, |
| site_engagement::EngagementType::kNavigation, |
| num_launches); |
| ExpectTotalCounts(tester, ~histograms, 0); |
| ExpectLaunchCounts(tester, /*windowLaunches=*/num_launches, |
| /*tabLaunches=*/0); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(WebAppEngagementBrowserTest, DefaultApp) { |
| base::HistogramTester tester; |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| |
| GURL example_url( |
| embedded_test_server()->GetURL("/banners/manifest_test_page.html")); |
| InstallDefaultAppAndCountApps(CreateInstallOptions(example_url)); |
| ASSERT_EQ(webapps::InstallResultCode::kSuccessNewInstall, |
| result_code_.value()); |
| |
| absl::optional<AppId> app_id = FindAppWithUrlInScope(example_url); |
| ASSERT_TRUE(app_id); |
| // TODO(ericwilligers): Assert app_id was installed by default. |
| |
| Browser* browser = LaunchWebAppBrowserAndWait(*app_id); |
| NavigateToURLAndWait(browser, example_url); |
| |
| Histograms histograms; |
| histograms[kHistogramInWindow] = true; |
| histograms[kHistogramDefaultInstalled_InWindow] = true; |
| histograms[kHistogramNoUserInstalledApps] = true; |
| |
| ExpectBucketCounts(tester, histograms, |
| site_engagement::EngagementType::kWebappShortcutLaunch, 1); |
| ExpectBucketCounts(tester, histograms, |
| site_engagement::EngagementType::kNavigation, 1); |
| ExpectTotalCounts(tester, ~histograms, 0); |
| NavigateToURLAndWait(browser, example_url); |
| TestEngagementEventsAfterLaunch(histograms, browser); |
| ExpectLaunchCounts(tester, /*windowLaunches=*/1, /*tabLaunches=*/0); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(WebAppEngagementBrowserTest, NavigateAwayFromAppTab) { |
| base::HistogramTester tester; |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| |
| const GURL start_url = |
| embedded_test_server()->GetURL("/banners/scope_a/page_1.html"); |
| const GURL outer_url = |
| embedded_test_server()->GetURL("/banners/manifest_test_page.html"); |
| |
| auto web_app_info = std::make_unique<WebAppInstallInfo>(); |
| web_app_info->start_url = start_url; |
| web_app_info->scope = start_url; |
| web_app_info->user_display_mode = UserDisplayMode::kBrowser; |
| AppId app_id = InstallWebAppAndCountApps(std::move(web_app_info)); |
| |
| Browser* browser = LaunchBrowserForWebAppInTab(app_id); |
| EXPECT_FALSE(browser->app_controller()); |
| |
| NavigateToURLAndWait(browser, start_url); |
| { |
| Histograms histograms; |
| histograms[kHistogramInTab] = true; |
| histograms[kHistogramUserInstalled_InTab] = true; |
| histograms[kHistogramUpToThreeUserInstalledApps] = true; |
| TestEngagementEventsAfterLaunch(histograms, browser); |
| } |
| |
| // Navigate away from the web app to an outer simple web site: |
| NavigateToURLAndWait(browser, outer_url); |
| { |
| Histograms histograms; |
| histograms[kHistogramUpToThreeUserInstalledApps] = true; |
| TestEngagementEventsAfterLaunch(histograms, browser); |
| } |
| ExpectLaunchCounts(tester, /*windowLaunches=*/0, /*tabLaunches=*/1); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(WebAppEngagementBrowserTest, RecordedForNonApps) { |
| base::HistogramTester tester; |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| CountUserInstalledApps(); |
| |
| // Launch a non-app tab in default browser. |
| const GURL example_url = |
| embedded_test_server()->GetURL("/banners/no_manifest_test_page.html"); |
| NavigateToURLAndWait(browser(), example_url); |
| |
| // Check that no histograms recorded, e.g. no |
| // SiteEngagementService::ENGAGEMENT_WEBAPP_SHORTCUT_LAUNCH. |
| Histograms histograms; |
| ExpectTotalCounts(tester, ~histograms, 0); |
| |
| // The engagement broken down by the number of apps installed must be recorded |
| // for all engagement events. |
| histograms[kHistogramNoUserInstalledApps] = true; |
| TestEngagementEventsAfterLaunch(histograms, browser()); |
| } |
| |
| // On Chrome OS, PWAs are launched via the app service rather than via command |
| // line flags. |
| #if !BUILDFLAG(IS_CHROMEOS) |
| IN_PROC_BROWSER_TEST_F(WebAppEngagementBrowserTest, CommandLineWindowByUrl) { |
| base::HistogramTester tester; |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| |
| // There should be one browser to start with. |
| unsigned int expected_browsers = 1; |
| const int expected_tabs = 1; |
| EXPECT_EQ(expected_browsers, chrome::GetBrowserCount(browser()->profile())); |
| EXPECT_EQ(expected_tabs, browser()->tab_strip_model()->count()); |
| |
| const GURL example_url( |
| embedded_test_server()->GetURL("/banners/manifest_test_page.html")); |
| |
| auto result = ExternallyManagedAppManagerInstall( |
| browser()->profile(), CreateInstallOptions(example_url)); |
| ASSERT_EQ(webapps::InstallResultCode::kSuccessNewInstall, result.code); |
| absl::optional<AppId> app_id = FindAppWithUrlInScope(example_url); |
| ASSERT_TRUE(app_id); |
| content::CreateAndLoadWebContentsObserver app_loaded_observer; |
| |
| base::CommandLine command_line(base::CommandLine::NO_PROGRAM); |
| command_line.AppendSwitchASCII(switches::kApp, example_url.spec()); |
| |
| // The app should open as a window. |
| EXPECT_TRUE(StartupBrowserCreator().ProcessCmdLineImpl( |
| command_line, base::FilePath(), chrome::startup::IsProcessStartup::kNo, |
| {browser()->profile(), StartupProfileMode::kBrowserWindow}, {})); |
| app_loaded_observer.Wait(); |
| |
| Browser* const app_browser = BrowserList::GetInstance()->GetLastActive(); |
| EXPECT_TRUE(app_browser->is_type_app()); |
| |
| { |
| // From c/b/ui/startup/launch_mode_recorder.h: |
| constexpr char kLaunchModesHistogram[] = "Launch.Modes"; |
| const base::HistogramBase::Sample LM_AS_WEBAPP_WINDOW_BY_URL = 23; |
| |
| tester.ExpectUniqueSample(kLaunchModesHistogram, LM_AS_WEBAPP_WINDOW_BY_URL, |
| 1); |
| } |
| |
| // Check that the number of browsers and tabs is correct. |
| expected_browsers++; |
| |
| EXPECT_EQ(expected_browsers, chrome::GetBrowserCount(browser()->profile())); |
| EXPECT_EQ(expected_tabs, browser()->tab_strip_model()->count()); |
| EXPECT_EQ(expected_tabs, app_browser->tab_strip_model()->count()); |
| } |
| |
| // TODO(crbug.com/1382269): Flaky on Mac. |
| #if BUILDFLAG(IS_MAC) |
| #define MAYBE_CommandLineWindowByAppId DISABLED_CommandLineWindowByAppId |
| #else |
| #define MAYBE_CommandLineWindowByAppId CommandLineWindowByAppId |
| #endif |
| IN_PROC_BROWSER_TEST_F(WebAppEngagementBrowserTest, |
| MAYBE_CommandLineWindowByAppId) { |
| base::HistogramTester tester; |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| |
| // There should be one browser to start with. |
| unsigned int expected_browsers = 1; |
| const int expected_tabs = 1; |
| EXPECT_EQ(expected_browsers, chrome::GetBrowserCount(browser()->profile())); |
| EXPECT_EQ(expected_tabs, browser()->tab_strip_model()->count()); |
| |
| const GURL example_url( |
| embedded_test_server()->GetURL("/banners/manifest_test_page.html")); |
| |
| auto result = ExternallyManagedAppManagerInstall( |
| browser()->profile(), CreateInstallOptions(example_url)); |
| ASSERT_EQ(webapps::InstallResultCode::kSuccessNewInstall, result.code); |
| absl::optional<AppId> app_id = FindAppWithUrlInScope(example_url); |
| ASSERT_TRUE(app_id); |
| content::CreateAndLoadWebContentsObserver app_loaded_observer; |
| |
| base::CommandLine command_line(base::CommandLine::NO_PROGRAM); |
| command_line.AppendSwitchASCII(switches::kAppId, *app_id); |
| |
| // The app should open as a window. |
| EXPECT_TRUE(StartupBrowserCreator().ProcessCmdLineImpl( |
| command_line, base::FilePath(), chrome::startup::IsProcessStartup::kNo, |
| {browser()->profile(), StartupProfileMode::kBrowserWindow}, {})); |
| app_loaded_observer.Wait(); |
| |
| Browser* const app_browser = BrowserList::GetInstance()->GetLastActive(); |
| EXPECT_EQ(app_browser->type(), Browser::TYPE_APP); |
| EXPECT_TRUE(app_browser->app_controller()); |
| EXPECT_TRUE(AppBrowserController::IsWebApp(app_browser)); |
| |
| { |
| // From c/b/ui/startup/launch_mode_recorder.h: |
| constexpr char kLaunchModesHistogram[] = "Launch.Modes"; |
| const base::HistogramBase::Sample LM_AS_WEBAPP_WINDOW_BY_APP_ID = 24; |
| |
| tester.ExpectUniqueSample(kLaunchModesHistogram, |
| LM_AS_WEBAPP_WINDOW_BY_APP_ID, 1); |
| } |
| |
| // Check that the number of browsers and tabs is correct. |
| expected_browsers++; |
| |
| EXPECT_EQ(expected_browsers, chrome::GetBrowserCount(browser()->profile())); |
| EXPECT_EQ(expected_tabs, browser()->tab_strip_model()->count()); |
| EXPECT_EQ(expected_tabs, app_browser->tab_strip_model()->count()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(WebAppEngagementBrowserTest, CommandLineTab) { |
| base::HistogramTester tester; |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| |
| // There should be one browser to start with. |
| const unsigned int expected_browsers = 1; |
| int expected_tabs = 1; |
| EXPECT_EQ(expected_browsers, chrome::GetBrowserCount(browser()->profile())); |
| EXPECT_EQ(expected_tabs, browser()->tab_strip_model()->count()); |
| |
| const GURL example_url( |
| embedded_test_server()->GetURL("/banners/manifest_test_page.html")); |
| |
| ExternalInstallOptions install_options = CreateInstallOptions(example_url); |
| install_options.user_display_mode = UserDisplayMode::kBrowser; |
| auto result = |
| ExternallyManagedAppManagerInstall(browser()->profile(), install_options); |
| ASSERT_EQ(webapps::InstallResultCode::kSuccessNewInstall, result.code); |
| absl::optional<AppId> app_id = FindAppWithUrlInScope(example_url); |
| ASSERT_TRUE(app_id); |
| content::CreateAndLoadWebContentsObserver app_loaded_observer; |
| |
| base::CommandLine command_line(base::CommandLine::NO_PROGRAM); |
| command_line.AppendSwitchASCII(switches::kAppId, *app_id); |
| |
| // The app should open as a tab. |
| EXPECT_TRUE(StartupBrowserCreator().ProcessCmdLineImpl( |
| command_line, base::FilePath(), chrome::startup::IsProcessStartup::kNo, |
| {browser()->profile(), StartupProfileMode::kBrowserWindow}, {})); |
| app_loaded_observer.Wait(); |
| |
| { |
| // From startup_browser_creator_impl.cc: |
| constexpr char kLaunchModesHistogram[] = "Launch.Modes"; |
| const base::HistogramBase::Sample LM_AS_WEBAPP_IN_TAB = 21; |
| |
| tester.ExpectUniqueSample(kLaunchModesHistogram, LM_AS_WEBAPP_IN_TAB, 1); |
| } |
| |
| // Check that the number of browsers and tabs is correct. |
| expected_tabs++; |
| |
| EXPECT_EQ(expected_browsers, chrome::GetBrowserCount(browser()->profile())); |
| EXPECT_EQ(expected_tabs, browser()->tab_strip_model()->count()); |
| } |
| #endif |
| |
| } // namespace web_app |