0

[Extensions] Send users to a different chrome webstore URL.

This changes this for the visit chrome webstore button in the extensions
menu in the app menu and the chrome://extensions sidebar.

This is behind a finch feature flag and is disabled by default.

Bug: 1488136
Change-Id: Ida1b0e8deabc0fbb2937cf065d588690848f2773
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4906476
Commit-Queue: Justin Lulejian <jlulejian@chromium.org>
Reviewed-by: David Bertoni <dbertoni@chromium.org>
Auto-Submit: Justin Lulejian <jlulejian@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1205953}
This commit is contained in:
Justin Lulejian
2023-10-05 18:37:02 +00:00
committed by Chromium LUCI CQ
parent 98818e3c72
commit 7b02a30982
8 changed files with 125 additions and 11 deletions

@ -54,6 +54,7 @@
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "extensions/browser/extension_prefs.h" #include "extensions/browser/extension_prefs.h"
#include "extensions/common/constants.h" #include "extensions/common/constants.h"
#include "extensions/common/extension_features.h"
#include "extensions/common/extension_urls.h" #include "extensions/common/extension_urls.h"
#include "net/base/url_util.h" #include "net/base/url_util.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
@ -508,9 +509,14 @@ void ShowSearchEngineSettings(Browser* browser) {
} }
void ShowWebStore(Browser* browser, const base::StringPiece& utm_source_value) { void ShowWebStore(Browser* browser, const base::StringPiece& utm_source_value) {
GURL webstore_url = extension_urls::GetWebstoreLaunchURL();
// TODO(crbug.com/1488136): Refactor this check into
// extension_urls::GetWebstoreLaunchURL() and fix tests relying on it.
if (base::FeatureList::IsEnabled(extensions_features::kNewWebstoreURL)) {
webstore_url = extension_urls::GetNewWebstoreLaunchURL();
}
ShowSingletonTabIgnorePathOverwriteNTP( ShowSingletonTabIgnorePathOverwriteNTP(
browser, extension_urls::AppendUtmSource( browser, extension_urls::AppendUtmSource(webstore_url, utm_source_value));
extension_urls::GetWebstoreLaunchURL(), utm_source_value));
} }
void ShowPrivacySandboxSettings(Browser* browser) { void ShowPrivacySandboxSettings(Browser* browser) {

@ -26,6 +26,7 @@
#include "components/password_manager/core/common/password_manager_features.h" #include "components/password_manager/core/common/password_manager_features.h"
#include "components/performance_manager/public/features.h" #include "components/performance_manager/public/features.h"
#include "content/public/test/browser_test.h" #include "content/public/test/browser_test.h"
#include "extensions/common/extension_features.h"
#include "extensions/common/extension_urls.h" #include "extensions/common/extension_urls.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/interaction/element_identifier.h" #include "ui/base/interaction/element_identifier.h"
@ -197,19 +198,63 @@ IN_PROC_BROWSER_TEST_F(ExtensionsMenuModelInteractiveTest, ManageExtensions) {
MENU_ACTION_VISIT_CHROME_WEB_STORE, 0); MENU_ACTION_VISIT_CHROME_WEB_STORE, 0);
} }
// Test to confirm that the visit Chome Web Store menu item navigates when // TODO(crbug.com/1488136): Remove this test in favor of a unit test
// selected and emits histograms that it did so. // extension_urls::GetWebstoreLaunchURL().
IN_PROC_BROWSER_TEST_F(ExtensionsMenuModelInteractiveTest, class ExtensionsMenuVisitChromeWebstoreModelInteractiveTest
: public AppMenuModelInteractiveTest,
public testing::WithParamInterface<bool> {
public:
ExtensionsMenuVisitChromeWebstoreModelInteractiveTest() {
std::vector<base::test::FeatureRef> enabled_features = {
features::kExtensionsMenuInAppMenu};
std::vector<base::test::FeatureRef> disabled_features{};
if (GetParam()) {
enabled_features.push_back(extensions_features::kNewWebstoreURL);
} else {
LOG(ERROR) << "disabling new webstore URL";
disabled_features.push_back(extensions_features::kNewWebstoreURL);
}
scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features);
}
void SetUp() override {
set_open_about_blank_on_browser_launch(true);
ASSERT_TRUE(embedded_test_server()->InitializeAndListen());
InteractiveBrowserTest::SetUp();
}
protected:
base::HistogramTester histograms;
};
INSTANTIATE_TEST_SUITE_P(
All,
ExtensionsMenuVisitChromeWebstoreModelInteractiveTest,
// extensions_features::kNewWebstoreURL enabled status.
testing::Bool(),
[](const testing::TestParamInfo<ExtensionsMenuModelPresenceTest::ParamType>&
info) {
return info.param ? "NewVisitChromeWebstoreUrl"
: "OldVisitChromeWebstoreUrl";
});
// Test to confirm that the visit Chrome Web Store menu item navigates to the
// correct chrome webstore URL when selected and emits histograms that it did
// so.
IN_PROC_BROWSER_TEST_P(ExtensionsMenuVisitChromeWebstoreModelInteractiveTest,
VisitChromeWebStore) { VisitChromeWebStore) {
GURL expected_webstore_launch_url =
GetParam() ? extension_urls::GetNewWebstoreLaunchURL()
: extension_urls::GetWebstoreLaunchURL();
RunTestSequence( RunTestSequence(
InstrumentTab(kPrimaryTabPageElementId), InstrumentTab(kPrimaryTabPageElementId),
PressButton(kToolbarAppMenuButtonElementId), PressButton(kToolbarAppMenuButtonElementId),
SelectMenuItem(AppMenuModel::kExtensionsMenuItem), SelectMenuItem(AppMenuModel::kExtensionsMenuItem),
SelectMenuItem(ExtensionsMenuModel::kVisitChromeWebStoreMenuItem), SelectMenuItem(ExtensionsMenuModel::kVisitChromeWebStoreMenuItem),
WaitForWebContentsNavigation(kPrimaryTabPageElementId, WaitForWebContentsNavigation(
extension_urls::AppendUtmSource( kPrimaryTabPageElementId,
extension_urls::GetWebstoreLaunchURL(), extension_urls::AppendUtmSource(expected_webstore_launch_url,
extension_urls::kAppMenuUtmSource))); extension_urls::kAppMenuUtmSource)));
histograms.ExpectTotalCount("WrenchMenu.TimeToAction.VisitChromeWebStore", 1); histograms.ExpectTotalCount("WrenchMenu.TimeToAction.VisitChromeWebStore", 1);
histograms.ExpectTotalCount("WrenchMenu.TimeToAction.ManageExtensions", 0); histograms.ExpectTotalCount("WrenchMenu.TimeToAction.ManageExtensions", 0);

@ -576,6 +576,7 @@ source_set("unit_tests") {
"extension_resource_unittest.cc", "extension_resource_unittest.cc",
"extension_set_unittest.cc", "extension_set_unittest.cc",
"extension_unittest.cc", "extension_unittest.cc",
"extension_urls_unittest.cc",
"feature_switch_unittest.cc", "feature_switch_unittest.cc",
"features/complex_feature_unittest.cc", "features/complex_feature_unittest.cc",
"features/feature_provider_unittest.cc", "features/feature_provider_unittest.cc",

@ -209,4 +209,11 @@ BASE_FEATURE(kExtensionsServiceWorkerOptimizedEventDispatch,
"ExtensionsServiceWorkerOptimizedEventDispatch", "ExtensionsServiceWorkerOptimizedEventDispatch",
base::FEATURE_DISABLED_BY_DEFAULT); base::FEATURE_DISABLED_BY_DEFAULT);
// If enabled, the button for visiting the chrome webstore in both the
// extensions menu in the app menu and the chrome://extensions sidebar will send
// the user to the new chrome webstore URL.
BASE_FEATURE(kNewWebstoreURL,
"NewWebstoreURL",
base::FEATURE_DISABLED_BY_DEFAULT);
} // namespace extensions_features } // namespace extensions_features

@ -103,6 +103,8 @@ BASE_DECLARE_FEATURE(kExtensionsZipFileInstalledInProfileDir);
BASE_DECLARE_FEATURE(kExtensionsServiceWorkerOptimizedEventDispatch); BASE_DECLARE_FEATURE(kExtensionsServiceWorkerOptimizedEventDispatch);
BASE_DECLARE_FEATURE(kNewWebstoreURL);
} // namespace extensions_features } // namespace extensions_features
#endif // EXTENSIONS_COMMON_EXTENSION_FEATURES_H_ #endif // EXTENSIONS_COMMON_EXTENSION_FEATURES_H_

@ -9,6 +9,7 @@
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "extensions/common/constants.h" #include "extensions/common/constants.h"
#include "extensions/common/extension_features.h"
#include "extensions/common/extensions_client.h" #include "extensions/common/extensions_client.h"
#include "net/base/url_util.h" #include "net/base/url_util.h"
#include "url/gurl.h" #include "url/gurl.h"
@ -59,6 +60,11 @@ GURL AppendUtmSource(const GURL& url,
// TODO(devlin): Try to use GURL methods like Resolve instead of string // TODO(devlin): Try to use GURL methods like Resolve instead of string
// concatenation. // concatenation.
std::string GetWebstoreExtensionsCategoryURL() { std::string GetWebstoreExtensionsCategoryURL() {
// TODO(crbug.com/1488136): Refactor this check into
// extension_urls::GetWebstoreLaunchURL() and fix tests relying on it.
if (base::FeatureList::IsEnabled(extensions_features::kNewWebstoreURL)) {
return GetNewWebstoreLaunchURL().spec() + "category/extensions";
}
return GetWebstoreLaunchURL().spec() + "/category/extensions"; return GetWebstoreLaunchURL().spec() + "/category/extensions";
} }

@ -52,8 +52,8 @@ GURL GetNewWebstoreLaunchURL();
GURL AppendUtmSource(const GURL& url, GURL AppendUtmSource(const GURL& url,
const base::StringPiece& utm_source_value); const base::StringPiece& utm_source_value);
// Returns the URL to the extensions category on the Web Store. This is // Returns the URL to the extensions category on the old and new Web Store
// derived from GetWebstoreLaunchURL(). // depending on extensions_features::kNewWebstoreURL feature flag.
std::string GetWebstoreExtensionsCategoryURL(); std::string GetWebstoreExtensionsCategoryURL();
// Returns the URL prefix for an item in the extension/app gallery. This URL // Returns the URL prefix for an item in the extension/app gallery. This URL

@ -0,0 +1,47 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "extensions/common/extension_urls.h"
#include "base/test/scoped_feature_list.h"
#include "extensions/common/extension_features.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace extension_urls {
namespace {
class ExtensionWebstoreURLsTest : public testing::Test,
public testing::WithParamInterface<bool> {
public:
explicit ExtensionWebstoreURLsTest(bool enable_new_webstore_url = false) {
if (GetParam()) {
scoped_feature_list_.InitAndEnableFeature(
extensions_features::kNewWebstoreURL);
}
}
protected:
base::test::ScopedFeatureList scoped_feature_list_;
};
INSTANTIATE_TEST_SUITE_P(NewChromeWebstoreLaunchUrl,
ExtensionWebstoreURLsTest,
testing::Values(true));
INSTANTIATE_TEST_SUITE_P(PreviousChromeWebstoreLaunchUrl,
ExtensionWebstoreURLsTest,
testing::Values(false));
} // namespace
// Tests that the correct extensions webstore category URL is returned depending
// on feature extensions_features::kNewWebstoreURL.
TEST_P(ExtensionWebstoreURLsTest, GetNewWebstoreExtensionsCategoryURL) {
const std::string expected_category_url =
GetParam() ? GetNewWebstoreLaunchURL().spec() + "category/extensions"
: GetWebstoreLaunchURL().spec() + "/category/extensions";
EXPECT_EQ(expected_category_url, GetWebstoreExtensionsCategoryURL());
}
} // namespace extension_urls