From d90e6c6dd8d7957497154bc0fa10c237455b1a2d Mon Sep 17 00:00:00 2001 From: rajch_ales Date: Wed, 5 Aug 2026 21:15:19 +0200 Subject: [PATCH] Use configured browser for source windows --- agent.md | 1 + src/services/catalog-products.ts | 14 +++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/agent.md b/agent.md index 6500822..d08f101 100644 --- a/agent.md +++ b/agent.md @@ -70,6 +70,7 @@ This project replaces the Excel/VBA workflow named `Catalog maker - 20` with a N - Do not implement new scraping with raw `fetch`, regex-only HTML parsing, Selenium or direct HTTP shortcuts. - Scrapers must use controlled browser navigation, selectors, explicit waits and bounded request counts. - The configured browser engine for a source is authoritative. If a source says `firefox`, launch Firefox or fail loudly; do not silently fall back to Chromium, Edge or another browser. +- Visible source windows, URL health checks, source lookup and picture parsing must all use the same configured browser engine from that source's database setting. - Keep scraping slow and observable, preserve source URL/status information, and handle blocked pages or missing selectors as explicit errors. - Supplier data remains a local draft until the user explicitly confirms an Apply / Save action. diff --git a/src/services/catalog-products.ts b/src/services/catalog-products.ts index 0eea291..1584db8 100644 --- a/src/services/catalog-products.ts +++ b/src/services/catalog-products.ts @@ -185,7 +185,7 @@ export async function findProductSources( const candidate = item.candidates?.[0]; if (candidate?.url) { try { - await openInBrowser(candidate.url); + await openInBrowser(candidate.url, { engine: item.source.browserEngine }); } catch { // Picture extraction can continue even if the visible browser cannot start. } @@ -332,7 +332,7 @@ async function findSourceCandidates(source, product, { includePictures = false } if (candidates.length) { let verification = null; if (includePictures && source.key === "hudy" && product.color && candidates[0].url) { - verification = await verifyHudyVariant(candidates[0].url, product); + verification = await verifyHudyVariant(candidates[0].url, product, source.browserEngine); candidates[0].verification = verification; if (verification.matchedUrl) candidates[0].url = verification.matchedUrl; if (includePictures && verification.pictures?.length) { @@ -343,7 +343,7 @@ async function findSourceCandidates(source, product, { includePictures = false } if (includePictures) { for (const candidate of candidates) { if (source.key === "hudy" && candidate.url) { - candidate.pictures = await extractPicturesFromPage(candidate.url); + candidate.pictures = await extractPicturesFromPage(candidate.url, source.browserEngine); } else { candidate.pictures = extractPictureUrls(html, response.url || attempt.url); } @@ -585,7 +585,7 @@ function findColorVariantUrl(html, pageUrl, color) { return ""; } -async function verifyHudyVariant(url, product) { +async function verifyHudyVariant(url, product, browserEngine = "chromium") { try { const eanGroup = Array.isArray(product.eanGroup) ? product.eanGroup @@ -603,7 +603,7 @@ async function verifyHudyVariant(url, product) { if (visited.has(page.url)) continue; visited.add(page.url); - const response = await scrapePage(page.url, { waitAfterLoadMs: 750 }); + const response = await scrapePage(page.url, { engine: browserEngine, waitAfterLoadMs: 750 }); const html = response.pageSource; lastStatus = response.status; const pageEans = extractPageEans(html); @@ -705,9 +705,9 @@ function extractPictureUrls(html, pageUrl) { return urls.slice(0, 12); } -async function extractPicturesFromPage(url) { +async function extractPicturesFromPage(url, browserEngine = "chromium") { try { - const response = await scrapePage(url, { waitAfterLoadMs: 750 }); + const response = await scrapePage(url, { engine: browserEngine, waitAfterLoadMs: 750 }); return extractHudyGalleryPictureUrls(response.pageSource, response.url || url); } catch { return [];