mirror of
https://github.com/R0m1k3/Priceflow.git
synced 2026-10-15 11:17:06 +02:00
Merge pull request #228 from R0m1k3/antigravity
chore: Update task plan to focus on removing obscuring popups from pr…
This commit is contained in:
3 files changed
+103
-36
No files matched your search
@@ -60,6 +60,20 @@ POPUP_SELECTORS = [
|
||||
"span.a-button-inner > input.a-button-input[type='submit']",
|
||||
"form:has-text('Continuer les achats') input[type='submit']",
|
||||
"[aria-labelledby='continue-shopping-label']",
|
||||
|
||||
# Generic & specific additions
|
||||
"[aria-modal='true'] button",
|
||||
"[class*='cookie'] button",
|
||||
"[id*='cookie'] button",
|
||||
"button:has-text('Non merci')",
|
||||
"button:has-text('Continuer sans accepter')",
|
||||
"button:has-text('Fermer')",
|
||||
".popin-close",
|
||||
".js-modal-close",
|
||||
|
||||
# Specific targeted fix for "Stock Inconnu" / "Calendrier" type overlays if they use standard classes
|
||||
"[id*='advent'] button",
|
||||
"[class*='advent'] button",
|
||||
]
|
||||
|
||||
|
||||
@@ -226,42 +240,56 @@ class BrowserlessService:
|
||||
|
||||
@staticmethod
|
||||
async def _handle_popups(page: Page):
|
||||
"""Attempt to close popups and cookie banners with retry logic."""
|
||||
logger.debug("Attempting to close popups...")
|
||||
|
||||
# First pass: Try to close all visible popups
|
||||
closed_popups = []
|
||||
for popup_selector in POPUP_SELECTORS:
|
||||
"""Attempt to close popups and cookie banners with refined retry logic."""
|
||||
logger.debug("🛡️ Attempting to close popups...")
|
||||
|
||||
async def try_close(selector: str):
|
||||
try:
|
||||
if await page.locator(popup_selector).count() > 0:
|
||||
logger.info(f"🚫 Closing popup: {popup_selector}")
|
||||
await page.locator(popup_selector).first.click(timeout=2000)
|
||||
closed_popups.append(popup_selector)
|
||||
await page.wait_for_timeout(1000)
|
||||
# Check for multiple elements
|
||||
locator = page.locator(selector)
|
||||
count = await locator.count()
|
||||
if count > 0:
|
||||
# Click the first visible and enabled one
|
||||
for i in range(count):
|
||||
el = locator.nth(i)
|
||||
if await el.is_visible() and await el.is_enabled():
|
||||
logger.info(f"🚫 Closing popup via selector: {selector}")
|
||||
await el.click(timeout=1000)
|
||||
return True
|
||||
except Exception:
|
||||
pass
|
||||
return False
|
||||
|
||||
# Try Escape key multiple times
|
||||
for _ in range(2):
|
||||
# Multiple passes to catch delayed popups (animations, etc.)
|
||||
for pass_idx in range(3):
|
||||
closed_something = False
|
||||
|
||||
# 1. Standard Selectors
|
||||
for selector in POPUP_SELECTORS:
|
||||
if await try_close(selector):
|
||||
closed_something = True
|
||||
await page.wait_for_timeout(500) # Wait for animation
|
||||
|
||||
# 2. Key presses (Escape)
|
||||
try:
|
||||
await page.keyboard.press("Escape")
|
||||
await page.wait_for_timeout(500)
|
||||
await page.wait_for_timeout(300)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Second pass: Verify and retry if any popups are still visible
|
||||
if closed_popups:
|
||||
logger.info(f"Verifying {len(closed_popups)} closed popup(s)...")
|
||||
await page.wait_for_timeout(1000)
|
||||
|
||||
for popup_selector in closed_popups:
|
||||
try:
|
||||
if await page.locator(popup_selector).count() > 0:
|
||||
logger.warning(f"Popup reappeared, retrying: {popup_selector}")
|
||||
await page.locator(popup_selector).first.click(timeout=2000)
|
||||
await page.wait_for_timeout(1000)
|
||||
except Exception:
|
||||
pass
|
||||
# If we didn't find anything in this pass and it's not the first, break early
|
||||
if not closed_something and pass_idx > 0:
|
||||
break
|
||||
|
||||
await page.wait_for_timeout(1000) # Wait between passes
|
||||
|
||||
# Final check: Force click typical overlay backdrops (risky but effective)
|
||||
try:
|
||||
# Click coordinates (top-right or top-left corner often safish to close modals)
|
||||
# await page.mouse.click(10, 10)
|
||||
pass
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
async def _extract_amazon_price(page: Page) -> str:
|
||||
|
||||
@@ -1,17 +1,23 @@
|
||||
# Task: Fix Screenshot Update in Tracking
|
||||
# Task: Remove Obscuring Windows from Product Screenshots
|
||||
|
||||
## Context
|
||||
The user reports that forcing an update in the "Suivi" (Tracking) section does not update the screenshot as expected.
|
||||
|
||||
The user has reported that screenshots in the "suivi produits" (product tracking) section still contain windows (popups, overlays) that obscure the content. A specific example provided shows a "Stock Inconnu" and "Calendrier de l'Avent" popup on a B&M website.
|
||||
|
||||
## Current Focus
|
||||
Investigating the "force update" mechanism and why the screenshot is not refreshing.
|
||||
|
||||
Investigating the scraping and screenshot logic to handle these popups.
|
||||
|
||||
## Master Plan
|
||||
- [x] Investigate the "force update" API endpoint and backend logic.
|
||||
- [x] Check how screenshots are captured and saved in `tracking_scraper_service.py` or similar.
|
||||
- [x] Verify if the frontend is correctly requesting the update and displaying the new image.
|
||||
- [x] Fix the issue preventing the screenshot from updating.
|
||||
- [x] Verify the fix (Code review confirms relative paths are now consistent across the app).
|
||||
|
||||
- [x] Explore codebase to locate scraping and screenshot logic <!-- id: 0 -->
|
||||
- [x] Identify specific handling for B&M or generic popup closing <!-- id: 1 -->
|
||||
- [x] Implement fix to close popups before screenshot <!-- id: 2 -->
|
||||
- [/] Verify fix (Requires App Rebuild) <!-- id: 3 -->
|
||||
|
||||
## Progress Log
|
||||
- Created `task.md`.
|
||||
|
||||
- Initialized task.md
|
||||
- Created implementation plan to expand popup selectors.
|
||||
- Updated `browserless_service.py` with expanded selectors and retry logic.
|
||||
- Attempted local verification but failed due to environment restrictions.
|
||||
@@ -0,0 +1,33 @@
|
||||
import asyncio
|
||||
import logging
|
||||
import sys
|
||||
from app.services.browserless_service import browserless_service
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
async def verify_popups():
|
||||
# URL that was reported to have issues
|
||||
url = "https://www.bmstores.fr/363943-bougie-parfumee-avec-bijou-350g-senteurs-assorties"
|
||||
# Fallback to search if that product is gone
|
||||
fallback_url = "https://www.bmstores.fr/module/ambjolisearch/jolisearch?s=calendrier"
|
||||
|
||||
logger.info(f"--- Testing Popup Handling on {url} ---")
|
||||
|
||||
try:
|
||||
content, screenshot_path = await browserless_service.get_page_content(
|
||||
url,
|
||||
extract_text=False
|
||||
)
|
||||
|
||||
logger.info(f"Screenshot saved to: {screenshot_path}")
|
||||
logger.info("Please inspect the screenshot to ensure no 'Stock Inconnu' or 'Calendrier' popups are visible.")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Verification failed: {e}")
|
||||
finally:
|
||||
await browserless_service.shutdown()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(verify_popups())
|
||||
Reference in new issue
Block a user