-
-
Notifications
You must be signed in to change notification settings - Fork 8.6k
[py][bidi] Allow resetting viewport #16623
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
base: trunk
Are you sure you want to change the base?
Conversation
PR Compliance Guide 🔍Below is a summary of compliance checks for this PR:
Compliance status legend🟢 - Fully Compliant🟡 - Partial Compliant 🔴 - Not Compliant ⚪ - Requires Further Human Verification 🏷️ - Compliance label |
|||||||||||||||||||||||||
PR Code Suggestions ✨Latest suggestions up to ce185c6
Previous suggestions✅ Suggestions up to commit b91113a
|
|||||||||||||||||||||||||
|
I haven't tested this yet, so we'll see if browsers actually support it in CI. This issue was discussed at length in Slack today, and there might be other BiDi functionality that needs to follow this same pattern when This is kind of awkward in Python, but defaulting to a sentinel is the best approach I could think of. |
navin772
left a comment
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.
Should we also test a flow where we don't pass the viewport param (the undefined case)?
It could be:
set_viewport with {width, height} -> assert viewport -> set_viewport with no viewport param(undefined) -> assert still same height, width -> set_viewport as None -> assert resets to default
We could add it to a previous test.
|
@cgoldberg I think using def set_viewport(
self,
context: str | None = None,
viewport: dict | None | type(Ellipsis) = ...,
device_pixel_ratio: float | None | type(Ellipsis) = ...,
user_contexts: list[str] | None = None,
) -> None:
if context is not None and user_contexts is not None:
raise ValueError("Cannot specify both context and user_contexts")
if context is None and user_contexts is None:
raise ValueError("Must specify either context or user_contexts")
params: dict[str, Any] = {}
if context is not None:
params["context"] = context
else:
params["userContexts"] = user_contexts
if viewport is not ...:
params["viewport"] = viewport # handles all 3 cases
if device_pixel_ratio is not ...:
params["devicePixelRatio"] = device_pixel_ratio
self.conn.execute(command_builder("browsingContext.setViewport", params))WDYT about this approach? |
That's interesting. Your code made me realize I can remove the if-else checks to simplify it even if I use the sentinel. I just updated the code. I guess it just comes down to whether it's less confusing to use the Ellipses or the Sentinel. They discuss it here: https://peps.python.org/pep-0661/#use-the-existing-ellipsis-sentinel-value I don't know what they mean by Ellipses "can’t be as confidently used in all cases". |
|
LGTM. I personally prefer Sentinel as “…” can represent a few things depending on the use case (e.g. in arrays) @navin772 @cgoldberg |
navin772
left a comment
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.
LGTM! Either of them looks good now.
User description
🔗 Related Issues
Fixes: #16622
Also see: ##16601 and w3c/webdriver-bidi#1039
💥 What does this PR do?
The BiDi spec allows you to reset the viewport size and device pixel ratio by sending
"viewport": nullor"devicePixelRatio": null:https://w3c.github.io/webdriver-bidi/#command-browsingContext-setViewport
This PR accomplishes that by sending
"viewport": nullor"devicePixelRatio": null, when the arguments toset_viewport()are explicitly set toNone.For example:
If either argument is not passed, the behavior remains the same as before (
viewportand/ordevicePixelRatiois not included in the JSON command payload).This PR also includes a test for this and updates the other viewport tests to reset the viewport and device pixel ratio to default values in their teardown so they don't affect other tests.
🔧 Implementation Notes
To differentiate between being invoked with the arguments set to
Noneand not being provided, I used a sentinel value as the default for the keyword args. Python doesn't have a built-in utility for defining sentinel values (it may someday, see PEP661: https://peps.python.org/pep-0661/), so rather than writing my own, I usedthe
Sentinelclass fromtyping_extensions(we already include this as a dependency): https://typing-extensions.readthedocs.io/en/latest/#sentinel-objects🔄 Types of changes
PR Type
Enhancement, Bug fix
Description
Allow resetting viewport and device pixel ratio to defaults via
NoneUse sentinel value to differentiate explicit
Nonefrom unspecified argumentsAdd comprehensive tests for viewport reset functionality
Update existing tests with teardown to reset viewport state
Diagram Walkthrough
File Walkthrough
browsing_context.py
Implement viewport reset with sentinel value patternpy/selenium/webdriver/common/bidi/browsing_context.py
Sentinelfromtyping_extensionsand defineUNDEFINEDsentinelvalue
set_viewport()method signature to use sentinel defaults forviewportanddevice_pixel_ratioparametersarguments (UNDEFINED), explicit
None(reset), and actual valuesNoneresets parameters to defaultsbidi_browsing_context_tests.py
Add viewport reset tests and cleanup test teardownspy/test/selenium/webdriver/common/bidi_browsing_context_tests.py
state in teardown
cases
test_set_viewport_back_to_default()test to verify resetfunctionality
Nonerestores default viewport and device pixelratio values