from __future__ import annotations from typing import TYPE_CHECKING import pytest from crawlee.fingerprint_suite import HeaderGenerator from crawlee.fingerprint_suite._browserforge_adapter import get_available_header_values from crawlee.fingerprint_suite._consts import ( BROWSER_TYPE_HEADER_KEYWORD, ) if TYPE_CHECKING: from crawlee.fingerprint_suite._types import SupportedBrowserType def test_get_common_headers(header_network: dict) -> None: header_generator = HeaderGenerator() headers = header_generator.get_common_headers() assert 'Accept' in headers assert headers['Accept'] in get_available_header_values(header_network, {'Accept', 'accept'}) assert 'Accept-Language' in headers def test_get_random_user_agent_header() -> None: """Test that a random User-Agent header is generated.""" header_generator = HeaderGenerator() headers = header_generator.get_random_user_agent_header() assert 'User-Agent' in headers assert headers['User-Agent'] @pytest.mark.parametrize('browser_type', ['chrome', 'firefox', 'edge', 'safari']) def test_get_user_agent_header_stress_test(browser_type: SupportedBrowserType, header_network: dict) -> None: """Test that the User-Agent header is consistently generated correctly. (Very fast even when stress tested.)""" for _ in range(100): header_generator = HeaderGenerator() headers = header_generator.get_user_agent_header(browser_type=browser_type) assert 'User-Agent' in headers assert any(keyword in headers['User-Agent'] for keyword in BROWSER_TYPE_HEADER_KEYWORD[browser_type]) assert headers['User-Agent'] in get_available_header_values(header_network, {'user-agent', 'User-Agent'}) def test_get_user_agent_header_invalid_browser_type() -> None: """Test that an invalid browser type raises a ValueError.""" header_generator = HeaderGenerator() with pytest.raises(ValueError, match=r'Unsupported browser type'): header_generator.get_user_agent_header(browser_type='invalid_browser') # ty: ignore[invalid-argument-type] def test_get_sec_ch_ua_headers_chromium(header_network: dict) -> None: """Test that Sec-Ch-Ua headers are generated correctly for Chrome.""" header_generator = HeaderGenerator() headers = header_generator.get_sec_ch_ua_headers(browser_type='chrome') assert headers.get('sec-ch-ua') in get_available_header_values(header_network, 'sec-ch-ua') assert headers.get('sec-ch-ua-mobile') in get_available_header_values(header_network, 'sec-ch-ua-mobile') assert headers.get('sec-ch-ua-platform') in get_available_header_values(header_network, 'sec-ch-ua-platform') def test_get_sec_ch_ua_headers_firefox() -> None: """Test that sec-ch-ua headers are not generated for Firefox.""" header_generator = HeaderGenerator() headers = header_generator.get_sec_ch_ua_headers(browser_type='firefox') assert not headers def test_get_sec_ch_ua_headers_invalid_browser_type() -> None: """Test that an invalid browser type raises a ValueError for sec-ch-ua headers.""" header_generator = HeaderGenerator() with pytest.raises(ValueError, match=r'Unsupported browser type'): header_generator.get_sec_ch_ua_headers(browser_type='invalid_browser') # ty: ignore[invalid-argument-type]