@@ -445,6 +445,29 @@ def _is_captcha_detected(self, snapshot: Snapshot) -> bool:
445445 captcha = getattr (snapshot .diagnostics , "captcha" , None ) if snapshot .diagnostics else None
446446 if not captcha or not getattr (captcha , "detected" , False ):
447447 return False
448+ # IMPORTANT: Many sites load CAPTCHA libraries proactively. We only want to
449+ # block execution when there's evidence it's actually *present/active*.
450+ # If we block on low-signal detections (e.g. just a recaptcha script tag),
451+ # interactive runs will “do nothing” and time out.
452+ evidence = getattr (captcha , "evidence" , None )
453+ if evidence is not None :
454+ def _list (name : str ) -> list [str ]:
455+ try :
456+ v = getattr (evidence , name , None )
457+ except Exception :
458+ v = None
459+ if v is None and isinstance (evidence , dict ):
460+ v = evidence .get (name )
461+ if not v :
462+ return []
463+ return [str (x ) for x in v if x is not None ]
464+
465+ iframe_hits = _list ("iframe_src_hits" )
466+ url_hits = _list ("url_hits" )
467+ text_hits = _list ("text_hits" )
468+ # If we only saw selector/script hints, treat as non-blocking.
469+ if not iframe_hits and not url_hits and not text_hits :
470+ return False
448471 confidence = getattr (captcha , "confidence" , 0.0 )
449472 return confidence >= self ._captcha_options .min_confidence
450473
0 commit comments