-
Notifications
You must be signed in to change notification settings - Fork 18
Add unit tests for properties
#18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
from ._stealth_config import StealthConfig | ||
|
||
__ALL__ = ["StealthConfig"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
from ._properties import Properties | ||
|
||
__ALL__ = ["Properties"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
import pytest | ||
from fake_http_header import FakeHttpHeader | ||
from playwright_stealth.properties._header_properties import HeaderProperties | ||
|
||
|
||
@pytest.fixture | ||
def fake_headers(): | ||
"""Fixture to generate fake headers with an additional 'origin' key if missing.""" | ||
return FakeHttpHeader(domain_code="com", browser="chrome").as_header_dict() | ||
|
||
|
||
@pytest.fixture | ||
def brands(): | ||
"""Fixture for sample brand data.""" | ||
return [{"brand": "BrandA", "version": "1"}, {"brand": "BrandB", "version": "2"}] | ||
|
||
|
||
@pytest.fixture | ||
def header_properties(fake_headers, brands): | ||
"""Fixture to initialize HeaderProperties with fake headers and brands.""" | ||
return HeaderProperties(brands=brands, dnt="1", **fake_headers) | ||
|
||
|
||
def test_initialization(header_properties, fake_headers, brands): | ||
"""Test that HeaderProperties initializes with correct attributes and values.""" | ||
assert header_properties.user_agent == fake_headers["User-Agent"] | ||
assert header_properties.accept_language == fake_headers["Accept-language"] | ||
assert header_properties.accept_encoding == fake_headers["Accept-encoding"] | ||
assert header_properties.accept == fake_headers["Accept"] | ||
assert header_properties.referer == fake_headers["Referer"] | ||
assert header_properties.dnt == "1" | ||
assert header_properties.sec_ch_ua == header_properties._generate_sec_ch_ua(brands) | ||
assert ( | ||
header_properties.sec_ch_ua_mobile | ||
== header_properties._generate_sec_ch_ua_mobile() | ||
) | ||
assert ( | ||
header_properties.sec_ch_ua_platform | ||
== header_properties._generate_sec_ch_ua_platform() | ||
) | ||
assert ( | ||
header_properties.sec_ch_ua_form_factors | ||
== header_properties._generate_sec_ch_ua_form_factors() | ||
) | ||
|
||
|
||
def test_generate_sec_ch_ua_platform(header_properties): | ||
"""Test _generate_sec_ch_ua_platform with various user agents.""" | ||
test_cases = [ | ||
("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)", "macOS"), | ||
("Mozilla/5.0 (Windows NT 10.0; Win64; x64)", "Windows"), | ||
("Mozilla/5.0 (X11; Linux x86_64)", "Linux"), | ||
("Mozilla/5.0 (Unknown OS)", "Unknown"), | ||
] | ||
for user_agent, expected_platform in test_cases: | ||
header_properties.user_agent = user_agent | ||
assert header_properties._generate_sec_ch_ua_platform() == expected_platform | ||
|
||
|
||
def test_generate_sec_ch_ua(header_properties, brands): | ||
"""Test _generate_sec_ch_ua generates correct string format.""" | ||
ua_string = header_properties._generate_sec_ch_ua(brands) | ||
expected_string = '"BrandA";v="1","BrandB";v="2",' | ||
assert ua_string == expected_string | ||
|
||
|
||
def test_generate_sec_ch_ua_mobile(header_properties): | ||
"""Test _generate_sec_ch_ua_mobile returns expected value.""" | ||
assert header_properties._generate_sec_ch_ua_mobile() == "?0" | ||
|
||
|
||
def test_generate_sec_ch_ua_form_factors(header_properties): | ||
"""Test _generate_sec_ch_ua_form_factors returns expected value.""" | ||
assert header_properties._generate_sec_ch_ua_form_factors() == "desktop" | ||
|
||
|
||
def test_as_dict(header_properties): | ||
"""Test as_dict converts headers to kebab-case correctly and includes all keys.""" | ||
headers_dict = header_properties.as_dict() | ||
expected_keys = { | ||
"user-agent", | ||
"accept-language", | ||
"accept-encoding", | ||
"accept", | ||
"referer", | ||
"dnt", | ||
"sec-ch-ua", | ||
"sec-ch-ua-mobile", | ||
"sec-ch-ua-platform", | ||
"sec-ch-ua-form-factors", | ||
} | ||
assert set(headers_dict.keys()) == expected_keys | ||
assert headers_dict["user-agent"] == header_properties.user_agent | ||
assert headers_dict["accept-language"] == header_properties.accept_language | ||
assert headers_dict["accept-encoding"] == header_properties.accept_encoding | ||
assert headers_dict["accept"] == header_properties.accept | ||
assert headers_dict["referer"] == header_properties.referer | ||
assert headers_dict["dnt"] == header_properties.dnt | ||
assert headers_dict["sec-ch-ua"] == header_properties.sec_ch_ua | ||
assert headers_dict["sec-ch-ua-mobile"] == header_properties.sec_ch_ua_mobile | ||
assert headers_dict["sec-ch-ua-platform"] == header_properties.sec_ch_ua_platform | ||
assert ( | ||
headers_dict["sec-ch-ua-form-factors"] | ||
== header_properties.sec_ch_ua_form_factors | ||
) | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"user_agent,expected_platform", | ||
[ | ||
("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)", "macOS"), | ||
("Mozilla/5.0 (Windows NT 10.0; Win64; x64)", "Windows"), | ||
("Mozilla/5.0 (X11; Linux x86_64)", "Linux"), | ||
("Mozilla/5.0 (Unknown OS)", "Unknown"), | ||
], | ||
) | ||
def test_generate_sec_ch_ua_platform_parametrized(user_agent, expected_platform): | ||
"""Parametrized test for _generate_sec_ch_ua_platform.""" | ||
header_properties = HeaderProperties( | ||
brands=[], | ||
dnt="1", | ||
**{ | ||
"User-Agent": user_agent, | ||
"Accept-language": "", | ||
"Accept-encoding": "", | ||
"Accept": "", | ||
"Referer": "", | ||
} | ||
) | ||
assert header_properties._generate_sec_ch_ua_platform() == expected_platform | ||
|
||
|
||
def test_missing_headers(): | ||
"""Test that HeaderProperties raises an error when required headers are missing.""" | ||
with pytest.raises(KeyError): | ||
HeaderProperties(brands=[], dnt="1") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import pytest | ||
from fake_http_header import FakeHttpHeader | ||
from playwright_stealth.properties._navigator_properties import NavigatorProperties | ||
|
||
|
||
@pytest.fixture | ||
def fake_headers(): | ||
"""Fixture to generate fake headers using FakeHttpHeader.""" | ||
return FakeHttpHeader(domain_code="com", browser="chrome").as_header_dict() | ||
|
||
|
||
@pytest.fixture | ||
def brands(): | ||
"""Fixture for sample brand data.""" | ||
return [ | ||
{"brand": "Chromium", "version": "95"}, | ||
{"brand": "Google Chrome", "version": "95"}, | ||
] | ||
|
||
|
||
@pytest.fixture | ||
def navigator_properties(fake_headers, brands): | ||
"""Fixture to initialize NavigatorProperties with fake headers and brands.""" | ||
return NavigatorProperties(brands=brands, dnt="1", **fake_headers) | ||
|
||
|
||
def test_initialization(navigator_properties, fake_headers, brands): | ||
"""Test that NavigatorProperties initializes with correct attributes.""" | ||
assert navigator_properties.userAgent == fake_headers["User-Agent"] | ||
assert navigator_properties.platform in ["Macintosh", "Windows", "Linux"] | ||
assert navigator_properties.language == "en-US" | ||
assert isinstance(navigator_properties.languages, list) | ||
assert ( | ||
navigator_properties.appVersion | ||
== navigator_properties._generate_app_version(fake_headers["User-Agent"]) | ||
) | ||
assert navigator_properties.vendor in ["Google Inc.", ""] | ||
assert navigator_properties.deviceMemory == 8 | ||
assert navigator_properties.hardwareConcurrency == 8 | ||
assert navigator_properties.maxTouchPoints == 0 | ||
assert navigator_properties.doNotTrack == "1" | ||
assert navigator_properties.brands == brands | ||
assert navigator_properties.mobile is False | ||
|
||
|
||
def test_generate_platform(navigator_properties): | ||
"""Test the _generate_platform method with various user agents.""" | ||
ua_mac = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)" | ||
ua_windows = "Mozilla/5.0 (Windows NT 10.0; Win64; x64)" | ||
ua_linux = "Mozilla/5.0 (X11; Linux x86_64)" | ||
assert navigator_properties._generate_platform(ua_mac) == "Macintosh" | ||
assert navigator_properties._generate_platform(ua_windows) == "Windows" | ||
assert navigator_properties._generate_platform(ua_linux) == "Linux" | ||
|
||
|
||
def test_generate_languages(navigator_properties): | ||
"""Test the _generate_languages method.""" | ||
accept_language = "en-US,en;q=0.9,fr;q=0.8" | ||
expected_languages = ["en-US", "en", "fr"] | ||
assert ( | ||
navigator_properties._generate_languages(accept_language) == expected_languages | ||
) | ||
|
||
|
||
def test_generate_app_version(navigator_properties): | ||
"""Test the _generate_app_version method.""" | ||
user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64)" | ||
expected_version = "5.0 (Windows NT 10.0; Win64; x64)" | ||
assert navigator_properties._generate_app_version(user_agent) == expected_version | ||
|
||
|
||
def test_generate_vendor(navigator_properties): | ||
"""Test the _generate_vendor method.""" | ||
ua_chrome = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/85.0.4183.102" | ||
ua_firefox = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Firefox/80.0" | ||
ua_safari = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Safari/605.1.15" | ||
assert navigator_properties._generate_vendor(ua_chrome) == "Google Inc." | ||
assert navigator_properties._generate_vendor(ua_firefox) == "" | ||
assert navigator_properties._generate_vendor(ua_safari) == "Google Inc." | ||
|
||
|
||
def test_as_dict(navigator_properties): | ||
"""Test that as_dict converts the navigator properties to a dictionary correctly.""" | ||
navigator_dict = navigator_properties.as_dict() | ||
assert navigator_dict["userAgent"] == navigator_properties.userAgent | ||
assert navigator_dict["platform"] == navigator_properties.platform | ||
assert navigator_dict["language"] == navigator_properties.language | ||
assert navigator_dict["languages"] == navigator_properties.languages | ||
assert navigator_dict["appVersion"] == navigator_properties.appVersion | ||
assert navigator_dict["vendor"] == navigator_properties.vendor | ||
assert navigator_dict["deviceMemory"] == navigator_properties.deviceMemory | ||
assert ( | ||
navigator_dict["hardwareConcurrency"] | ||
== navigator_properties.hardwareConcurrency | ||
) | ||
assert navigator_dict["maxTouchPoints"] == navigator_properties.maxTouchPoints | ||
assert navigator_dict["doNotTrack"] == navigator_properties.doNotTrack | ||
assert navigator_dict["brands"] == navigator_properties.brands | ||
assert navigator_dict["mobile"] == navigator_properties.mobile |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This approach allowed for potential mismatches of a vendor and renderer. (i.e AMD as the vendor and a NVIDIA GTX 1660 as the rendered)
Consolidated the logic into one random.choice() call to prevent this.
LMK if this was by design