Bug 1725213 - Add module that returns the common/brand name for a URL. r=mossop,amy
authorHarry Twyford <htwyford@mozilla.com>
Tue, 17 Aug 2021 14:29:28 +0000
changeset 589114 1b2c01f0a82b4202519b29cbcaa511d9f8f81d4c
parent 589113 d718fdd1a373b1b482b523a40e558efae806bc70
child 589115 8077cd932f28d7e30b51c9fe49a0fabe83bd1263
push id148157
push userhtwyford@mozilla.com
push dateTue, 17 Aug 2021 14:31:50 +0000
treeherderautoland@1b2c01f0a82b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmossop, amy
bugs1725213
milestone93.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1725213 - Add module that returns the common/brand name for a URL. r=mossop,amy Differential Revision: https://phabricator.services.mozilla.com/D122375
browser/components/places/CommonNames.jsm
browser/components/places/Snapshots.jsm
browser/components/places/moz.build
browser/components/places/tests/unit/interactions/head_interactions.js
browser/components/places/tests/unit/interactions/test_commonNames.js
browser/components/places/tests/unit/interactions/xpcshell.ini
new file mode 100644
--- /dev/null
+++ b/browser/components/places/CommonNames.jsm
@@ -0,0 +1,330 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+var EXPORTED_SYMBOLS = ["CommonNames"];
+
+const { XPCOMUtils } = ChromeUtils.import(
+  "resource://gre/modules/XPCOMUtils.jsm"
+);
+
+XPCOMUtils.defineLazyModuleGetters(this, {
+  PageDataCollector: "resource:///modules/pagedata/PageDataCollector.jsm",
+  shortURL: "resource://activity-stream/lib/ShortURL.jsm",
+});
+
+/**
+ * A subset of the most visited sites according to Alexa. Used as a fallback if
+ * a site doesn't expose site_name metadata. Maps a site's hostname (not
+ * including `www.`) to its common name.
+ */
+const CUSTOM_NAMES = new Map([
+  ["adobe.com", "Adobe"],
+  ["adp.com", "ADP"],
+  ["airbnb.com", "Airbnb"],
+  ["alibaba.com", "Alibaba"],
+  ["aliexpress.com", "AliExpress"],
+  ["aliexpress.ru", "AliExpress.ru"],
+  ["allegro.pl", "Allegro"],
+  ["amazon.ca", "Amazon.ca"],
+  ["amazon.co.jp", "Amazon.co.jp"],
+  ["amazon.co.uk", "Amazon.co.uk"],
+  ["amazon.com", "Amazon"],
+  ["amazon.de", "Amazon.de"],
+  ["amazon.es", "Amazon.es"],
+  ["amazon.fr", "Amazon.fr"],
+  ["amazon.in", "Amazon.in"],
+  ["amazon.it", "Amazon.it"],
+  ["amazonaws.com", "AWS"],
+  ["americanexpress.com", "American Express"],
+  ["ameritrade.com", "TD Ameritrade"],
+  ["aol.com", "AOL"],
+  ["apple.com", "Apple"],
+  ["archive.org", "Internet Archive"],
+  ["ask.com", "Ask.com"],
+  ["att.com", "AT&T"],
+  ["aws.amazon.com", "AWS"],
+  ["bankofamerica.com", "Bank of America"],
+  ["bbc.co.uk", "BBC"],
+  ["bbc.com", "BBC"],
+  ["bestbuy.com", "Best Buy"],
+  ["bing.com", "Bing"],
+  ["blogger.com", "Blogger"],
+  ["bloomberg.com", "Bloomberg"],
+  ["bluehost.com", "Bluehost"],
+  ["booking.com", "Booking.com"],
+  ["bscscan.com", "BscScan"],
+  ["businessinsider.com", "Insider"],
+  ["ca.gov", "California State Portal"],
+  ["canada.ca", "Government of Canada"],
+  ["canva.com", "Canva"],
+  ["capitalone.com", "Capital One"],
+  ["cdc.gov", "CDC.gov"],
+  ["chase.com", "Chase"],
+  ["chess.com", "Chess.com"],
+  ["citi.com", "Citi.com"],
+  ["cj.com", "CJ Affiliate"],
+  ["cnbc.com", "CNBC"],
+  ["cnet.com", "CNET"],
+  ["cnn.com", "CNN"],
+  ["cnnindonesia.com", "CNN Indonesia"],
+  ["coingecko.com", "CoinGecko"],
+  ["coinmarketcap.com", "CoinMarketCap"],
+  ["constantcontact.com", "Constant Contact"],
+  ["coursera.org", "Coursera"],
+  ["cowin.gov.in", "CoWIN"],
+  ["craigslist.org", "Craigslist"],
+  ["dailymail.co.uk", "Daily Mail"],
+  ["dailymotion.com", "Dailymotion"],
+  ["deepl.com", "DeepL"],
+  ["dell.com", "Dell"],
+  ["discord.com", "Discord"],
+  ["disneyplus.com", "Disney+"],
+  ["docs.google.com", "Google Docs"],
+  ["docusign.net", "DocuSign"],
+  ["drive.google.com", "Google Drive"],
+  ["dropbox.com", "Dropbox"],
+  ["duckduckgo.com", "DuckDuckGo"],
+  ["ebay.co.uk", "eBay"],
+  ["ebay.com", "eBay"],
+  ["ebay.de", "eBay"],
+  ["espn.com", "ESPN"],
+  ["etherscan.io", "Etherscan"],
+  ["etrade.com", "E*TRADE"],
+  ["etsy.com", "Etsy"],
+  ["evernote.com", "Evernote"],
+  ["expedia.com", "Expedia"],
+  ["facebook.com", "Facebook"],
+  ["fandom.com", "Fandom"],
+  ["fast.com", "Fast.com"],
+  ["fedex.com", "FedEx"],
+  ["feedly.com", "Feedly"],
+  ["fidelity.com", "Fidelity"],
+  ["fiverr.com", "Fiverr"],
+  ["flickr.com", "Flickr"],
+  ["flipkart.com", "Flipkart"],
+  ["force.com", "Salesforce"],
+  ["foxnews.com", "Fox News"],
+  ["freshdesk.com", "Freshdesk"],
+  ["geeksforgeeks.org", "GeeksforGeeks"],
+  ["github.com", "GitHub"],
+  ["glassdoor.com", "Glassdoor"],
+  ["gmail.com", "Gmail"],
+  ["godaddy.com", "GoDaddy"],
+  ["goodreads.com", "Goodreads"],
+  ["google.az", "Google"],
+  ["google.ca", "Google"],
+  ["google.cn", "Google"],
+  ["google.co.id", "Google"],
+  ["google.co.in", "Google"],
+  ["google.co.jp", "Google"],
+  ["google.co.th", "Google"],
+  ["google.co.uk", "Google"],
+  ["google.com", "Google"],
+  ["google.com.ar", "Google"],
+  ["google.com.au", "Google"],
+  ["google.com.br", "Google"],
+  ["google.com.eg", "Google"],
+  ["google.com.hk", "Google"],
+  ["google.com.mx", "Google"],
+  ["google.com.sa", "Google"],
+  ["google.com.sg", "Google"],
+  ["google.com.tr", "Google"],
+  ["google.com.tw", "Google"],
+  ["google.de", "Google"],
+  ["google.es", "Google"],
+  ["google.fr", "Google"],
+  ["google.it", "Google"],
+  ["google.pl", "Google"],
+  ["google.ru", "Google"],
+  ["googlevideo.com", "Google Video"],
+  ["grammarly.com", "Grammarly"],
+  ["hbomax.com", "HBO Max"],
+  ["healthline.com", "Healthline"],
+  ["homedepot.com", "The Home Depot"],
+  ["hootsuite.com", "Hootsuite"],
+  ["hostgator.com", "HostGator"],
+  ["hotstar.com", "Hotstar"],
+  ["hp.com", "HP"],
+  ["hulu.com", "Hulu"],
+  ["icicibank.com", "ICICI Bank"],
+  ["ikea.com", "IKEA"],
+  ["ilovepdf.com", "iLovePDF"],
+  ["imdb.com", "IMDb"],
+  ["imgur.com", "Imgur"],
+  ["indeed.com", "Indeed"],
+  ["indiamart.com", "IndiaMART"],
+  ["indiatimes.com", "Indiatimes"],
+  ["instagram.com", "Instagram"],
+  ["instructure.com", "Instructure"],
+  ["intuit.com", "Intuit"],
+  ["investing.com", "Investing.com"],
+  ["iqbroker.com", "IQ Option"],
+  ["irs.gov", "IRS.gov"],
+  ["istockphoto.com", "iStock"],
+  ["japanpost.jp", "Japan Post"],
+  ["kayak.com ", "Kayak"],
+  ["linkedin.com", "LinkedIn"],
+  ["linktr.ee", "Linktree"],
+  ["live.com", "Live"],
+  ["loom.com", "Loom"],
+  ["mail.google.com", "Gmail"],
+  ["mailchimp.com", "Mailchimp"],
+  ["manage.wix.com", "Wix"],
+  ["maps.google.com", "Google Maps"],
+  ["marca.com", "MARCA"],
+  ["mediafire.com", "MediaFire"],
+  ["mercadolibre.com.mx", "Mercado Libre"],
+  ["mercadolivre.com.br", "Mercado Livre"],
+  ["mercari.com", "Mercari"],
+  ["microsoft.com", "Microsoft"],
+  ["mlb.com", "MLB.com"],
+  ["moneycontrol.com", "moneycontrol.com"],
+  ["mozilla.org", "Mozilla"],
+  ["msn.com", "MSN"],
+  ["myshopify.com", "Shopify"],
+  ["myworkdayjobs.com", "Workday"],
+  ["naukri.com", "Naukri.com"],
+  ["ndtv.com", "NDTV.com"],
+  ["netflix.com", "Netflix"],
+  ["nih.gov", "National Institutes of Health (NIH)"],
+  ["nike.com", "Nike"],
+  ["nordstrom.com", "Nordstrom"],
+  ["notion.so", "Notion"],
+  ["nypost.com", "New York Post"],
+  ["nytimes.com", "New York Times"],
+  ["office.com", "Office"],
+  ["office365.com", "Office 365"],
+  ["olympics.com", "Olympics"],
+  ["onlinesbi.com", "State Bank of India"],
+  ["orange.fr", "Orange"],
+  ["patreon.com", "Patreon"],
+  ["paypal.com", "PayPal"],
+  ["pinterest.com", "Pinterest"],
+  ["primevideo.com", "Prime Video"],
+  ["quora.com", "Quora"],
+  ["rakuten.co.jp", "Rakuten"],
+  ["rakuten.com", "Rakuten"],
+  ["realtor.com", "Realtor.com"],
+  ["redd.it", "Reddit"],
+  ["reddit.com", "Reddit"],
+  ["redfin.com", "Redfin"],
+  ["researchgate.net", "ResearchGate"],
+  ["reuters.com", "Reuters"],
+  ["reverso.net", "Reverso"],
+  ["roblox.com", "Roblox"],
+  ["rt.com", "RT"],
+  ["salesforce.com", "Salesforce"],
+  ["samsung.com", "Samsung"],
+  ["scribd.com", "Scribd"],
+  ["sheets.google.com", "Google Sheets"],
+  ["shein.com", "Shein"],
+  ["shutterstock.com", "Shutterstock"],
+  ["skype.com", "Skype"],
+  ["slides.google.com", "Google Slides"],
+  ["slideshare.net", "SlideShare"],
+  ["soundcloud.com", "SoundCloud"],
+  ["speedtest.net", "Speedtest"],
+  ["spotify.com", "Spotify"],
+  ["squarespace.com", "Squarespace"],
+  ["stackexchange.com", "Stack Exchange"],
+  ["stackoverflow.com", "Stack Overflow"],
+  ["steampowered.com", "Steam"],
+  ["taboola.com", "Taboola.com"],
+  ["target.com", "Target"],
+  ["td.com", "TD Bank"],
+  ["telegram.org", "Telegram"],
+  ["theguardian.com", "The Guardian"],
+  ["tiktok.com", "TikTok"],
+  ["tmall.com", "Tmall"],
+  ["tokopedia.com", "Tokopedia"],
+  ["trello.com", "Trello"],
+  ["tripadvisor.com", "Tripadvisor"],
+  ["trustpilot.com", "Trustpilot"],
+  ["twitch.tv", "Twitch"],
+  ["twitter.com", "Twitter"],
+  ["udemy.com", "Udemy"],
+  ["unsplash.com", "Unsplash"],
+  ["ups.com", "UPS"],
+  ["upwork.com", "Upwork"],
+  ["usps.com", "USPS"],
+  ["vimeo.com", "Vimeo"],
+  ["w3schools.com", "W3Schools"],
+  ["walmart.com", "Walmart"],
+  ["washingtonpost.com", "Washington Post"],
+  ["wayfair.com", "Wayfair"],
+  ["weather.com", "The Weather Channel"],
+  ["webmd.com", "WebMD"],
+  ["wellsfargo.com", "Wells Fargo"],
+  ["wetransfer.com", "WeTransfer"],
+  ["whatsapp.com", "WhatsApp"],
+  ["wikihow.com", "wikiHow"],
+  ["wikimedia.org", "Wikimedia Commons"],
+  ["wikipedia.org", "Wikipedia"],
+  ["wildberries.ru", "Wildberries"],
+  ["wordpress.org", "WordPress.org"],
+  ["worldometers.info", "Worldometer"],
+  ["wsj.com", "Wall Street Journal"],
+  ["xfinity.com", "Xfinity"],
+  ["y2mate.com", "Y2mate"],
+  ["yahoo.co.jp", "Yahoo Japan"],
+  ["yahoo.com", "Yahoo"],
+  ["yandex.ru", "Yandex"],
+  ["yelp.com", "Yelp"],
+  ["youtube.com", "YouTube"],
+  ["zendesk.com", "Zendesk"],
+  ["zerodha.com", "Zerodha"],
+  ["zillow.com", "Zillow"],
+  ["zoom.us", "Zoom"],
+]);
+
+/**
+ * Maps the domains from CUSTOM_NAMES to a regex that matches a URL ending with
+ * that domain, meaning the regex also captures potential subdomains.
+ */
+XPCOMUtils.defineLazyGetter(this, "CUSTOM_NAMES_REGEX", () => {
+  let regexMap = new Map();
+  for (let suffix of CUSTOM_NAMES.keys()) {
+    let reg = new RegExp(`^(.+\.)?${suffix}$`);
+    regexMap.set(suffix, reg);
+  }
+  return regexMap;
+});
+
+/**
+ * A class that exposes a static method to return a site's "common name". This
+ * is ideally the site's brand name with appropriate spacing and capitalization.
+ * For example, the common name for stackoverflow.com is "Stack Overflow". If
+ * a common name cannot be fetched, the origin is returned with its TLD
+ * stripped, e.g. "stackoverflow".
+ */
+class CommonNames {
+  /**
+   * Returns a snapshot's common name.
+   *
+   * @param {Snapshot} snapshot
+   *   The snapshot for which to fetch a common name. See Snapshots.jsm for a
+   *   definition.
+   * @returns {string} The snapshot's common name.
+   */
+  static getName(snapshot) {
+    let commonName = snapshot.pageData.get(PageDataCollector.DATA_TYPE.GENERAL)
+      ?.site_name;
+    if (commonName) {
+      return commonName;
+    }
+
+    let url = new URL(snapshot.url);
+    let longest = null;
+    for (let suffix of CUSTOM_NAMES.keys()) {
+      let reg = CUSTOM_NAMES_REGEX.get(suffix);
+      if (reg.test(url.hostname)) {
+        longest = !longest || longest.length < suffix.length ? suffix : longest;
+      }
+    }
+
+    return longest ? CUSTOM_NAMES.get(longest) : shortURL({ url });
+  }
+}
--- a/browser/components/places/Snapshots.jsm
+++ b/browser/components/places/Snapshots.jsm
@@ -8,16 +8,17 @@ var EXPORTED_SYMBOLS = ["Snapshots"];
 
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
 
 const VERSION_PREF = "browser.places.snapshots.version";
 
 XPCOMUtils.defineLazyModuleGetters(this, {
+  CommonNames: "resource:///modules/CommonNames.jsm",
   Interactions: "resource:///modules/Interactions.jsm",
   PageDataCollector: "resource:///modules/pagedata/PageDataCollector.jsm",
   PageDataService: "resource:///modules/pagedata/PageDataService.jsm",
   PlacesUtils: "resource://gre/modules/PlacesUtils.jsm",
   Services: "resource://gre/modules/Services.jsm",
 });
 
 /**
@@ -418,31 +419,34 @@ const Snapshots = new (class Snapshots {
       try {
         let dataArray = JSON.parse(`[${pageDataStr}]`);
         dataArray.forEach(d => pageData.set(d.type, d.data));
       } catch (e) {
         logConsole.error(e);
       }
     }
 
-    return {
+    let snapshot = {
       url: row.getResultByName("url"),
       title: row.getResultByName("title"),
       createdAt: this.#toDate(row.getResultByName("created_at")),
       removedAt: this.#toDate(row.getResultByName("removed_at")),
       firstInteractionAt: this.#toDate(
         row.getResultByName("first_interaction_at")
       ),
       lastInteractionAt: this.#toDate(
         row.getResultByName("last_interaction_at")
       ),
       documentType: row.getResultByName("document_type"),
       userPersisted: !!row.getResultByName("user_persisted"),
       pageData,
     };
+
+    snapshot.commonName = CommonNames.getName(snapshot);
+    return snapshot;
   }
 
   /**
    * Translates a date value from the database.
    *
    * @param {number} value
    *   The date in milliseconds from the epoch.
    * @returns {Date?}
--- a/browser/components/places/moz.build
+++ b/browser/components/places/moz.build
@@ -12,16 +12,17 @@ MOCHITEST_CHROME_MANIFESTS += ["tests/ch
 BROWSER_CHROME_MANIFESTS += [
     "tests/browser/browser.ini",
     "tests/browser/interactions/browser.ini",
 ]
 
 JAR_MANIFESTS += ["jar.mn"]
 
 EXTRA_JS_MODULES += [
+    "CommonNames.jsm",
     "Interactions.jsm",
     "InteractionsBlocklist.jsm",
     "PlacesUIUtils.jsm",
     "Snapshots.jsm",
     "SnapshotSelector.jsm",
 ]
 
 FINAL_TARGET_FILES.actors += [
--- a/browser/components/places/tests/unit/interactions/head_interactions.js
+++ b/browser/components/places/tests/unit/interactions/head_interactions.js
@@ -186,16 +186,23 @@ function assertSnapshot(actual, expected
   }
   if (expected.lastUpdated) {
     Assert.greaterOrEqual(
       actual.lastInteractionAt,
       expected.lastUpdated,
       "Should have a last interaction time greater than or equal to the expected last updated time"
     );
   }
+  if (expected.commonName) {
+    Assert.equal(
+      actual.commonName,
+      expected.commonName,
+      "Should have the Snapshot URL's common name."
+    );
+  }
   if (expected.removedAt) {
     Assert.greaterOrEqual(
       actual.removedAt.getTime(),
       expected.removedAt.getTime(),
       "Should have the removed at time greater than or equal to the expected removed at time"
     );
   } else {
     Assert.strictEqual(
new file mode 100644
--- /dev/null
+++ b/browser/components/places/tests/unit/interactions/test_commonNames.js
@@ -0,0 +1,153 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const TEST_URL1 = "https://example.com/";
+const TEST_URL2 = "https://mozilla.org:8080/12345";
+const TEST_URL3 = "https://google.com/";
+const TEST_URL4 = "https://example.com/1234";
+const TEST_URL5 = "https://en.wikipedia.org/";
+const TEST_URL6 = "https://maps.google.com/";
+/**
+ * Tests CommonNames.jsm, the module that returns a URL's "common name" —
+ * usually, the site's brand name with correct spacing and capitalization.
+ */
+
+XPCOMUtils.defineLazyModuleGetters(this, {
+  PageDataCollector: "resource:///modules/pagedata/PageDataCollector.jsm",
+  PageDataService: "resource:///modules/pagedata/PageDataService.jsm",
+});
+
+add_task(async function setup() {
+  await Interactions.reset();
+  await addInteractions([
+    { url: TEST_URL1 },
+    { url: TEST_URL2 },
+    { url: TEST_URL3 },
+    { url: TEST_URL4 },
+    { url: TEST_URL5 },
+    { url: TEST_URL6 },
+  ]);
+
+  registerCleanupFunction(async () => {
+    await Interactions.reset();
+  });
+});
+
+/**
+ * Tests that we return site_name page data as a common name.
+ */
+add_task(async function fromMetadata() {
+  PageDataService.pageDataDiscovered(TEST_URL1, [
+    {
+      type: PageDataCollector.DATA_TYPE.GENERAL,
+      data: {
+        site_name: "Test Example",
+      },
+    },
+  ]);
+  await assertUrlNotification(TOPIC_ADDED, [TEST_URL1], () =>
+    Snapshots.add({ url: TEST_URL1 })
+  );
+
+  let snapshot = await Snapshots.get(TEST_URL1);
+  Assert.equal(
+    snapshot.commonName,
+    "Test Example",
+    "snapshot.commonName should contain the site_name data."
+  );
+});
+
+/**
+ * Tests that we return a value from our custom list if we have no site_name
+ * metadata for a site.
+ *
+ * This subtest depends on mozilla.org being in the CUSTOM_LIST map in
+ * CommonNames.jsm.
+ */
+add_task(async function customName_noMetadata() {
+  await assertUrlNotification(TOPIC_ADDED, [TEST_URL2], () =>
+    Snapshots.add({ url: TEST_URL2 })
+  );
+
+  let snapshot = await Snapshots.get(TEST_URL2);
+  Assert.equal(
+    snapshot.commonName,
+    "Mozilla",
+    "snapshot.commonName should contain our custom label."
+  );
+});
+
+/**
+ * Tests that we return site_name page data as a common name even if that site
+ * is in the CUSTOM_LIST map in CommonNames.jsm.
+ *
+ * This subtest depends on google.com being in the CUSTOM_LIST map in
+ * CommonNames.jsm.
+ */
+add_task(async function customName_withMetadata() {
+  PageDataService.pageDataDiscovered(TEST_URL3, [
+    {
+      type: PageDataCollector.DATA_TYPE.GENERAL,
+      data: {
+        site_name: "Test Example 2",
+      },
+    },
+  ]);
+  await assertUrlNotification(TOPIC_ADDED, [TEST_URL3], () =>
+    Snapshots.add({ url: TEST_URL3 })
+  );
+
+  let snapshot = await Snapshots.get(TEST_URL3);
+  Assert.equal(
+    snapshot.commonName,
+    "Test Example 2",
+    "snapshot.commonName should contain site_name data even though it's on the custom list."
+  );
+});
+
+/**
+ * Tests that we return the URL without its TLD when we don't have any data
+ * about a URL.
+ */
+add_task(async function shortUrl() {
+  await assertUrlNotification(TOPIC_ADDED, [TEST_URL4], () =>
+    Snapshots.add({ url: TEST_URL4 })
+  );
+
+  let snapshot = await Snapshots.get(TEST_URL4);
+  Assert.equal(
+    snapshot.commonName,
+    "example",
+    "snapshot.commonName should contain the URL with the TLD stripped."
+  );
+});
+
+/**
+ * Tests that we strip subdomains from a snapshot's URL iff CUSTOM_LIST does not
+ * contain a URL with those subdomains.
+ *
+ * This subtest depends on wikipedia.org and maps.google.com being in
+ * CUSTOM_LIST.
+ */
+add_task(async function subdomains() {
+  await assertUrlNotification(TOPIC_ADDED, [TEST_URL5], () =>
+    Snapshots.add({ url: TEST_URL5 })
+  );
+  await assertUrlNotification(TOPIC_ADDED, [TEST_URL6], () =>
+    Snapshots.add({ url: TEST_URL6 })
+  );
+
+  let snapshot = await Snapshots.get(TEST_URL5);
+  Assert.equal(
+    snapshot.commonName,
+    "Wikipedia",
+    "snapshot.commonName should match wikipedia.org even though en.wikipedia.org was passed in."
+  );
+
+  snapshot = await Snapshots.get(TEST_URL6);
+  Assert.equal(
+    snapshot.commonName,
+    "Google Maps",
+    "snapshot.commonName should match Google Maps even though google.com is in the custom list."
+  );
+});
--- a/browser/components/places/tests/unit/interactions/xpcshell.ini
+++ b/browser/components/places/tests/unit/interactions/xpcshell.ini
@@ -3,16 +3,17 @@ prefs =
   browser.places.interactions.enabled=true
   browser.places.interactions.log=true
   browser.pagedata.enabled=true
   browser.pagedata.log=true
 head = head_interactions.js
 firefox-appdir = browser
 skip-if = toolkit == 'android'
 
+[test_commonNames.js]
 [test_snapshot_added_no_interaction.js]
 [test_snapshots_basics.js]
 [test_snapshots_create_criteria.js]
 [test_snapshots_pagedata.js]
 [test_snapshots_queries.js]
 [test_snapshotselection_recent.js]
 [test_snapshotselection_setUrlAndRebuildNow.js]
 [test_snapshotselection_typed.js]