diff --git a/packages/core/src/scrapers/ebay.ts b/packages/core/src/scrapers/ebay.ts index 75eec88..b7fae76 100644 --- a/packages/core/src/scrapers/ebay.ts +++ b/packages/core/src/scrapers/ebay.ts @@ -1,8 +1,8 @@ import { parseHTML } from "linkedom"; import { type CookieConfig, + ensureCookies, formatCookiesForHeader, - loadCookiesOptional, } from "../utils/cookies"; import { delay } from "../utils/delay"; @@ -11,7 +11,6 @@ const EBAY_COOKIE_CONFIG: CookieConfig = { name: "eBay", domain: ".ebay.ca", envVar: "EBAY_COOKIE", - filePath: "./cookies/ebay.json", }; // ----------------------------- Types ----------------------------- @@ -335,27 +334,18 @@ function parseEbayListings( // ----------------------------- Cookie Loading ----------------------------- /** - * Load eBay cookies with priority: URL param > ENV var > file - * Uses shared cookie utility for consistent handling across all scrapers + * Load eBay cookies from EBAY_COOKIE */ -async function loadEbayCookies( - cookiesSource?: string, -): Promise { - const cookies = await loadCookiesOptional(EBAY_COOKIE_CONFIG, cookiesSource); - - if (cookies.length === 0) { +async function loadEbayCookies(): Promise { + try { + const cookies = await ensureCookies(EBAY_COOKIE_CONFIG); + return formatCookiesForHeader(cookies, "www.ebay.ca"); + } catch { console.warn( - "No eBay cookies found. eBay may block requests without valid session cookies.\n" + - "Provide cookies via (in priority order):\n" + - " 1. 'cookies' URL parameter (highest priority), or\n" + - " 2. EBAY_COOKIE environment variable, or\n" + - " 3. ./cookies/ebay.json file (lowest priority)\n" + - 'Format: JSON array or cookie string like "name1=value1; name2=value2"', + "No valid eBay cookies found in EBAY_COOKIE. eBay may block requests without a raw Cookie header string.", ); return undefined; } - - return formatCookiesForHeader(cookies, "www.ebay.ca"); } // ----------------------------- Main ----------------------------- @@ -371,7 +361,6 @@ export default async function fetchEbayItems( keywords?: string[]; buyItNowOnly?: boolean; canadaOnly?: boolean; - cookies?: string; // Optional: Cookie string or JSON (helps bypass bot detection) } = {}, ) { const { @@ -382,11 +371,9 @@ export default async function fetchEbayItems( keywords = [SEARCH_QUERY], // Default to search query if no keywords provided buyItNowOnly = true, canadaOnly = true, - cookies: cookiesSource, } = opts; - // Load eBay cookies with priority: URL param > ENV var > file - const cookies = await loadEbayCookies(cookiesSource); + const cookies = await loadEbayCookies(); // Build eBay search URL - use Canadian site, Buy It Now filter, and Canada-only preference const urlParams = new URLSearchParams({ diff --git a/packages/core/test/ebay-core.test.ts b/packages/core/test/ebay-core.test.ts new file mode 100644 index 0000000..64c8e6f --- /dev/null +++ b/packages/core/test/ebay-core.test.ts @@ -0,0 +1,41 @@ +import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test"; +import fetchEbayItems from "../src/scrapers/ebay"; + +const originalFetch = global.fetch; +const originalWarn = console.warn; + +describe("eBay Scraper Cookie Handling", () => { + beforeEach(() => { + global.fetch = mock(() => + Promise.resolve({ + ok: true, + text: () => Promise.resolve(""), + }), + ) as typeof fetch; + }); + + afterEach(() => { + global.fetch = originalFetch; + console.warn = originalWarn; + delete process.env.EBAY_COOKIE; + }); + + test("should ignore request cookie overrides and rely on EBAY_COOKIE", async () => { + const warnMock = mock(() => {}); + console.warn = warnMock; + + await fetchEbayItems("laptop", 1000, { + cookies: "s=from-request", + }); + + expect(global.fetch).toHaveBeenCalledTimes(1); + + const [, init] = (global.fetch as ReturnType).mock.calls[0]; + const headers = (init as RequestInit).headers as Record; + + expect(headers.Cookie).toBeUndefined(); + expect(warnMock).toHaveBeenCalledWith( + "No valid eBay cookies found in EBAY_COOKIE. eBay may block requests without a raw Cookie header string.", + ); + }); +});