diff --git a/examples/screenshot/screenshot_with_screenshot_api.py b/examples/screenshot/screenshot_with_screenshot_api.py index bd4bb21..723d137 100644 --- a/examples/screenshot/screenshot_with_screenshot_api.py +++ b/examples/screenshot/screenshot_with_screenshot_api.py @@ -17,6 +17,7 @@ rendering_wait=5000, # Delay in milliseconds to wait after the page was loaded wait_for_selector='div.products-wrap', # XPath or CSS selector to wait for auto_scroll=True, # Whether to automatically scroll down to the bottom of the page + # vision_deficiency=VisionDeficiency.DEUTERANOPIA, # Simulate vision deficiency ) ) diff --git a/scrapfly/api_response.py b/scrapfly/api_response.py index 0038a53..77a9228 100644 --- a/scrapfly/api_response.py +++ b/scrapfly/api_response.py @@ -226,14 +226,22 @@ def error_message(self): message = "<-- %s | %s - %s." % (self.response.status_code, self.error['code'], self.error['message']) if self.error['links']: - message += " Checkout the related doc: %s" % list(self.error['links'].values())[0] + links = self.error['links'] + if isinstance(links, dict): + message += " Checkout the related doc: %s" % list(links.values())[0] + elif isinstance(links, list): + message += " Checkout the related doc: %s" % ", ".join(links) return message message = "<-- %s | %s." % (self.response.status_code, self.result['message']) if self.result.get('links'): - message += " Checkout the related doc: %s" % ", ".join(self.result['links']) + links = self.result['links'] + if isinstance(links, dict): + message += " Checkout the related doc: %s" % list(links.values())[0] + elif isinstance(links, list): + message += " Checkout the related doc: %s" % ", ".join(links) return message diff --git a/scrapfly/screenshot_config.py b/scrapfly/screenshot_config.py index c542b8f..4623521 100644 --- a/scrapfly/screenshot_config.py +++ b/scrapfly/screenshot_config.py @@ -38,6 +38,24 @@ class Format(Enum): GIF = "gif" +class VisionDeficiency(Enum): + """ + Simulate vision deficiency for accessibility testing (WCAG compliance) + + Attributes: + DEUTERANOPIA: Red-green color blindness (green-blind), affects ~6% of males. + PROTANOPIA: Red-green color blindness (red-blind), affects ~2% of males + TRITANOPIA: Simulate color blindness. + ACHROMATOPSIA: Complete color blindness (monochromacy), affects ~0.003% + BLURREDVISION: Blurred/unfocused vision, affects ~2.2B globally + """ + DEUTERANOPIA = "deuteranopia" + PROTANOPIA = "protanopia" + TRITANOPIA = "tritanopia" + ACHROMATOPSIA = "achromatopsia" + BLURREDVISION = "blurredvision" + + class ScreenshotConfig(BaseApiConfig): url: str format: Optional[Format] = None @@ -72,6 +90,7 @@ def __init__( cache: Optional[bool] = None, cache_ttl: Optional[bool] = None, cache_clear: Optional[bool] = None, + vision_deficiency: Optional[VisionDeficiency] = None, webhook: Optional[str] = None, raise_on_upstream_error: bool = True ): @@ -92,6 +111,7 @@ def __init__( self.cache = cache self.cache_ttl = cache_ttl self.cache_clear = cache_clear + self.vision_deficiency = vision_deficiency self.webhook = webhook self.raise_on_upstream_error = raise_on_upstream_error @@ -147,6 +167,9 @@ def to_api_params(self, key:str) -> Dict: if self.cache_clear is not None: logging.warning('Params "cache_clear" is ignored. Works only if cache is enabled') + if self.vision_deficiency is not None: + params['vision_deficiency'] = self.vision_deficiency.value + if self.webhook is not None: params['webhook_name'] = self.webhook @@ -171,6 +194,7 @@ def to_dict(self) -> Dict: 'cache': self.cache, 'cache_ttl': self.cache_ttl, 'cache_clear': self.cache_clear, + 'vision_deficiency': self.vision_deficiency.value if self.vision_deficiency else None, 'webhook': self.webhook, 'raise_on_upstream_error': self.raise_on_upstream_error } @@ -198,6 +222,7 @@ def from_dict(screenshot_config_dict: Dict) -> 'ScreenshotConfig': cache = screenshot_config_dict.get('cache', None) cache_ttl = screenshot_config_dict.get('cache_ttl', None) cache_clear = screenshot_config_dict.get('cache_clear', None) + vision_deficiency = screenshot_config_dict.get('vision_deficiency', None) webhook = screenshot_config_dict.get('webhook', None) raise_on_upstream_error = screenshot_config_dict.get('raise_on_upstream_error', True) @@ -216,6 +241,7 @@ def from_dict(screenshot_config_dict: Dict) -> 'ScreenshotConfig': cache=cache, cache_ttl=cache_ttl, cache_clear=cache_clear, + vision_deficiency=vision_deficiency, webhook=webhook, raise_on_upstream_error=raise_on_upstream_error )