diff --git a/src/chrome/src/agent/adapters.js b/src/chrome/src/agent/adapters.js index 258d83d6b..03369a34b 100644 --- a/src/chrome/src/agent/adapters.js +++ b/src/chrome/src/agent/adapters.js @@ -16515,6 +16515,22 @@ const ADAPTERS = [ - Search hosts (listado.mercadolibre.com.ar, listado.mercadolibre.com.mx, lista.mercadolivre.com.br) can redirect automation to /gz/account-verification. If that wall appears, STOP and ask the user to complete it manually — do not retry, bypass, or claim results were read.`, }, + // ─── Regional — Shopee (Southeast Asia, Taiwan, LATAM) ─────────────── + { + name: 'shopee', + category: 'general', + matches: (url) => /^https?:\/\/(?:www\.)?(?:shopee\.(?:com|sg|vn|tw|co\.th|com\.mx|com\.my|com\.br|com\.la|com\.ar|co\.id|ph)|shopeekh\.com)\//.test(url), + notes: ` +- As of 2026-08, shopee.com is a "Choose a country or region" handoff to separate regional storefronts. Choose the user's actual market before searching: accounts, catalog, currency, stock, delivery addresses, vouchers, and payment methods are region-specific, so availability in one storefront is not proof that another can fulfill it. +- A storefront may first show a language chooser or redirect to /verify/traffic/error with an almost empty page. Select the user's language when offered; for /verify/traffic, stop retries and ask the user to complete the traffic check manually in the current tab, then re-read it. Do not treat the empty tree as no results or try to bypass the check. +- On a product page select the preferred variation and quantity before comparing or adding it. Key labels include Indonesian "Masukkan Keranjang" / "Beli Sekarang", Vietnamese "Thêm Vào Giỏ Hàng" / "Mua Ngay", Thai "เพิ่มไปยังรถเข็น" / "ซื้อเลย", Chinese "加入購物車" / "直接購買", and Portuguese "Adicionar ao Carrinho" / "Comprar Agora"; use only the labels visible in the active market. +- Shopee is a multi-seller marketplace. A Shopee Mall badge identifies a participating official store, but still read the selected seller, shop profile, ratings, item reviews, return terms, stock, origin, shipping option, and arrival estimate; product reviews and a Mall badge do not prove every seller offer is equivalent. +- Discounts are conditional. A seller voucher, free shipping voucher, and platform voucher can have separate minimum spend, product, payment, user, quota, and expiry rules. Shipping also varies by seller; apply only eligible vouchers and quote the final checkout total separately from coins, cashback, and advertised savings. +- "Add to Cart" preserves a multi-item review step; "Buy Now" jumps directly to checkout. Re-read every selected variation, quantity, seller, shipping option, address, voucher, payment method, and total before "Place Order", and require the user's explicit confirmation before placing or paying for an order. +- Login can require password, SMS OTP, QR confirmation in the Shopee app, CAPTCHA, or trusted-device approval. Ask the user to complete any OTP, QR, or account verification manually; never request, read, repeat, or expose a verification code, and continue from the returned page instead of restarting the task. +- "Order Received" can release held purchase funds to the seller and affect guarantee or return timing. Never select it from tracking status alone; require the user's explicit confirmation that the exact goods arrived and were inspected. Report a placed order only from the confirmation or My Purchases page with an order ID; a cart, checkout, payment prompt, or submitted request is incomplete.`, + }, + // ─── Regional — Flipkart (India) ───────────────────────────────────── { name: 'flipkart', diff --git a/src/chrome/src/ui/recommended-actions.js b/src/chrome/src/ui/recommended-actions.js index c1da60abd..4e46184c6 100644 --- a/src/chrome/src/ui/recommended-actions.js +++ b/src/chrome/src/ui/recommended-actions.js @@ -5,7 +5,7 @@ const SOCIAL_HOST_RE = /(^|\.)(instagram\.com|tiktok\.com|x\.com|twitter\.com|fa const PUBLIC_MEDIA_HOST_RE = /(^|\.)(youtube\.com|youtu\.be|tiktok\.com|instagram\.com|x\.com|twitter\.com|reddit\.com|redd\.it|facebook\.com|fb\.com|fb\.watch|pinterest\.com|pin\.it|linkedin\.com|threads\.net)$/i; const MEETING_HOST_RE = /(^|\.)(zoom\.us|meet\.google\.com|teams\.microsoft\.com|whereby\.com|webex\.com|gotomeeting\.com)$/i; const DATING_HOST_RE = /(^|\.)(tinder\.com|bumble\.com|hinge\.co|okcupid\.com|match\.com|pof\.com|badoo\.com|happn\.com|coffeemeetsbagel\.com)$/i; -const SHOPPING_HOST_RE = /(^|\.)(amazon\.[a-z.]+|ebay\.[a-z.]+|etsy\.com|walmart\.com|target\.com|bestbuy\.com|shopify\.com|aliexpress\.com|mercadolibre\.[a-z.]+|mercadolivre\.com\.br|hepsiburada\.com|trendyol\.com|n11\.com|shopee\.[a-z.]+|lazada\.[a-z.]+)$/i; +const SHOPPING_HOST_RE = /(^|\.)(amazon\.[a-z.]+|ebay\.[a-z.]+|etsy\.com|walmart\.com|target\.com|bestbuy\.com|shopify\.com|aliexpress\.com|mercadolibre\.[a-z.]+|mercadolivre\.com\.br|hepsiburada\.com|trendyol\.com|n11\.com|shopee\.[a-z.]+|shopeekh\.com|lazada\.[a-z.]+)$/i; const PRODUCT_PATH_RE = /\/(dp|gp\/product|itm|p|product|products|prod|item|listing|ilan|urun)\b/i; const RELEASES_PATH_RE = /^\/[^/]+\/[^/]+\/releases(?:\/|$)/i; const SEARCH_INPUT_RE = /^(search|q|query|keyword|keywords|s)$/i; diff --git a/src/firefox/src/agent/adapters.js b/src/firefox/src/agent/adapters.js index 2459b6da2..a805bc5c9 100644 --- a/src/firefox/src/agent/adapters.js +++ b/src/firefox/src/agent/adapters.js @@ -16513,6 +16513,22 @@ const ADAPTERS = [ - Search hosts (listado.mercadolibre.com.ar, listado.mercadolibre.com.mx, lista.mercadolivre.com.br) can redirect automation to /gz/account-verification. If that wall appears, STOP and ask the user to complete it manually — do not retry, bypass, or claim results were read.`, }, + // ─── Regional — Shopee (Southeast Asia, Taiwan, LATAM) ─────────────── + { + name: 'shopee', + category: 'general', + matches: (url) => /^https?:\/\/(?:www\.)?(?:shopee\.(?:com|sg|vn|tw|co\.th|com\.mx|com\.my|com\.br|com\.la|com\.ar|co\.id|ph)|shopeekh\.com)\//.test(url), + notes: ` +- As of 2026-08, shopee.com is a "Choose a country or region" handoff to separate regional storefronts. Choose the user's actual market before searching: accounts, catalog, currency, stock, delivery addresses, vouchers, and payment methods are region-specific, so availability in one storefront is not proof that another can fulfill it. +- A storefront may first show a language chooser or redirect to /verify/traffic/error with an almost empty page. Select the user's language when offered; for /verify/traffic, stop retries and ask the user to complete the traffic check manually in the current tab, then re-read it. Do not treat the empty tree as no results or try to bypass the check. +- On a product page select the preferred variation and quantity before comparing or adding it. Key labels include Indonesian "Masukkan Keranjang" / "Beli Sekarang", Vietnamese "Thêm Vào Giỏ Hàng" / "Mua Ngay", Thai "เพิ่มไปยังรถเข็น" / "ซื้อเลย", Chinese "加入購物車" / "直接購買", and Portuguese "Adicionar ao Carrinho" / "Comprar Agora"; use only the labels visible in the active market. +- Shopee is a multi-seller marketplace. A Shopee Mall badge identifies a participating official store, but still read the selected seller, shop profile, ratings, item reviews, return terms, stock, origin, shipping option, and arrival estimate; product reviews and a Mall badge do not prove every seller offer is equivalent. +- Discounts are conditional. A seller voucher, free shipping voucher, and platform voucher can have separate minimum spend, product, payment, user, quota, and expiry rules. Shipping also varies by seller; apply only eligible vouchers and quote the final checkout total separately from coins, cashback, and advertised savings. +- "Add to Cart" preserves a multi-item review step; "Buy Now" jumps directly to checkout. Re-read every selected variation, quantity, seller, shipping option, address, voucher, payment method, and total before "Place Order", and require the user's explicit confirmation before placing or paying for an order. +- Login can require password, SMS OTP, QR confirmation in the Shopee app, CAPTCHA, or trusted-device approval. Ask the user to complete any OTP, QR, or account verification manually; never request, read, repeat, or expose a verification code, and continue from the returned page instead of restarting the task. +- "Order Received" can release held purchase funds to the seller and affect guarantee or return timing. Never select it from tracking status alone; require the user's explicit confirmation that the exact goods arrived and were inspected. Report a placed order only from the confirmation or My Purchases page with an order ID; a cart, checkout, payment prompt, or submitted request is incomplete.`, + }, + // ─── Regional — Flipkart (India) ───────────────────────────────────── { name: 'flipkart', diff --git a/src/firefox/src/ui/recommended-actions.js b/src/firefox/src/ui/recommended-actions.js index 0d412132e..88bc0bc94 100644 --- a/src/firefox/src/ui/recommended-actions.js +++ b/src/firefox/src/ui/recommended-actions.js @@ -4,7 +4,7 @@ import { t } from './i18n.js'; const SOCIAL_HOST_RE = /(^|\.)(instagram\.com|tiktok\.com|x\.com|twitter\.com|facebook\.com|fb\.com|threads\.net|youtube\.com|youtu\.be|reddit\.com|pinterest\.com|snapchat\.com)$/i; const PUBLIC_MEDIA_HOST_RE = /(^|\.)(youtube\.com|youtu\.be|tiktok\.com|instagram\.com|x\.com|twitter\.com|reddit\.com|redd\.it|facebook\.com|fb\.com|fb\.watch|pinterest\.com|pin\.it|linkedin\.com|threads\.net)$/i; const DATING_HOST_RE = /(^|\.)(tinder\.com|bumble\.com|hinge\.co|okcupid\.com|match\.com|pof\.com|badoo\.com|happn\.com|coffeemeetsbagel\.com)$/i; -const SHOPPING_HOST_RE = /(^|\.)(amazon\.[a-z.]+|ebay\.[a-z.]+|etsy\.com|walmart\.com|target\.com|bestbuy\.com|shopify\.com|aliexpress\.com|mercadolibre\.[a-z.]+|mercadolivre\.com\.br|hepsiburada\.com|trendyol\.com|n11\.com|shopee\.[a-z.]+|lazada\.[a-z.]+)$/i; +const SHOPPING_HOST_RE = /(^|\.)(amazon\.[a-z.]+|ebay\.[a-z.]+|etsy\.com|walmart\.com|target\.com|bestbuy\.com|shopify\.com|aliexpress\.com|mercadolibre\.[a-z.]+|mercadolivre\.com\.br|hepsiburada\.com|trendyol\.com|n11\.com|shopee\.[a-z.]+|shopeekh\.com|lazada\.[a-z.]+)$/i; const PRODUCT_PATH_RE = /\/(dp|gp\/product|itm|p|product|products|prod|item|listing|ilan|urun)\b/i; const RELEASES_PATH_RE = /^\/[^/]+\/[^/]+\/releases(?:\/|$)/i; const SEARCH_INPUT_RE = /^(search|q|query|keyword|keywords|s)$/i; diff --git a/test/run.js b/test/run.js index b46a37430..31da2030c 100644 --- a/test/run.js +++ b/test/run.js @@ -2868,6 +2868,53 @@ test('matches Mercado Libre LATAM storefronts and includes marketplace guidance' assert.equal(firefoxAdapter?.notes, adapter?.notes); }); +test('matches current Shopee regional storefronts with marketplace guidance', () => { + const trustedUrls = [ + 'https://shopee.com/', + 'https://shopee.sg/search?keyword=phone', + 'https://www.shopee.vn/example-shop/example-item', + 'https://shopee.tw/', + 'https://shopee.co.th/', + 'https://shopee.com.mx/', + 'https://shopee.com.my/', + 'https://shopee.com.br/', + 'https://shopee.com.la/', + 'https://shopee.com.ar/', + 'https://shopee.co.id/', + 'https://shopee.ph/', + 'https://www.shopeekh.com/', + ]; + for (const url of trustedUrls) { + assert.equal(getActiveAdapter(url)?.name, 'shopee'); + assert.equal(getActiveAdapterFx(url)?.name, 'shopee'); + } + + const rejectedUrls = [ + 'https://seller.shopee.sg/', + 'https://help.shopee.sg/portal/4', + 'https://account.seller.shopee.com/signin', + 'https://shopee.com.phishing.example/search?keyword=phone', + 'https://example.com/?next=https://shopee.sg/', + ]; + for (const url of rejectedUrls) { + assert.notEqual(getActiveAdapter(url)?.name, 'shopee'); + assert.notEqual(getActiveAdapterFx(url)?.name, 'shopee'); + } + + const adapter = getActiveAdapter(trustedUrls[1]); + const firefoxAdapter = getActiveAdapterFx(trustedUrls.at(-1)); + assert.match(adapter?.notes || '', /2026-08.*Choose a country or region/s); + assert.match(adapter?.notes || '', /verify\/traffic.*complete.*manually/s); + assert.match(adapter?.notes || '', /preferred variation.*Masukkan Keranjang.*Thêm Vào Giỏ Hàng.*加入購物車/s); + assert.match(adapter?.notes || '', /Shopee Mall.*seller.*ratings/s); + assert.match(adapter?.notes || '', /seller voucher.*free shipping voucher.*platform voucher.*minimum spend/s); + assert.match(adapter?.notes || '', /Add to Cart.*Buy Now.*Place Order/s); + assert.match(adapter?.notes || '', /OTP.*manually/s); + assert.match(adapter?.notes || '', /Order Received.*release.*funds.*order ID/s); + assert.equal((adapter?.notes || '').trim().split('\n').filter((line) => line.startsWith('- ')).length, 8); + assert.equal(firefoxAdapter?.notes, adapter?.notes); +}); + test('matches Flipkart shopping surfaces with India marketplace guidance', () => { const trustedUrls = [ 'https://flipkart.com/', @@ -9737,6 +9784,17 @@ test('recommended actions match issue scenarios', () => { } }); +for (const [label, buildRecommendedActions] of [['chrome', buildRecommendedActionsCh], ['firefox', buildRecommendedActionsFx]]) { + test(`recommended actions recognize Shopee Cambodia's distinct hostname in ${label}`, () => { + const actions = buildRecommendedActions({ + url: 'https://www.shopeekh.com/kh-en/detail/123', + title: 'Wireless headphones', + description: 'US$20.00', + }); + assert.ok(actions.some((action) => action.id === 'compare-price')); + }); +} + test('WebBrain promotion has explicit X and LinkedIn variants with ready-to-go plans', () => { const exactPost = 'Introducing WebBrain — an open-source AI browser agent that lives in your browser. Chat with any page, automate multi-step workflows, and bring your own LLM. Extensible by design. Try it: https://webbrain.one'; const expectedTweetSteps = [