c5f13703827e3e250f52b9be54b1898f0fdcd3d3 - chromium/src

132 views
Skip to first unread message

yuezh...@chromium.org

unread,
Mar 24, 2021, 1:15:06 AM3/24/21
to chromium...@chromium.org
commit c5f13703827e3e250f52b9be54b1898f0fdcd3d3
Author: Yue Zhang <yuezh...@chromium.org>
AuthorDate: Wed Mar 24 05:14:43 2021
Commit: Chromium LUCI CQ <chromiu...@luci-project-accounts.iam.gserviceaccount.com>
CommitDate: Wed Mar 24 05:14:43 2021

[ChromeCart] Improve cart visit detection heuristics

This CL improves cart visit detection heuristics by upstreaming https://colab.corp.google.com/drive/1Z8xrIRYK5SX20mVDDdlvk9n4DLpJ67-o?usp=sharing.
To verify the heuristics remain correct during upstream, we generate test URLs via https://colab.corp.google.com/drive/1CC46Fw6Eiua840gTxa3dwyg9pNSd_5_K?usp=sharing.

Bug: 1189786
Change-Id: Ieb02100ed5839e6cf8529144940100a8dd9158b8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2774935
Commit-Queue: Yue Zhang <yuezh...@chromium.org>
Reviewed-by: Wei-Yin Chen (陳威尹) <wyc...@chromium.org>
Reviewed-by: Yaron Friedman <yfri...@chromium.org>
Cr-Commit-Position: refs/heads/master@{#865986}

diff --git a/chrome/browser/cart/resources/cart_domain_cart_url_mapping.json b/chrome/browser/cart/resources/cart_domain_cart_url_mapping.json
index 8d805c0..e320358 100644
--- a/chrome/browser/cart/resources/cart_domain_cart_url_mapping.json
+++ b/chrome/browser/cart/resources/cart_domain_cart_url_mapping.json
@@ -5,5 +5,6 @@
"hm.com": "https://www2.hm.com/en_us/cart",
"etsy.com": "https://www.etsy.com/cart",
"bestbuy.com": "https://www.bestbuy.com/cart",
-"homedepot.com": "https://www.homedepot.com/mycart/home"
+"homedepot.com": "https://www.homedepot.com/mycart/home",
+"guitarcenter.com":"https://www.guitarcenter.com/cart"
}
\ No newline at end of file
diff --git a/chrome/renderer/cart/commerce_hint_agent.cc b/chrome/renderer/cart/commerce_hint_agent.cc
index fe049a7..d8f87f5 100644
--- a/chrome/renderer/cart/commerce_hint_agent.cc
+++ b/chrome/renderer/cart/commerce_hint_agent.cc
@@ -4,6 +4,7 @@

#include "chrome/renderer/cart/commerce_hint_agent.h"

+#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/metrics/field_trial_params.h"
#include "base/no_destructor.h"
@@ -41,8 +42,6 @@
constexpr unsigned kLengthLimit = 4096;
constexpr char kAmazonDomain[] = "amazon.com";
constexpr char kEbayDomain[] = "ebay.com";
-constexpr char kAppleDomain[] = "apple.com";
-constexpr char kMacysDomain[] = "macys.com";

constexpr base::FeatureParam<std::string> kSkipPattern{
&ntp_features::kNtpChromeCartModule, "product-skip-pattern",
@@ -171,37 +170,60 @@
return *instance;
}

-// The heuristics of cart pages are from top 30 US shopping domains.
-// https://colab.corp.google.com/drive/1ANuCcRphLieSbhy5t05IEnOYLT5RmEdf#scrollTo=k9Sh9VvodKQx
-const re2::RE2& GetVisitCartPatternAmazon() {
- static base::NoDestructor<re2::RE2> instance(
- "^/(-/[A-Za-z_-]+/)?gp/((.*/)?cart(/.*)?)(/|$)");
- return *instance;
-}
-
-const re2::RE2& GetVisitCartPatternApple() {
- static base::NoDestructor<re2::RE2> instance("/([^/]+/)?shop/([^/]+/)?bag$");
- return *instance;
-}
-
-const re2::RE2& GetVisitCartPatternMacy() {
- static base::NoDestructor<re2::RE2> instance("/(my-bag|bag(/[^/]+)*.ognc)$");
- return *instance;
-}
-
-const re2::RE2& GetVisitCartPattern() {
- re2::RE2::Options options;
+// The heuristics of cart pages are from top 100 US shopping domains.
+// https://colab.corp.google.com/drive/1fTGE_SQw_8OG4ubzQvWcBuyHEhlQ-pwQ?usp=sharing
+// TODO(crbug.com/1189786): Using per-site pattern and full URL matching could
+// be unnecessary. Improve this later by using general pattern if possible and
+// more flexible matching.
+const re2::RE2& GetVisitCartPattern(const GURL& url) {
+ static base::NoDestructor<std::map<std::string, std::string>>
+ heuristic_string_map([] {
+ const base::StringPiece json_resource(
+ ui::ResourceBundle::GetSharedInstance().GetRawDataResource(
+ IDR_CART_DOMAIN_CART_URL_REGEX_JSON));
+ const base::NoDestructor<base::Value> json(
+ base::JSONReader::Read(json_resource).value());
+ DCHECK(json->is_dict());
+ std::map<std::string, std::string> map;
+ for (const auto& item : json->DictItems()) {
+ map.insert(
+ {std::move(item.first), std::move(item.second.GetString())});
+ }
+ return map;
+ }());
+ static base::NoDestructor<std::map<std::string, std::unique_ptr<re2::RE2>>>
+ heuristic_regex_map;
+ static re2::RE2::Options options;
options.set_case_sensitive(false);
- static base::NoDestructor<re2::RE2> instance(
- "(/(my|co-|shopping[-_]?)?(cart|bag)(view)?(/|\\.|$|\\?))"
- "|"
- "(/checkout/([^/]+/)?(basket|bag)(/|\\.|$))"
- "|"
- "(/checkoutcart(display)?view(/|\\.|$))"
- "|"
- "(/bundles/shop(/|\\.|$))",
- options);
- return *instance;
+ const std::string& domain = eTLDPlusOne(url);
+ if (heuristic_string_map->find(domain) == heuristic_string_map->end()) {
+ // clang-format off
+ static base::NoDestructor<re2::RE2> instance(
+ "(^https?://cart\\.)"
+ "|"
+ "(/("
+ "(((my|co|shopping)[-_]?)?(cart|bag)(view|display)?)"
+ "|"
+ "(checkout/([^/]+/)?(basket|bag))"
+ "|"
+ "(checkoutcart(display)?view)"
+ "|"
+ "(bundles/shop)"
+ "|"
+ "((ajax)?orderitemdisplay(view)?)"
+ "|"
+ "(cart-show)"
+ ")(/|\\.|$))",
+ options);
+ // clang-format on
+ return *instance;
+ }
+ if (heuristic_regex_map->find(domain) == heuristic_regex_map->end()) {
+ heuristic_regex_map->insert(
+ {domain, std::make_unique<re2::RE2>(heuristic_string_map->at(domain),
+ options)});
+ }
+ return *heuristic_regex_map->at(domain);
}

// TODO(crbug/1164236): cover more shopping sites.
@@ -347,22 +369,8 @@
}

bool CommerceHintAgent::IsVisitCart(const GURL& url) {
- if (eTLDPlusOne(url) == kAmazonDomain) {
- return PartialMatch(url.path_piece().substr(0, kLengthLimit),
- GetVisitCartPatternAmazon()) ||
- url.path_piece() == "/gp/aw/c";
- }
- if (eTLDPlusOne(url) == kAppleDomain) {
- return PartialMatch(url.path_piece().substr(0, kLengthLimit),
- GetVisitCartPatternApple());
- }
- if (eTLDPlusOne(url) == kMacysDomain) {
- return PartialMatch(url.path_piece().substr(0, kLengthLimit),
- GetVisitCartPatternMacy());
- }
- return PartialMatch(url.path_piece().substr(0, kLengthLimit),
- GetVisitCartPattern()) ||
- base::StartsWith(url.host_piece(), "cart");
+ return PartialMatch(url.spec().substr(0, kLengthLimit),
+ GetVisitCartPattern(url));
}

bool CommerceHintAgent::IsVisitCheckout(const GURL& url) {
@@ -494,6 +502,8 @@
if (frame->Parent())
return;

+ if (!url.SchemeIs(url::kHttpsScheme))
+ return;
if (IsVisitCart(url) && IsSameDomainXHR(url.host(), request)) {
DVLOG(1) << "In-cart XHR: " << request.Url();
ExtractProducts();
@@ -534,7 +544,7 @@
if (frame->Parent())
return;
const GURL& url(frame->GetDocument().Url());
- if (!url.SchemeIsHTTPOrHTTPS())
+ if (!url.SchemeIs(url::kHttpsScheme))
return;

if (IsVisitCart(url)) {
@@ -564,7 +574,7 @@
if (frame->Parent())
return;
const GURL url(frame->GetDocument().Url());
- if (!url.SchemeIsHTTPOrHTTPS())
+ if (!url.SchemeIs(url::kHttpsScheme))
return;

if (IsVisitCart(url)) {
diff --git a/chrome/renderer/cart/commerce_hint_agent_browsertest.cc b/chrome/renderer/cart/commerce_hint_agent_browsertest.cc
index 3fd8b41..bf8655d 100644
--- a/chrome/renderer/cart/commerce_hint_agent_browsertest.cc
+++ b/chrome/renderer/cart/commerce_hint_agent_browsertest.cc
@@ -13,6 +13,7 @@
#include "chrome/browser/signin/identity_manager_factory.h"
#include "chrome/common/chrome_features.h"
#include "chrome/test/base/chrome_test_utils.h"
+#include "components/network_session_configurator/common/network_switches.h"
#include "components/optimization_guide/core/optimization_guide_features.h"
#include "components/search/ntp_features.h"
#include "components/signin/public/identity_manager/identity_manager.h"
@@ -63,10 +64,11 @@
}
#endif // !BUILDFLAG(IS_CHROMEOS_ASH)

-const char kMockExample[] = "walmart.com";
-const char kMockExampleFallbackURL[] = "https://www.walmart.com/cart";
-const char kMockExampleLinkURL[] = "https://www.walmart.com/shopping-cart/";
-const char kMockExampleURL[] = "http://www.walmart.com/cart.html";
+const char kMockExample[] = "guitarcenter.com";
+const char kMockExampleFallbackURL[] = "https://www.guitarcenter.com/cart";
+const char kMockExampleLinkURL[] =
+ "https://www.guitarcenter.com/shopping-cart/";
+const char kMockExampleURL[] = "https://www.guitarcenter.com/cart.html";

const cart_db::ChromeCartContentProto kMockExampleProtoFallbackCart =
BuildProto(kMockExample, kMockExampleFallbackURL);
@@ -78,8 +80,8 @@
BuildProtoWithProducts(
kMockExample,
kMockExampleURL,
- {"https://static.walmart.com/product-image/123.png",
- "https://static.walmart.com/product-image/456.png"});
+ {"https://static.guitarcenter.com/product-image/123.png",
+ "https://static.guitarcenter.com/product-image/456.png"});

const char kMockAmazon[] = "amazon.com";
const char kMockAmazonURL[] = "https://www.amazon.com/gp/cart/view.html";
@@ -123,6 +125,12 @@
{{"product-skip-pattern", "(^|\\W)(?i)(skipped)(\\W|$)"}});
}

+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ // HTTPS server only serves a valid cert for localhost, so this is needed
+ // to load pages from other hosts without an error.
+ command_line->AppendSwitch(switches::kIgnoreCertificateErrors);
+ }
+
void SetUpOnMainThread() override {
PlatformBrowserTest::SetUpOnMainThread();
Profile* profile =
@@ -135,12 +143,10 @@
// This is necessary to test non-localhost domains. See |NavigateToURL|.
host_resolver()->AddRule("*", "127.0.0.1");

- embedded_test_server()->ServeFilesFromSourceDirectory(
- "chrome/test/data/cart/");
- embedded_test_server()->RegisterRequestHandler(
- base::BindRepeating(&BasicResponse));
- ASSERT_TRUE(embedded_test_server()->InitializeAndListen());
- embedded_test_server()->StartAcceptingConnections();
+ https_server_.ServeFilesFromSourceDirectory("chrome/test/data/cart/");
+ https_server_.RegisterRequestHandler(base::BindRepeating(&BasicResponse));
+ ASSERT_TRUE(https_server_.InitializeAndListen());
+ https_server_.StartAcceptingConnections();
}

protected:
@@ -152,8 +158,7 @@
// All domains resolve to 127.0.0.1 in this test.
GURL gurl(url);
ASSERT_TRUE(content::NavigateToURL(
- web_contents(),
- embedded_test_server()->GetURL(gurl.host(), gurl.path())));
+ web_contents(), https_server_.GetURL(gurl.host(), gurl.path())));
base::RunLoop().RunUntilIdle();
}

@@ -290,27 +295,28 @@

base::test::ScopedFeatureList scoped_feature_list_;
CartService* service_;
+ net::EmbeddedTestServer https_server_{net::EmbeddedTestServer::TYPE_HTTPS};
bool satisfied_;
};

IN_PROC_BROWSER_TEST_F(CommerceHintAgentTest, AddToCartByURL) {
// For add-to-cart by URL, normally a URL in that domain has already been
// committed.
- NavigateToURL("https://www.walmart.com/");
- NavigateToURL("https://www.walmart.com/add-to-cart?product=1");
+ NavigateToURL("https://www.guitarcenter.com/");
+ NavigateToURL("https://www.guitarcenter.com/add-to-cart?product=1");

WaitForCartCount(kExpectedExampleFallbackCart);
}

IN_PROC_BROWSER_TEST_F(CommerceHintAgentTest, AddToCartByForm) {
- NavigateToURL("https://www.walmart.com/");
+ NavigateToURL("https://www.guitarcenter.com/");
SendXHR("/wp-admin/admin-ajax.php", "action: woocommerce_add_to_cart");

WaitForCartCount(kExpectedExampleFallbackCart);
}

IN_PROC_BROWSER_TEST_F(CommerceHintAgentTest, AddToCartByForm_WithLink) {
- NavigateToURL("https://www.walmart.com/product.html");
+ NavigateToURL("https://www.guitarcenter.com/product.html");
SendXHR("/wp-admin/admin-ajax.php", "action: woocommerce_add_to_cart");

WaitForCartCount(kExpectedExampleLinkCart);
@@ -325,7 +331,7 @@
}

IN_PROC_BROWSER_TEST_F(CommerceHintAgentTest, AddToCartByURL_XHR) {
- NavigateToURL("https://www.walmart.com/");
+ NavigateToURL("https://www.guitarcenter.com/");
SendXHR("/add-to-cart", "product: 123");

WaitForCartCount(kExpectedExampleFallbackCart);
@@ -333,28 +339,28 @@

IN_PROC_BROWSER_TEST_F(CommerceHintAgentTest, VisitCart) {
// Cannot use dummy page with zero products, or the cart would be deleted.
- NavigateToURL("https://www.walmart.com/cart.html");
+ NavigateToURL("https://www.guitarcenter.com/cart.html");

WaitForCartCount(kExpectedExample);
}

IN_PROC_BROWSER_TEST_F(CommerceHintAgentTest, ExtractCart) {
// This page has two products.
- NavigateToURL("https://www.walmart.com/cart.html");
+ NavigateToURL("https://www.guitarcenter.com/cart.html");

WaitForProductCount(kExpectedExampleWithProducts);
}

IN_PROC_BROWSER_TEST_F(CommerceHintAgentTest, CartPriority) {
- NavigateToURL("https://www.walmart.com/");
- NavigateToURL("https://www.walmart.com/add-to-cart?product=1");
+ NavigateToURL("https://www.guitarcenter.com/");
+ NavigateToURL("https://www.guitarcenter.com/add-to-cart?product=1");
WaitForCartCount(kExpectedExampleFallbackCart);

- NavigateToURL("https://www.walmart.com/cart.html");
+ NavigateToURL("https://www.guitarcenter.com/cart.html");
WaitForCarts(kExpectedExample);

- NavigateToURL("https://www.walmart.com/");
- NavigateToURL("https://www.walmart.com/add-to-cart?product=1");
+ NavigateToURL("https://www.guitarcenter.com/");
+ NavigateToURL("https://www.guitarcenter.com/add-to-cart?product=1");
WaitForCarts(kExpectedExample);
}

@@ -362,8 +368,8 @@
service_->AddCart(kMockExample, base::nullopt, kMockExampleProto);
WaitForCartCount(kExpectedExampleFallbackCart);

- NavigateToURL("https://www.walmart.com/");
- NavigateToURL("https://www.walmart.com/123/checkout/456");
+ NavigateToURL("https://www.guitarcenter.com/");
+ NavigateToURL("https://www.guitarcenter.com/123/checkout/456");
WaitForCartCount(kEmptyExpected);
}

@@ -381,7 +387,7 @@
service_->AddCart(kMockExample, base::nullopt, kMockExampleProto);
WaitForCartCount(kExpectedExampleFallbackCart);

- NavigateToURL("https://www.walmart.com/purchase.html");
+ NavigateToURL("https://www.guitarcenter.com/purchase.html");

std::string script = "document.getElementById('submit').click()";
ASSERT_TRUE(ExecJs(web_contents(), script));
@@ -401,10 +407,10 @@
auto* identity_manager = IdentityManagerFactory::GetForProfile(profile);
ASSERT_TRUE(identity_manager);
signin::ClearPrimaryAccount(identity_manager);
- NavigateToURL("https://www.walmart.com/cart");
+ NavigateToURL("https://www.guitarcenter.com/cart");
WaitForCartCount(kEmptyExpected);

- NavigateToURL("https://www.walmart.com/");
+ NavigateToURL("https://www.guitarcenter.com/");
SendXHR("/wp-admin/admin-ajax.php", "action: woocommerce_add_to_cart");
WaitForCartCount(kEmptyExpected);

@@ -412,7 +418,7 @@
WaitForCartCount(kEmptyExpected);

signin::SetPrimaryAccount(identity_manager, "us...@gmail.com");
- NavigateToURL("https://www.walmart.com/");
+ NavigateToURL("https://www.guitarcenter.com/");
SendXHR("/add-to-cart", "product: 123");
WaitForCartCount(kExpectedExampleFallbackCart);
}
@@ -425,10 +431,10 @@
ASSERT_TRUE(identity_manager);
ASSERT_EQ(profile_manager->GetNumberOfProfiles(), 1U);
signin::ClearPrimaryAccount(identity_manager);
- NavigateToURL("https://www.walmart.com/cart");
+ NavigateToURL("https://www.guitarcenter.com/cart");
WaitForCartCount(kEmptyExpected);

- NavigateToURL("https://www.walmart.com/");
+ NavigateToURL("https://www.guitarcenter.com/");
SendXHR("/wp-admin/admin-ajax.php", "action: woocommerce_add_to_cart");
WaitForCartCount(kEmptyExpected);

@@ -445,7 +451,7 @@
run_loop.Run();
ASSERT_EQ(profile_manager->GetNumberOfProfiles(), 2U);

- NavigateToURL("https://www.walmart.com/");
+ NavigateToURL("https://www.guitarcenter.com/");
SendXHR("/add-to-cart", "product: 123");
WaitForCartCount(kExpectedExampleFallbackCart);
}
diff --git a/chrome/renderer/cart/commerce_hint_agent_unittest.cc b/chrome/renderer/cart/commerce_hint_agent_unittest.cc
index 2fefea7..39808a7 100644
--- a/chrome/renderer/cart/commerce_hint_agent_unittest.cc
+++ b/chrome/renderer/cart/commerce_hint_agent_unittest.cc
@@ -45,27 +45,618 @@
};

const char* kVisitCart[] = {
- "https://www.amazon.com/gp/aw/c?ref_=navm_hdr_cart",
- "https://smile.amazon.com/gp/aw/c?ref_=navm_hdr_cart",
- "https://www.amazon.com/gp/aws/cart/add.html",
- "https://smile.amazon.com/gp/cart/view.html",
- "https://www.amazon.com/gp/cart/view.html/ref=lh_cart",
- "https://www.amazon.com/-/es/gp/cart/view.html",
- "https://cart.ebay.com/",
- "https://cart.payments.ebay.com/sc/add",
- "https://www.etsy.com/cart/listing.php",
- "https://www.target.com/co-cart",
- "https://secure2.homedepot.com/mycart/home",
- "http://example.com/us/cart/",
- "http://example.com/cart/",
- "https://example.com/cart",
- "http://example.com/cart",
+ // Real cart URLs.
+ "https://www.brownells.com/aspx/Store/Cart.aspx",
+ "https://www.carid.com/cart.php",
+ "https://www.chegg.com/shoppingcart",
+ "https://www.target.com/co-cart",
+ "https://beastacademy.com/checkout/cart",
+ "https://cart.ebay.com/",
+ "https://cart.ebay.com/sc/view",
+ "https://cart.godaddy.com/",
+ "https://cart.godaddy.com/Basket.aspx",
+ "https://cart.godaddy.com/basket.aspx",
+ "https://cart.godaddy.com/go/checkout",
+ "https://cart.godaddy.com/upp/vcart",
+ "https://cart.payments.ebay.com/sc/add",
+ "https://es-store.usps.com/store/cart/cart.jsp",
+ "https://poshmark.com/bundles/shop",
+ "https://secure-athleta.gap.com/shopping-bag",
+ "https://secure-bananarepublic.gap.com/shopping-bag",
+ "https://secure-oldnavy.gap.com/buy/shopping_bag.do",
+ "https://secure-oldnavy.gap.com/shopping-bag",
+ "https://secure-www.gap.com/shopping-bag",
+ "https://secure.newegg.com/Shop/Cart",
+ "https://secure.newegg.com/shop/cart",
+ "https://secure2.homedepot.com/mycart/home",
+ "https://shop.advanceautoparts.com/web/OrderItemDisplay",
+ "https://shop.lululemon.com/shop/mybag",
+ "https://smile.amazon.co.uk/gp/cart/view.html",
+ "https://smile.amazon.com/gp/aw/c?ref_=navm_hdr_cart",
+ "https://smile.amazon.com/gp/cart/view.html",
+ "https://store.bricklink.com/v2/globalcart.page",
+ "https://store.steampowered.com/cart",
+ "https://store.steampowered.com/cart/",
+ "https://store.usps.com/store/cart/cart.jsp",
+ "https://training.atlassian.com/auth/cart",
+ "https://www.abebooks.com/servlet/ShopBasketPL",
+ "https://www.abebooks.com/servlet/ShoppingBasket",
+ "https://www.academy.com/shop/cart",
+ "https://www.acehardware.com/cart",
+ "https://www.adorama.com/Als.Mvc/CartView",
+ "https://www.adorama.com/als.mvc/cartview",
+ "https://www.ae.com/us/en/cart",
+ "https://www.altardstate.com/cart/",
+ "https://www.amazon.co.uk/gp/aws/cart/add.html",
+ "https://www.amazon.co.uk/gp/cart/view.html",
+ "https://www.amazon.co.uk/gp/cart/view.html/ref=chk_logo_return_to_cart",
+ "https://www.amazon.co.uk/gp/cart/view.html/ref=lh_cart",
+ "https://www.amazon.com/-/es/gp/cart/view.html",
+ "https://www.amazon.com/gp/aw/c?ref_=navm_hdr_cart",
+ "https://www.amazon.com/gp/aws/cart/add.html",
+ "https://www.amazon.com/gp/cart/view.html",
+ "https://www.amazon.com/gp/cart/view.html/ref=lh_cart",
+ "https://www.amazon.com/gp/cart/view.html/ref=lh_cart_vc_btn",
+ "https://www.anthropologie.com/cart",
+ "https://www.apple.com/shop/bag",
+ "https://www.apple.com/us-hed/shop/bag",
+ "https://www.apple.com/us/shop/goto/bag",
+ "https://www.apple.com/us_epp_805199/shop/bag",
+ "https://www.atlassian.com/purchase/cart",
+ "https://www.att.com/buy/cart",
+ "https://www.att.com/buy/checkout/cartview",
+ "https://www.backcountry.com/Store/cart/cart.jsp",
+ "https://www.basspro.com/shop/AjaxOrderItemDisplayView",
+ "https://www.bathandbodyworks.com/cart",
+ "https://www.bedbathandbeyond.com/store/cart",
+ "https://www.belk.com/shopping-bag/",
+ "https://www.bestbuy.com/cart",
+ "https://www.bhphotovideo.com/c/find/cart.jsp",
+ "https://www.bhphotovideo.com/find/cart.jsp",
+ "https://www.bhphotovideo.com/find/cart.jsp/mode/edu",
+ "https://www.bloomingdales.com/my-bag",
+ "https://www.boostmobile.com/cart.html",
+ "https://www.bricklink.com/v2/globalcart.page",
+ "https://www.brownells.com/aspx/Store/Cart.aspx",
+ "https://www.brownells.com/aspx/store/cart.aspx",
+ "https://www.buybuybaby.com/store/cart",
+ "https://www.carid.com/cart.php",
+ "https://www.chegg.com/shoppingcart",
+ "https://www.chegg.com/shoppingcart/",
+ "https://www.containerstore.com/cart/list.htm",
+ "https://www.costco.com/CheckoutCartDisplayView",
+ "https://www.costco.com/CheckoutCartView",
+ "https://www.crateandbarrel.com/Checkout/Cart",
+ "https://www.crateandbarrel.com/checkout/cart",
+ "https://www.dickssportinggoods.com/OrderItemDisplay",
+ "https://www.dillards.com/webapp/wcs/stores/servlet/OrderItemDisplay",
+ "https://www.dsw.com/en/us/shopping-bag",
+ "https://www.etsy.com/cart",
+ "https://www.etsy.com/cart/",
+ "https://www.etsy.com/cart/listing.php",
+ "https://www.etsy.com/cart/listing.php",
+ "https://www.eyebuydirect.com/cart",
+ "https://www.fingerhut.com/cart/index",
+ "https://www.finishline.com/store/cart/cart.jsp",
+ "https://www.freepeople.com/cart",
+ "https://www.freepeople.com/cart/",
+ "https://www.gamestop.com/cart",
+ "https://www.gamestop.com/cart/",
+ "https://www.groupon.com/cart",
+ "https://www.groupon.com/checkout/cart",
+ "https://www.harborfreight.com/checkout/cart",
+ "https://www.hmhco.com/hmhstorefront/cart",
+ "https://www.homedepot.com/mycart/home",
+ "https://www.hottopic.com/cart",
+ "https://www.hsn.com/checkout/bag",
+ "https://www.ikea.com/us/en/shoppingcart/",
+ "https://www.jcpenney.com/cart",
+ "https://www.jcrew.com/checkout/cart",
+ "https://www.joann.com/cart",
+ "https://www.kohls.com/checkout/shopping_cart.jsp",
+ "https://www.landsend.com/shopping-bag",
+ "https://www.landsend.com/shopping-bag/",
+ "https://www.llbean.com/webapp/wcs/stores/servlet/LLBShoppingCartDisplay",
+ "https://www.lowes.com/cart",
+ "https://www.lulus.com/checkout/bag",
+ "https://www.macys.com/my-bag",
+ "https://www.microsoft.com/en-US/store/cart",
+ "https://www.microsoft.com/en-us/store/buy/cart",
+ "https://www.microsoft.com/en-us/store/cart",
+ "https://www.midwayusa.com/cart",
+ "https://www.midwayusa.com/cart/",
+ "https://www.neimanmarcus.com/checkout/cart.jsp",
+ "https://www.nike.com/cart",
+ "https://www.nordstrom.com/shopping-bag",
+ "https://www.officedepot.com/cart/shoppingCart.do",
+ "https://www.opticsplanet.com/checkout/cart",
+ "https://www.overstock.com/cart",
+ ("https://www.pacsun.com/on/demandware.store/Sites-pacsun-Site/default/"
+ "Cart-Show"),
+ "https://www.petsmart.com/cart/",
+ "https://www.pier1.com/cart",
+ "https://www.pokemoncenter.com/cart",
+ "https://www.potterybarn.com/shoppingcart/",
+ "https://www.qvc.com/checkout/cart.html",
+ "https://www.redbubble.com/cart",
+ "https://www.rei.com/ShoppingCart",
+ "https://www.revolve.com/r/ShoppingBag.jsp",
+ "https://www.rockauto.com/en/cart",
+ "https://www.rockauto.com/en/cart/",
+ "https://www.rockauto.com/en/cart/checkout",
+ "https://www.saksfifthavenue.com/cart",
+ "https://www.samsclub.com/cart",
+ "https://www.samsclub.com/sams/cart/cart.jsp",
+ "https://www.sephora.com/basket",
+ "https://www.shutterfly.com/cart",
+ "https://www.shutterfly.com/cart/",
+ "https://www.staples.com/cc/mmx/cart",
+ "https://www.sweetwater.com/store/cart.php",
+ "https://www.talbots.com/cart",
+ "https://www.target.com/co-cart",
+ "https://www.target.com/co-cart",
+ "https://www.teacherspayteachers.com/Cart",
+ "https://www.teacherspayteachers.com/Cart/Checkout",
+ "https://www.therealreal.com/cart",
+ "https://www.tractorsupply.com/TSCShoppingCartView",
+ "https://www.ulta.com/bag",
+ "https://www.ulta.com/bag/empty",
+ "https://www.ulta.com/bag/login",
+ "https://www.underarmour.com/en-us/cart",
+ "https://www.urbanoutfitters.com/cart",
+ "https://www.vitalsource.com/cart",
+ "https://www.walgreens.com/cart/view-ui",
+ "https://www.walmart.com/cart",
+ "https://www.walmart.com/cart/",
+ "https://www.wayfair.com/session/public/basket.php",
+ "https://www.wayfair.com/v/checkout/basket/add_and_show",
+ "https://www.wayfair.com/v/checkout/basket/show",
+ "https://www.weightwatchers.com/us/shop/checkout/cart",
+ "https://www.westelm.com/shoppingcart/",
+ "https://www.wiley.com/en-us/cart",
+ "https://www.williams-sonoma.com/shoppingcart/",
+ "https://www.zappos.com/cart",
+ "https://www.zennioptical.com/shoppingCart",
+ "https://www2.hm.com/en_gb/cart",
+ "https://www2.hm.com/en_us/cart",
+ // Example cart URLs.
+ "http://example.com/us/cart/",
+ "http://example.com/cart/",
+ "https://example.com/cart",
+ "http://example.com/cart",
+ "https://www.example.com/cart/list.htm",
+ "https://cart.example.com",
+ "https://www.example.com/my-cart",
+ "https://www.example.com/CartView/",
+ "https://www.example.com/checkout/cart",
+ "https://www.example.com/CheckoutCartView/",
+ "https://example.com/bundles/shop",
+ "https://www.example.com/AjaxOrderItemDisplay",
+ "https://www.example.com/OrderItemDisplayView.jsp",
+ "https://www.example.com/cart-show",
};

const char* kNotVisitCart[] = {
- "https://www.amazon.com/gp/aw/changed?ref_=navm_hdr_cart",
- "http://example.com/gp/aw/c?ref_=navm_hdr_cart",
- "http://example.com/cartoon",
+ // Real non-cart URLs.
+ "https://www.rockauto.com/xx/cart/",
+ "https://api.bestbuy.com/click/-/6429440/cart",
+ "https://api.bestbuy.com/click/-/6429442/cart",
+ "https://business.landsend.com/checkout/cart",
+ "https://business.officedepot.com/cart/checkout.do",
+ "https://business.officedepot.com/cart/shoppingCart.do",
+ "https://business.officedepot.com/cart/updateRouter.do",
+ "https://cart.ebay.com/api/xo",
+ "https://cns.usps.com/shippingCart",
+ "https://cns.usps.com/shippingCart.shtml",
+ "https://ecommerce2.apple.com/asb2bstorefront/asb2b/en/USD/cart",
+ "https://factory.jcrew.com/checkout/cart",
+ "https://m.llbean.com/webapp/wcs/stores/servlet/LLBShoppingCartDisplay",
+ "https://photo.samsclub.com/cart/items",
+ "https://photo.walgreens.com/cart/confirmation",
+ "https://photo.walgreens.com/cart/review",
+ "https://photo.walgreens.com/cart/shipping",
+ "https://photo.walgreens.com/cart/shoppingcart",
+ "https://photos3.walmart.com/shoppingcart",
+ "https://poshmark.com/bundles/sell",
+ "https://poshmark.com/category/Women-Bags",
+ "https://poshmark.com/category/Women-Bags-Crossbody_Bags",
+ "https://poshmark.com/showroom/"
+ "Louis-Vuitton-Handbags-1b6f536521bf8d6e0a155371",
+ "https://secure.newegg.com/Shopping/AddToCart.aspx",
+ "https://secure.newegg.com/Shopping/AddtoCart.aspx",
+ "https://secure.newegg.com/Shopping/EmailCart.aspx",
+ "https://shop.lululemon.com/c/bags/_/N-1z0xcuuZ8rd",
+ "https://shop.lululemon.com/c/bags/_/N-8rd",
+ "https://shop.lululemon.com/p/bags/All-Night-Festival-Bag-Micro/_/"
+ "prod9960617",
+ "https://shop.lululemon.com/p/bags/Everywhere-Belt-Bag/_/prod8900747",
+ "https://store.steampowered.com/app/1220140/Cartel_Tycoon/",
+ "https://store.steampowered.com/itemcart/checkout/",
+ "https://store.steampowered.com/points/shop/c/itembundles",
+ "https://store.usps.com/store/product/shipping-supplies/"
+ "readypost-15l-x-12w-x-10h-mailing-cartons-P_843061",
+ "https://www.academy.com/shop/browse/camping--outdoors/"
+ "sleeping-bags-and-bedding/airbeds--sleeping-pads",
+ "https://www.academy.com/shop/browse/outdoors/camping--outdoors/"
+ "sleeping-bags-airbeds-cots/airbeds--sleeping-pads",
+ "https://www.academy.com/shop/browse/sports/basketball/basketball-hoops",
+ "https://www.academy.com/shop/browse/sports/boxing--mma/"
+ "boxing-mma-punching-bags/heavy-bags",
+ "https://www.acehardware.com/cart/checkout",
+ "https://www.acehardware.com/departments/home-and-decor/"
+ "trash-and-recycling/garbage-cans-and-recycling-bins",
+ "https://www.acehardware.com/departments/lawn-and-garden/gardening-tools/"
+ "wheelbarrows-carts-and-hand-trucks",
+ "https://www.acehardware.com/departments/lawn-and-garden/gardening-tools/"
+ "wheelbarrows-carts-and-hand-trucks/7331739",
+ "https://www.adorama.com/l/Photography/Photography-Bags-and-Cases",
+ "https://www.ae.com/us/en/c/aerie/accessories-shoes/bags/cat6460064",
+ "https://www.ae.com/us/en/c/women/accessories-socks/belts-bags/cat1070004",
+ "https://www.ae.com/us/en/p/women/high-waisted-shorts/mom-shorts/"
+ "ae-paperbag-denim-mom-shorts/0338_6267_489",
+ "https://www.ae.com/us/en/p/women/jogger-pants/jogger-pants/"
+ "ae-paperbag-jogger-pant/0322_4413_309",
+ "https://www.altardstate.com/as/all-accessories/bags-keychains/",
+ "https://www.anthropologie.com/bags",
+ "https://www.anthropologie.com/shop/julien-leather-tote-bag",
+ "https://www.anthropologie.com/shop/liberty-crossbody-bag",
+ "https://www.anthropologie.com/shop/luna-slouchy-crossbody-bag",
+ "https://www.att.com/buy/bundles",
+ "https://www.att.com/buy/bundles/",
+ "https://www.att.com/buy/bundles/hsiaplans",
+ "https://www.backcountry.com/backcountry-double-ski-snowboard-rolling-bag",
+ "https://www.backcountry.com/down-sleeping-bags",
+ "https://www.backcountry.com/patagonia-baggies-shorts-mens",
+ "https://www.backcountry.com/sleeping-bags",
+ "https://www.basspro.com/shop/en/sleeping-bags",
+ "https://www.basspro.com/shop/en/"
+ "spring-fishing-classic-sale-tackle-boxes-and-bags",
+ "https://www.basspro.com/shop/en/tackle-bags",
+ "https://www.basspro.com/shop/en/tackle-boxes-bags",
+ "https://www.bathandbodyworks.com/c/gifts/gift-basket-stuffers",
+ "https://www.bathandbodyworks.com/on/demandware.store/"
+ "Sites-BathAndBodyWorks-Site/en_US/Cart-AddProduct",
+ "https://www.bathandbodyworks.com/on/demandware.store/"
+ "Sites-BathAndBodyWorks-Site/en_US/Cart-AddToWishlist",
+ "https://www.bathandbodyworks.com/on/demandware.store/"
+ "Sites-BathAndBodyWorks-Site/en_US/Cart-ContinueShopping",
+ "https://www.bedbathandbeyond.com/store/category/bedding/bed-in-a-bag/"
+ "16078/",
+ "https://www.bedbathandbeyond.com/store/category/bedding/bed-in-a-bag/"
+ "16078/_full-queen_queen/"
+ "dmlzdWFsVmFyaWFudC5ub252aXN1YWxWYXJpYW50LlNLVV9GT1JfU1dBVENILlNLVV9TSVpFOi"
+ "JmdWxsL3F1ZWVuInwicXVlZW4i",
+ "https://www.bedbathandbeyond.com/store/category/storage-cleaning/"
+ "storage-organization/drawers-carts/12642/",
+ "https://www.bedbathandbeyond.com/store/category/storage-cleaning/"
+ "storage-organization/storage-bins-baskets/12208/",
+ "https://www.belk.com/bed-bath/bedding/bed-in-a-bag/",
+ "https://www.belk.com/handbags/",
+ "https://www.belk.com/handbags/purses-handbags/",
+ "https://www.belk.com/handbags/purses-handbags/crossbody-bags/",
+ "https://www.bestbuy.com/site/combo/washer-dryer-bundles/"
+ "af7c2f64-5faa-4a9e-a079-7246f70db472",
+ "https://www.bestbuy.com/site/washers-dryers/washer-dryer-bundles/"
+ "pcmcat303000050004.c",
+ "https://www.bhphotovideo.com/c/browse/Bags-Cases-Carrying-Equipment/ci/"
+ "167/N/4075788798",
+ "https://www.bhphotovideo.com/c/buy/Shoulder-Gadget-Bags/ci/174",
+ "https://www.bloomingdales.com/shop/handbags",
+ "https://www.bloomingdales.com/shop/handbags/clutches-evening-bags",
+ "https://www.bloomingdales.com/shop/sale/handbags-purses",
+ "https://www.bloomingdales.com/shop/tory-burch/handbags-wallets",
+ "https://www.boostmobile.com/cart",
+ "https://www.buybuybaby.com/store/category/gear-travel/diaper-bags/30507/",
+ "https://www.buybuybaby.com/store/category/gear-travel/diaper-bags/"
+ "diaper-backpacks/32034/",
+ "https://www.buybuybaby.com/store/product/"
+ "carter-39-s-by-davinci-adrian-swivel-glider-with-ottoman-in-performance-"
+ "fabric/5354803",
+ "https://www.buybuybaby.com/store/registry/FreeGoodyBag",
+ "https://www.chegg.com/homework-help/"
+ "mauro-products-distributes-single-product-woven-basket-whose-chapter-6-"
+ "problem-7be-solution-9780077386214-exc",
+ "https://www.chegg.com/homework-help/questions-and-answers/"
+ "example-1010-p-252-suppose-mountain-climber-instead-drags-bag-supplies-"
+ "slope-increasing-sp-q31806760",
+ "https://www.containerstore.com/s/laundry-cleaning/hampers-baskets/12",
+ "https://www.containerstore.com/s/storage/decorative-bins-baskets/12",
+ "https://www.containerstore.com/s/storage/plastic-bins-baskets/12",
+ "https://www.containerstore.com/s/storage/plastic-bins-baskets/"
+ "white-nordic-storage-baskets-with-handles/12d",
+ "https://www.costco.com/ManageShoppingCartCmd",
+ "https://www.costco.com/handbags-wallets.html",
+ "https://www.costco.com/logon-instacart",
+ "https://www.crateandbarrel.com/decorating-and-accessories/baskets/1",
+ "https://www.crateandbarrel.com/furniture/bar-cabinets-and-carts/1",
+ "https://www.crateandbarrel.com/furniture/filing-cabinets-and-carts/1",
+ "https://www.dickssportinggoods.com/c/basketball-gear",
+ "https://www.dickssportinggoods.com/f/basketball-shoes-for-men",
+ "https://www.dickssportinggoods.com/f/golf-bags-accessories-1",
+ "https://www.dickssportinggoods.com/p/"
+ "jordan-air-jordan-1-mid-basketball-shoes-19nikmrjrdn1mdblknke/"
+ "19nikmrjrdn1mdblknke",
+ "https://www.dillards.com/brand/Michael+Kors/handbags",
+ "https://www.dillards.com/c/handbags",
+ "https://www.dillards.com/c/handbags-cross-body-bags",
+ "https://www.dillards.com/c/sale-clearance/handbags",
+ "https://www.dsw.com/en/us/category/womens-clearance-handbags/"
+ "N-1z141jrZ1z141ilZ1z141cp",
+ "https://www.dsw.com/en/us/category/womens-crossbody-handbags/"
+ "N-1z141jrZ1z128u1Z1z141cp",
+ "https://www.dsw.com/en/us/category/womens-handbags/N-1z141jrZ1z141cp",
+ "https://www.dsw.com/en/us/category/womens-leather-and-nubuck-handbags/"
+ "N-1z141jrZ1z12bixZ1z12b4gZ1z12b7gZ1z141cp",
+ "https://www.etsy.com/c/bags-and-purses/handbags",
+ "https://www.etsy.com/c/bags-and-purses/handbags/shoulder-bags",
+ "https://www.eyebuydirect.com/sunglasses/frames/cartel-tortoise-m-19614",
+ "https://www.fingerhut.com/cart/justAdded",
+ "https://www.fingerhut.com/search/Clothing/Handbags",
+ "https://www.fingerhut.com/search/Clothing/Handbags/2126.uts",
+ "https://www.fingerhut.com/search/Clothing/Luggage%20&%20Travel%20Bags",
+ "https://www.finishline.com/store/cart/cartSlide.jsp",
+ "https://www.finishline.com/store/men/shoes/basketball/_/N-3z3fil",
+ "https://www.finishline.com/store/product/"
+ "mens-air-jordan-6-rings-basketball-shoes/prod739613",
+ "https://www.finishline.com/store/product/"
+ "nike-zoom-freak-2-basketball-shoes/prod2800331",
+ "https://www.freepeople.com/bags/",
+ "https://www.freepeople.com/shop/carter-sweater-set/",
+ "https://www.freepeople.com/shop/hudson-sling-bag/",
+ "https://www.gamestop.com/clothing/bags-travel/backpacks",
+ "https://www.gamestop.com/toys-collectibles/toys/blind-bags",
+ "https://www.gamestop.com/toys-collectibles/toys/plush/products/"
+ "squishmallows-plush-bag-clip-assortment/11108921.html",
+ "https://www.groupon.com/coupons/carters",
+ "https://www.groupon.com/coupons/instacart",
+ "https://www.groupon.com/deals/"
+ "gg-mp-oled-fingertip-pulse-oximeter-finger-blood-oxygen-spo2-pr-heart-"
+ "rate-monitor-bag",
+ "https://www.harborfreight.com/material-handling/"
+ "hand-trucks-carts-dollies.html",
+ "https://www.harborfreight.com/tool-storage-organization/"
+ "tool-boxes-bags-belts.html",
+ "https://www.harborfreight.com/tool-storage-organization/tool-storage/"
+ "tool-carts.html",
+ "https://www.harborfreight.com/tool-storage-organization/"
+ "yukon-tool-storage/tool-carts-cabinets.html",
+ "https://www.homedepot.com/b/Appliances-Garbage-Disposals/N-5yc1vZc3no",
+ "https://www.homedepot.com/p/"
+ "GE-4-2-cu-ft-White-Top-Load-Washing-Machine-with-Stainless-Steel-Basket-"
+ "GTW335ASNWW/308653937",
+ "https://www.homedepot.com/p/"
+ "GE-4-5-cu-ft-High-Efficiency-White-Top-Load-Washing-Machine-with-"
+ "Stainless-Steel-Basket-GTW465ASNWW/308653940",
+ "https://www.homedepot.com/p/Vigoro-2-cu-ft-Bagged-Brown-Mulch-52050196/"
+ "205606287",
+ "https://www.hottopic.com/accessories/bags/",
+ "https://www.hottopic.com/accessories/bags/backpacks/",
+ "https://www.hottopic.com/accessories/bags/wallets/",
+ "https://www.hottopic.com/on/demandware.store/Sites-hottopic-Site/default/"
+ "Cart-AddToWishlist",
+ "https://www.hsn.com/shop/clearance-handbags-and-wallets-for-women/"
+ "fa0402-4525",
+ "https://www.hsn.com/shop/handbags-and-wallets-for-women/fa0402",
+ "https://www.hsn.com/shop/hands-free-handbags/20986",
+ "https://www.hsn.com/shop/patricia-nash-handbags-and-wallets-for-women/"
+ "fa0402-16311",
+ "https://www.ikea.com/us/en/cat/baskets-16201/",
+ "https://www.ikea.com/us/en/cat/kitchen-islands-carts-10471/",
+ "https://www.ikea.com/us/en/cat/kitchen-islands-carts-fu005/",
+ "https://www.ikea.com/us/en/cat/storage-boxes-baskets-10550/",
+ "https://www.jcpenney.com/cart/signin",
+ "https://www.jcpenney.com/g/purses-accessories/crossbody-bags",
+ "https://www.jcpenney.com/g/purses-accessories/view-all-handbags-wallets",
+ "https://www.jcpenney.com/jsp/cart/viewShoppingBag.jsp",
+ "https://www.jcrew.com/c/mens_category/bags",
+ "https://www.jcrew.com/c/womens_category/handbags",
+ "https://www.jcrew.com/checkout2/shoppingbag.jsp",
+ "https://www.joann.com/home-decor-and-holiday/"
+ "storage-and-organization-decor/baskets/",
+ "https://www.joann.com/iris-usa-6-drawer-medium-cart/7226947.html",
+ "https://www.joann.com/sewing/sewing-baskets-and-pin-cushions/",
+ "https://www.joann.com/we-r-memory-keepers-a-la-cart/zprd_18086751a.html",
+ "https://www.kohls.com/catalog/"
+ "womens-totes-handbags-purses-accessories.jsp",
+ "https://www.kohls.com/ecom/kohls-smartcart-kcash.html",
+ "https://www.kohls.com/product/prd-1369234/"
+ "shark-navigator-lift-away-deluxe-professional-bagless-vacuum.jsp",
+ "https://www.kohls.com/product/prd-3698449/"
+ "mens-nike-dri-fit-icon-basketball-shorts.jsp",
+ "https://www.landsend.com/products/open-or-zip-top-natural-canvas-tote-bag/"
+ "id_299717",
+ "https://www.landsend.com/shop/bags-travel-sale/S-xfd-ytq-xec",
+ "https://www.llbean.com/llb/shop/webapp/wcs/stores/servlet/"
+ "LLBShoppingCartDisplay",
+ "https://www.lowes.com/pl/Bagged-mulch-Mulch-Landscaping-Lawn-garden/"
+ "4294612786",
+ "https://www.lowes.com/pl/"
+ "Kitchen-islands-carts-Dining-kitchen-furniture-Furniture-Home-decor/"
+ "1323549633",
+ "https://www.lowes.com/pl/"
+ "Plastic-storage-totes-Baskets-storage-containers-Storage-organization/"
+ "4294713243",
+ "https://www.lowes.com/pl/"
+ "Wheelbarrows-Wheelbarrows-yard-carts-Outdoor-tools-equipment-Outdoors/"
+ "3394587996",
+ "https://www.lulus.com/categories/39_598/vegan-handbags-and-purses.html",
+ "https://www.lulus.com/categories/99_39/handbags-and-purses.html",
+ "https://www.lulus.com/products/weekend-traveler-black-and-cognac-tote-bag/"
+ "1029302.html",
+ "https://www.lulus.com/products/weekend-traveler-cognac-tote-bag/"
+ "1029322.html",
+ "https://www.macys.com/shop/bed-bath/bed-in-a-bag",
+ "https://www.macys.com/shop/featured/michael-kors-handbags",
+ "https://www.macys.com/shop/handbags-accessories",
+ "https://www.macys.com/shop/sale/Business_category/"
+ "Handbags%20%26%20Accessories%7CWomen%7CWomen%27s%20Shoes",
+ "https://www.microsoft.com/en-us/store/collections/surfacebagsandsleeves/"
+ "pc",
+ "https://www.microsoft.com/en-us/store/collections/surfacebundles",
+ "https://www.midwayusa.com/backpacks-and-bags/br",
+ "https://www.midwayusa.com/range-bags/br",
+ "https://www.midwayusa.com/shooting-rests-and-bags/br",
+ "https://www.neimanmarcus.com/c/handbags-all-handbags-cat46860739",
+ "https://www.neimanmarcus.com/c/handbags-cat13030735",
+ "https://www.neimanmarcus.com/c/sale-all-sale-women-handbags-cat74120753",
+ "https://www.neimanmarcus.com/c/sale-women-handbags-cat46520737",
+ "https://www.nike.com/w/mens-bags-and-backpacks-9xy71znik1",
+ "https://www.nike.com/w/mens-basketball-shoes-3glsmznik1zy7ok",
+ "https://www.nike.com/w/"
+ "mens-nike-by-you-basketball-shoes-3glsmz6ealhznik1zy7ok",
+ "https://www.nike.com/w/womens-basketball-shoes-3glsmz5e1x6zy7ok",
+ "https://www.nordstrom.com/browse/designer/women/handbags",
+ "https://www.nordstrom.com/browse/sale/women/handbags",
+ "https://www.nordstrom.com/browse/women/handbags",
+ "https://www.nordstrom.com/browse/women/handbags/crossbody",
+ "https://www.officedepot.com/cart/checkout.do",
+ "https://www.opticsplanet.com/cart-empty",
+ "https://www.overstock.com/Bedding-Bath/Bed-in-a-Bag/29942/cat.html",
+ "https://www.overstock.com/Home-Garden/Kitchen-Carts/1996/subcat.html",
+ "https://www.overstock.com/Home-Garden/"
+ "Malia-Outdoor-Standing-Wicker-Basket-Chair-with-Cushion-by-Christopher-"
+ "Knight-Home/29874486/product.html",
+ "https://www.overstock.com/Home-Garden/Simple-Living-Georgia-Kitchen-Cart/"
+ "30992405/product.html",
+ "https://www.pacsun.com/mens/backpacks-bags/",
+ "https://www.pacsun.com/on/demandware.store/Sites-pacsun-Site/default/"
+ "Cart-ContinueShopping",
+ "https://www.pacsun.com/womens/accessories/handbags/",
+ "https://www.pacsun.com/womens/jeans/baggy/",
+ "https://www.petsmart.com/cart-checkout/",
+ "https://www.petsmart.com/fish/filters-and-pumps/filter-media/"
+ "top-fin-ef-s-element-aquarium-filter-cartridges---12pk-57278.html",
+ "https://www.petsmart.com/on/demandware.store/Sites-PetSmart-Site/default/"
+ "Cart-ContinueShopping",
+ "https://www.petsmart.com/on/demandware.store/Sites-PetSmart-Site/default/"
+ "Paypal-StartExpressCheckoutFromCartFlow",
+ "https://www.pier1.com/cart/add",
+ "https://www.pier1.com/cart/change",
+ "https://www.pier1.com/products/sisal-bunny-girl-with-basket-15h",
+ "https://www.pier1.com/products/twig-basket-with-bunny",
+ "https://www.pokemoncenter.com/category/bags-and-totes",
+ "https://www.potterybarn.com/products/beachcomber-basket-collection/",
+ "https://www.potterybarn.com/products/seagrass-basket-collection-havana/",
+ "https://www.potterybarn.com/products/seagrass-basket-collection-savannah/",
+ "https://www.potterybarn.com/shop/organization/baskets-organization/",
+ "https://www.qvc.com/handbags-&-luggage/_/N-uoq0/c.html",
+ "https://www.qvc.com/handbags-&-luggage/dooney-&-bourke/_/N-uoq0Z1z141jd/"
+ "c.html",
+ "https://www.qvc.com/handbags-&-luggage/handbags/_/N-2a0k5/c.html",
+ "https://www.qvc.com/handbags-&-luggage/luggage/_/N-1cjuv/c.html",
+ "https://www.redbubble.com/shop/drawstring-bags",
+ "https://www.redbubble.com/shop/duffle-bags",
+ "https://www.redbubble.com/shop/makeup+bags",
+ "https://www.redbubble.com/shop/tote-bags",
+ "https://www.rei.com/c/mens-sleeping-bags",
+ "https://www.rei.com/c/womens-sleeping-bags",
+ "https://www.rei.com/product/126821/patagonia-baggies-shorts-womens",
+ "https://www.rei.com/rei-garage/c/sleeping-bags-and-accessories",
+ "https://www.revolve.com/bags-clutches/br/cc5b36/",
+ "https://www.revolve.com/bags-crossbody-bags/br/f8c179/",
+ "https://www.revolve.com/bags-totes/br/317dcf/",
+ "https://www.revolve.com/bags/br/2df9df/",
+ "https://www.rockauto.com/es/cart/",
+ "https://www.saksfifthavenue.com/c/handbags",
+ "https://www.saksfifthavenue.com/c/handbags/handbags/crossbody-bags",
+ "https://www.saksfifthavenue.com/c/handbags/handbags/totes",
+ "https://www.saksfifthavenue.com/c/handbags/saint-laurent",
+ "https://www.samsclub.com/b/gourmet-gift-baskets-and-food/1261",
+ "https://www.samsclub.com/sams/controller/SamsInstaCartZipcodeController",
+ "https://www.sephora.com/beauty-sample-bag",
+ "https://www.sephora.com/beauty/beauty-sample-bag",
+ "https://www.sephora.com/product/baggage-claim-gold-eye-masks-P428668",
+ "https://www.sephora.com/shop/makeup-bags-cosmetic-bags",
+ "https://www.shutterfly.com/maincart/start.sfly",
+ "https://www.shutterfly.com/personalized-gifts/cotton-tote-bags",
+ "https://www.shutterfly.com/signout/itemsInCart.sfly",
+ "https://www.staples.com/hp-ink-cartridges/cat_CG812",
+ "https://www.staples.com/services/printing/Cart",
+ "https://www.staples.com/services/printing/CartCheckout",
+ "https://www.staples.com/services/printing/cart",
+ "https://www.sweetwater.com/c933--Electric_Guitar_Gig_Bags",
+ "https://www.sweetwater.com/c982--Drum_Microphone_Bundles",
+ "https://www.sweetwater.com/shop/drums-percussion/drum-cases-bags/",
+ "https://www.sweetwater.com/store/detail/"
+ "PS9339--prs-private-stock-number-9339-mccarty-594-hollowbody-ii-namm-2021-"
+ "tiger-eye-glow",
+ "https://www.talbots.com/accessories/handbags",
+ "https://www.talbots.com/basket-weave-sweater---solid/P211121070.html",
+ "https://www.talbots.com/nappa-havana-turnlock-camera-bag/P211061420.html",
+ "https://www.talbots.com/on/demandware.store/Sites-talbotsus-Site/default/"
+ "Cart-SubmitForm",
+ "https://www.target.com/c/easter-basket-candy/-/N-4pa5f",
+ "https://www.target.com/c/easter-basket-fillers/-/N-w48b8",
+ "https://www.target.com/c/easter-baskets/-/N-4uswf",
+ "https://www.teacherspayteachers.com/Product/"
+ "Free-Easter-and-Spring-Craft-Chicks-in-a-Basket-1165442",
+ "https://www.teacherspayteachers.com/Product/"
+ "March-Madness-Basketball-Tournament-Math-Project-PBL-Digital-Google-"
+ "Slides-326537",
+ "https://www.teacherspayteachers.com/Store/Not-So-Wimpy-Teacher/Category/"
+ "Writing-Bundles-509675",
+ "https://www.therealreal.com/designers/chanel/women/handbags",
+ "https://www.therealreal.com/shop/women/handbags",
+ "https://www.therealreal.com/shop/women/handbags/crossbody-bags",
+ "https://www.therealreal.com/shop/women/handbags/totes",
+ "https://www.tractorsupply.com/tsc/catalog/egg-cartons",
+ "https://www.tractorsupply.com/tsc/catalog/garden-carts",
+ "https://www.tractorsupply.com/tsc/catalog/wheelbarrows-garden-carts",
+ "https://www.tractorsupply.com/tsc/product/"
+ "ohio-steel-15-cu-ft-poly-swivel-dump-cart",
+ "https://www.ulta.com/"
+ "free-dry-shampoo-9-piece-beauty-bag-with-50-hair-care-purchase",
+ "https://www.ulta.com/makeup-bags-organizers",
+ "https://www.underarmour.com/en-us/c/mens/accessories/bags/",
+ "https://www.underarmour.com/en-us/c/mens/shoes/basketball/",
+ "https://www.underarmour.com/en-us/c/mens/sports/basketball/",
+ "https://www.underarmour.com/en-us/c/shoes/basketball/",
+ "https://www.urbanoutfitters.com/bags-wallets-for-women",
+ "https://www.urbanoutfitters.com/shop/"
+ "bdg-bubble-corduroy-high-waisted-baggy-pant",
+ "https://www.urbanoutfitters.com/shop/"
+ "bdg-high-waisted-baggy-jean-medium-wash",
+ "https://www.urbanoutfitters.com/shop/carter-triangle-bracket-wall-shelf",
+ "https://www.vans.com/shop/mens-accessories-backpacks-bags",
+ "https://www.vans.com/shop/womens-accessories-backpacks-bags",
+ "https://www.walmart.com/browse/build-your-easter-basket/0/0/",
+ "https://www.walmart.com/browse/home/bed-in-a-bag-sets/"
+ "4044_539103_9474113_3388004",
+ "https://www.wayfair.com/furniture/sb0/kitchen-islands-carts-c415182.html",
+ "https://www.wayfair.com/storage-organization/sb0/"
+ "hampers-laundry-baskets-c215044.html",
+ "https://www.weightwatchers.com/us/recipe/"
+ "2-ingredient-dough-everything-bagels/5fbd830687a4600722b90e01",
+ "https://www.weightwatchers.com/us/recipe/"
+ "corned-beef-and-cabbage-fried-rice/601c5ce2a1ceeb43bfb53608",
+ "https://www.weightwatchers.com/us/recipe/"
+ "corned-beef-and-cabbage-red-potatoes-1/5626a5f34236657004995b4d",
+ "https://www.weightwatchers.com/us/recipe/"
+ "spinach-bagels-herbed-cream-cheese/5e596fb716a786036659fb09",
+ "https://www.westelm.com/products/hilo-basket-planters-d10517/",
+ "https://www.westelm.com/products/"
+ "mid-century-heathered-basketweave-wool-rug-steel-t1811/",
+ "https://www.westelm.com/products/parker-mid-century-bar-cart-h415/",
+ "https://www.westelm.com/shop/storage-organization/storage-baskets-bins/",
+ "https://www.williams-sonoma.com/shop/easter/easter-feature-build-basket/",
+ "https://www.williams-sonoma.com/shop/home-furniture/bar-carts-cabinets/",
+ "https://www.williams-sonoma.com/shop/home-furniture/kitchen-island-cart/",
+ "https://www.williams-sonoma.com/shop/tabletop-glassware-bar/"
+ "serving-trays-platters-baskets/",
+ "https://www.zappos.com/brooks-women-sneakers-athletic-shoes/"
+ "CK_XARC81wFSARpaARrAAQHiAgUBAgsYCg.zso",
+ "https://www.zappos.com/filters/women-sneakers-athletic-shoes/"
+ "CK_XARC81wFaByTcA4Ql5AfAAQHiAgQBAgsY.zso",
+ "https://www.zappos.com/sandals/CK_XARC51wHiAgIBAg.zso",
+ "https://www.zappos.com/sneakers-athletic-shoes/CK_XARC81wHiAgIBAg.zso",
+ "https://www2.hm.com/en_us/women/products/accessories/purses-bags.html",
+ "https://www2.hm.com/en_us/women/products/pants/paperbag-pants.html",
+ // Example non-cart URLs.
+ "https://example.com/gp/aw/c?ref_=navm_hdr_cart",
+ "https://example.com/cartoon",
+ "https://example.com/checkout",
+ "https://example.com/moving-cart",
+ "https://example.com/shoulder_bag",
};

const char* kVisitCheckout[] = {
diff --git a/chrome/renderer/resources/cart/cart_domain_cart_url_regex.json b/chrome/renderer/resources/cart/cart_domain_cart_url_regex.json
new file mode 100644
index 0000000..7663149
--- /dev/null
+++ b/chrome/renderer/resources/cart/cart_domain_cart_url_regex.json
@@ -0,0 +1,111 @@
+{
+"abebooks.com": "^https://www.abebooks.com/servlet/(shopbasketpl|shoppingbasket)/?$",
+"academy.com": "^https://www.academy.com/shop/cart/?$",
+"acehardware.com": "^https://www.acehardware.com/cart/?$",
+"adorama.com": "^https://www.adorama.com/als.mvc/cartview/?$",
+"advanceautoparts.com": "^https://shop.advanceautoparts.com/web/orderitemdisplay/?$",
+"ae.com": "^https://www.ae.com/us/en/cart/?$",
+"altardstate.com": "^https://www.altardstate.com/cart/?$",
+"amazon.co.uk": "((/(-/[A-Za-z_-]+/)?gp/((.*/)?cart(/.*)?)(/|$))|(/gp/aw/c\\?))",
+"amazon.com": "((/(-/[A-Za-z_-]+/)?gp/((.*/)?cart(/.*)?)(/|$))|(/gp/aw/c\\?))",
+"amplify.com": "^https://myshop.amplify.com/cart/?$",
+"anthropologie.com": "^https://www.anthropologie.com/cart/?$",
+"apple.com": "^https://www.apple.com/([^/]+/)?shop/([^/]+/)?bag$",
+"atlassian.com": "^https://[^/]+.atlassian.com/([^/]+/)?cart$",
+"att.com": "^https://www.att.com/(([^/]+/)?buy/(cart|checkout/cartview)|cart/mycart.html)$",
+"backcountry.com": "^https://www.backcountry.com/Store/cart/cart.jsp/?$",
+"basspro.com": "^https://www.basspro.com/shop/ajaxorderitemdisplayview/?$",
+"bathandbodyworks.com": "^https://www.bathandbodyworks.com/cart/?$",
+"beastacademy.com": "^https://beastacademy.com/checkout/cart/?$",
+"bedbathandbeyond.com": "^https://www.bedbathandbeyond.com/store/cart/?$",
+"belk.com": "^https://www.belk.com/shopping-bag/?$",
+"bestbuy.com": "^https://www.bestbuy.com/cart(/[^/]+/)?$",
+"bhphotovideo.com": "^https://www.bhphotovideo.com/(c/)?find/cart.jsp",
+"bloomingdales.com": "^https://www.bloomingdales.com/my-bag/?$",
+"boostmobile.com": "^https://www.boostmobile.com/cart.html/?$",
+"bricklink.com": "^https://(www|store).bricklink.com/v2/globalcart.page/?$",
+"brownells.com": "^https://www.brownells.com/aspx/store/cart.aspx/?$",
+"buybuybaby.com": "^https://www.buybuybaby.com/store/cart/?$",
+"carid.com": "^https://www.carid.com/cart.php/?$",
+"chegg.com": "^https://www.chegg.com/shoppingcart/?$",
+"containerstore.com": "^https://www.containerstore.com/cart/list.htm/?$",
+"costco.com": "^https://www.costco.com/checkoutcart(display)?view/?$",
+"crateandbarrel.com": "^https://www.crateandbarrel.com/checkout/cart/?$",
+"dickssportinggoods.com": "^https://www.dickssportinggoods.com/orderitemdisplay/?$",
+"dillards.com": "^https://www.dillards.com/webapp/wcs/stores/servlet/orderitemdisplay/?$",
+"dsw.com": "^https://www.dsw.com/en/us/shopping-bag/?$",
+"ebay.com": "^https://cart.(payments.)?ebay.com/(sc/(add|view)|cart)?$",
+"etsy.com": "^https://www.etsy.com/([^/]+/)?cart(/|/listing\\.php)?$",
+"eyebuydirect.com": "^https://www.eyebuydirect.com/cart/?$",
+"fingerhut.com": "^https://www.fingerhut.com/cart/index/?$",
+"finishline.com": "^https://www.finishline.com/store/cart/cart.jsp/?$",
+"freepeople.com": "^https://www.freepeople.com/cart/?$",
+"gamestop.com": "^https://www.gamestop.com/cart/?$",
+"gap.com": "^https://[^/]+.gap.com/(buy/)?shopping[_-]bag(.do)?$",
+"godaddy.com": "^https://cart.godaddy.com(/[^/]+)*/?$",
+"groupon.com": "^https://www.groupon.com/(checkout/)?cart/?$",
+"harborfreight.com": "^https://www.harborfreight.com/checkout/cart/?$",
+"hm.com": "^https://[^/]+.hm.com/[^/]+/cart/?$",
+"hmhco.com": "^https://www.hmhco.com/hmhstorefront/cart/?$",
+"homedepot.com": "^https://[^/]+.homedepot.com/mycart/home$",
+"hottopic.com": "^https://www.hottopic.com/cart/?$",
+"hsn.com": "^https://www.hsn.com/checkout/bag/?$",
+"ikea.com": "^https://[^/]+.ikea.com/(([^/]+/)+)(shoppingcart|checkout/shoppinglist)(/?)",
+"jcpenney.com": "^https://www.jcpenney.com/cart/?$",
+"jcrew.com": "^https://www.jcrew.com/checkout/cart/?$",
+"joann.com": "^https://www.joann.com/cart/?$",
+"kohls.com": "^https://www.kohls.com/checkout/shopping_cart.jsp$",
+"landsend.com": "^https://www.landsend.com/shopping-bag/?$",
+"llbean.com": "^https://www.llbean.com/webapp/wcs/stores/servlet/llbshoppingcartdisplay/?$",
+"lowes.com": "^https://[^/]+.lowes.com/cart(/(view.action)?)?$",
+"lululemon.com": "^https://shop.lululemon.com/shop/mybag/?$",
+"lulus.com": "^https://www.lulus.com/checkout/bag/?$",
+"macys.com": "^https://www.macys.com/((my-bag)|(bag(/[^/]+)*).ognc)$",
+"microsoft.com": "^https://www.microsoft.com/([^/]+/)?store/(buy/)?cart/?$",
+"midwayusa.com": "^https://(www|ads).midwayusa.com/cart/?$",
+"neimanmarcus.com": "^https://www.neimanmarcus.com/checkout/cart.jsp/?$",
+"newegg.com": "^https://secure.newegg.com/shop/cart/?$",
+"nike.com": "^https://www.nike.com/([^/]+/)*cart/?$",
+"nordstrom.com": "^https://www.nordstrom.com/shopping-bag/?$",
+"officedepot.com": "^https://www.officedepot.com/cart/shoppingCart.do/?$",
+"opticsplanet.com": "^https://www.opticsplanet.com/checkout/cart/?$",
+"overstock.com": "^https://www.overstock.com/cart/?$",
+"pacsun.com": "^https://www.pacsun.com/on/demandware.store/Sites-pacsun-Site/default/Cart-Show/?$",
+"petsmart.com": "^https://www.petsmart.com/cart/?$",
+"pier1.com": "^https://www.pier1.com/cart/?$",
+"pokemoncenter.com": "^https://www.pokemoncenter.com/cart/?$",
+"poshmark.com": "^https://(www.)?poshmark.com/bundles/shop/?$",
+"potterybarn.com": "^https://www.potterybarn.com/shoppingcart/?$",
+"qvc.com": "^https://www.qvc.com/checkout/cart.html/?$",
+"redbubble.com": "^https://www.redbubble.com/cart/?$",
+"rei.com": "^https://www.rei.com/shoppingcart/?$",
+"revolve.com": "^https://www.revolve.com/r/shoppingbag.jsp/?$",
+"rockauto.com": "^https://www.rockauto.com/en/cart(/(checkout)?)?$",
+"saksfifthavenue.com": "^https://www.saksfifthavenue.com/cart/?$",
+"samsclub.com": "^https://www.samsclub.com/(sams/)?cart/?",
+"sephora.com": "^https://www.sephora.com/basket/?$",
+"shutterfly.com": "^https://www.shutterfly.com/cart/?$",
+"staples.com": "^https://www.staples.com/cc/mmx/cart/?$",
+"steampowered.com": "^https://store.steampowered.com/cart/?$",
+"sweetwater.com": "^https://www.sweetwater.com/store/cart.php/?$",
+"talbots.com": "^https://www.talbots.com/cart/?$",
+"target.com": "^https://www.target.com/co-cart/?$",
+"teacherspayteachers.com": "^https://www.teacherspayteachers.com/cart(/checkout)?/?$",
+"therealreal.com": "^https://www.therealreal.com/cart/?$",
+"tractorsupply.com": "^https://www.tractorsupply.com/tscshoppingcartview/?$",
+"ulta.com": "^https://www.ulta.com/bag(/(empty|login))?/?$",
+"underarmour.com": "^https://www.underarmour.com/([^/]+/)?cart/?$",
+"urbanoutfitters.com": "^https://www.urbanoutfitters.com/cart/?$",
+"usps.com": "^https://[^/]+.usps.com/store/cart/cart.jsp$",
+"vans.com": "^https://www.vans.com/shop/orderitemdisplay/",
+"vitalsource.com": "^https://www.vitalsource.com/([^/]+/)?cart$",
+"walgreens.com": "^https://www.walgreens.com/cart/view-ui/?$",
+"walmart.com": "^https://([^/]+\\.)?walmart.com/cart/?$",
+"wayfair.com": "^https://www.wayfair.com/([^/]+/)+basket((.php)|(/[^/]+))$",
+"weightwatchers.com": "^https://www.weightwatchers.com/us/shop/checkout/cart/?$",
+"westelm.com": "^https://www.westelm.com/shoppingcart/?$",
+"wiley.com": "^https://www.wiley.com/([^/]+/)cart/?$",
+"williams-sonoma.com": "^https://www.williams-sonoma.com/shoppingcart/?$",
+"zappos.com": "^https://www.zappos.com/cart/?$",
+"zennioptical.com": "^https://www.zennioptical.com/shoppingCart/?$"
+}
\ No newline at end of file
diff --git a/chrome/renderer/resources/renderer_resources.grd b/chrome/renderer/resources/renderer_resources.grd
index 72350525..c707ab4 100644
--- a/chrome/renderer/resources/renderer_resources.grd
+++ b/chrome/renderer/resources/renderer_resources.grd
@@ -16,6 +16,7 @@
<include name="IDR_PREFER_HTML_PLUGIN_HTML" file="plugins/prefer_html_plugin.html" flattenhtml="true" type="BINDATA" />
<include name="IDR_PLUGIN_POSTER_HTML" file="plugins/plugin_poster.html" flattenhtml="true" type="BINDATA" />
<include name="IDR_CART_PRODUCT_EXTRACTION_JS" file="cart/cart-product-extraction.js" type="BINDATA"/>
+ <include name="IDR_CART_DOMAIN_CART_URL_REGEX_JSON" file="cart/cart_domain_cart_url_regex.json" type="BINDATA"/>

<!-- Extension libraries. -->
<if expr="enable_extensions">
diff --git a/chrome/test/data/cart/cart.html b/chrome/test/data/cart/cart.html
index c71a95f..1e0c33fe 100644
--- a/chrome/test/data/cart/cart.html
+++ b/chrome/test/data/cart/cart.html
@@ -2,22 +2,22 @@
<body>
<div>
<a href="/products/123/">Product one
- <img src="https://static.walmart.com/product-image/123.png" height=300 width=300></a>
+ <img src="https://static.guitarcenter.com/product-image/123.png" height=300 width=300></a>
<span>$12.34</span><a>remove</a>
</div>
<div>
<a href="/products/456/">Product two
- <img src="https://static.walmart.com/product-image/456.png" height=300 width=300></a>
+ <img src="https://static.guitarcenter.com/product-image/456.png" height=300 width=300></a>
<span>$56.78</span><a>remove</a>
</div>
<div>
<a href="/products/789/">Skipped
- <img src="https://static.walmart.com/product-image/789.png" height=300 width=300></a>
+ <img src="https://static.guitarcenter.com/product-image/789.png" height=300 width=300></a>
<span>$56.78</span><a>remove</a>
</div>
<div>
<a href="/products/abc/">A skipped product
- <img src="https://static.walmart.com/product-image/abc.png" height=300 width=300></a>
+ <img src="https://static.guitarcenter.com/product-image/abc.png" height=300 width=300></a>
<span>$56.78</span><a>remove</a>
</div>
<div>
diff --git a/chrome/test/data/cart/product.html b/chrome/test/data/cart/product.html
index ba3820e..cf8069c 100644
--- a/chrome/test/data/cart/product.html
+++ b/chrome/test/data/cart/product.html
@@ -2,6 +2,6 @@
<head>
</head>
<body>
-<a href="https://www.walmart.com/shopping-cartview/">cart</a>
-<a href="https://www.walmart.com/shopping-cart/">cart</a>
+<a href="https://www.guitarcenter.com/shopping-cartview/">cart</a>
+<a href="https://www.guitarcenter.com/shopping-cart/">cart</a>
</body>
Reply all
Reply to author
Forward
0 new messages