feat(consent-tester): browser_profile-Param — echte Engine-Wahl im Scan (Phase 1.1)

run_consent_test nimmt jetzt browser_profile (browser_profiles.py): Firefox/Gecko,
WebKit/Safari oder Blink (Chromium-Default / Chrome-/Edge-Channel / Brave via
executable_path). Rückwärtskompatibel: None → Chromium wie bisher. Fundament für
die echte /scan-matrix (Stage-1.b-Shim), die als nächstes Profile durchreicht.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-06-12 22:21:20 +02:00
parent 11740bd2f9
commit c816827720
+34 -17
View File
@@ -117,6 +117,7 @@ def _apply_edge_case_findings(result, url: str = "") -> None:
async def run_consent_test( async def run_consent_test(
url: str, wait_secs: int = 10, categories: list[str] | None = None, url: str, wait_secs: int = 10, categories: list[str] | None = None,
browser_profile: dict | None = None,
) -> ConsentTestResult: ) -> ConsentTestResult:
"""Run 3-phase consent test on a URL. """Run 3-phase consent test on a URL.
@@ -124,6 +125,9 @@ async def run_consent_test(
url: Website URL to test. url: Website URL to test.
wait_secs: Seconds to wait per phase. wait_secs: Seconds to wait per phase.
categories: Optional list of category names to test (empty = test all). categories: Optional list of category names to test (empty = test all).
browser_profile: Optional profile dict from browser_profiles.py — waehlt
die Engine (blink/gecko/webkit) + channel (chrome/msedge) bzw.
executable_path (Brave). None = Chromium-Default (wie bisher).
""" """
result = ConsentTestResult() result = ConsentTestResult()
wait_ms = wait_secs * 1000 wait_ms = wait_secs * 1000
@@ -136,24 +140,37 @@ async def run_consent_test(
from services.cmp_extractor import CMPCapture from services.cmp_extractor import CMPCapture
cmp_capture = CMPCapture() cmp_capture = CMPCapture()
_prof = browser_profile or {}
_engine = _prof.get("engine", "blink")
_chromium_args = [
"--no-sandbox",
"--disable-dev-shm-usage",
"--disable-blink-features=AutomationControlled",
"--window-size=1920,1080",
# P50c: Mercedes/Akamai Bot Manager crashed renderer
# without these (limits memory pressure + GPU init):
"--disable-gpu",
"--disable-software-rasterizer",
"--disable-background-timer-throttling",
"--disable-renderer-backgrounding",
"--disable-backgrounding-occluded-windows",
"--js-flags=--max-old-space-size=2048",
]
async with async_playwright() as p: async with async_playwright() as p:
browser = await p.chromium.launch( # Engine-Wahl je Profil: Firefox/Gecko, WebKit/Safari oder Blink
headless=True, # (Chromium-Default / Chrome-/Edge-Channel / Brave via executable_path).
args=[ if _engine == "gecko":
"--no-sandbox", browser = await p.firefox.launch(headless=True)
"--disable-dev-shm-usage", elif _engine == "webkit":
"--disable-blink-features=AutomationControlled", browser = await p.webkit.launch(headless=True)
"--window-size=1920,1080", else:
# P50c: Mercedes/Akamai Bot Manager crashed renderer _launch: dict = {"headless": True, "args": _chromium_args}
# without these (limits memory pressure + GPU init): if _prof.get("channel"):
"--disable-gpu", _launch["channel"] = _prof["channel"]
"--disable-software-rasterizer", if _prof.get("executable_path"):
"--disable-background-timer-throttling", _launch["executable_path"] = _prof["executable_path"]
"--disable-renderer-backgrounding", browser = await p.chromium.launch(**_launch)
"--disable-backgrounding-occluded-windows",
"--js-flags=--max-old-space-size=2048",
],
)
try: try:
# ── Phase A: Before consent ────────────────────────── # ── Phase A: Before consent ──────────────────────────