You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Diagnose and resolve repeated "Error: ConnectFailure (Connection refused)" when instantiating multiple ChromeDriver instances on Ubuntu 16.04.4 with Chrome 65 / ChromeDriver 2.35 using Selenium 3.9.0.
Provide a fix or guidance so that subsequent ChromeDriver instantiations do not log the ConnectFailure errors.
⚪
Verify behavior through reproduction steps similar to the reporter’s environment.
Objective: To create a detailed and reliable record of critical system actions for security analysis and compliance.
Status: No auditing: The new BiDi command invocation for setting screen orientation overrides adds a critical state change without any corresponding audit logging of the action, user, or outcome.
Generic: Robust Error Handling and Edge Case Management
Objective: Ensure comprehensive error handling that provides meaningful context and graceful degradation
Status: Missing error handling: The method sends the BiDi command without visible handling or reporting of command failures or invalid parameters, relying entirely on underlying layers with no contextual error messages here.
In ScreenOrientation.java, add validation to the toMap() method to ensure the natural orientation and type are consistent, preventing combinations like a PORTRAIT natural orientation with a landscape type.
public Map<String, Object> toMap() {
+ // Validate consistency between natural and type+ boolean isPortraitType = type == ScreenOrientationType.PORTRAIT_PRIMARY+ || type == ScreenOrientationType.PORTRAIT_SECONDARY;+ boolean isLandscapeType = type == ScreenOrientationType.LANDSCAPE_PRIMARY+ || type == ScreenOrientationType.LANDSCAPE_SECONDARY;+ if ((natural == ScreenOrientationNatural.PORTRAIT && !isPortraitType)+ || (natural == ScreenOrientationNatural.LANDSCAPE && !isLandscapeType)) {+ throw new IllegalArgumentException(+ "Inconsistent screen orientation: natural=" + natural + ", type=" + type);+ }
Map<String, Object> map = new HashMap<>();
map.put("natural", natural.toString());
map.put("type", type.toString());
return map;
}
Apply / Chat
Suggestion importance[1-10]: 7
__
Why: This suggestion correctly identifies a potential for inconsistent state and proposes a validation check that improves the robustness of the ScreenOrientation class by preventing invalid combinations from being sent.
Medium
General
Add polling to avoid flakiness
In SetScreenOrientationOverrideTest.java, replace the immediate assertion with a polling loop that waits for the screen orientation to update before asserting the expected values, preventing potential test flakiness.
Why: The suggestion correctly identifies a potential source of test flakiness due to the asynchronous nature of applying screen orientation changes and proposes a robust polling mechanism to mitigate it.
Medium
Learned best practice
✅ Return unmodifiable serialized mapSuggestion Impact:The commit changed toMap() to return Map.of(...), which produces an immutable/unmodifiable map, aligning with the suggestion's intent to return an unmodifiable map.
Why:
Relevant best practice - Use defensive copying and immutability for maps returned by accessors to avoid external mutation.
Low
Possible issue
Omit key instead of using null
In the SetScreenOrientationOverrideParameters constructor, use map.remove("screenOrientation") instead of map.put("screenOrientation", null) when the screenOrientation parameter is null.
public SetScreenOrientationOverrideParameters(ScreenOrientation screenOrientation) {
if (screenOrientation == null) {
- map.put("screenOrientation", null);+ map.remove("screenOrientation");
} else {
map.put("screenOrientation", screenOrientation.toMap());
}
}
Apply / Chat
Suggestion importance[1-10]: 6
__
Why: The suggestion correctly identifies that omitting an optional field is generally more robust for protocol interactions than sending an explicit null, improving code quality and adherence to best practices.
✅ Remove inconsistent and unnecessary page reloadSuggestion Impact:The commit removed the page reload (context.navigate) after calling setScreenOrientationOverride in the test, matching the suggestion to eliminate the unnecessary reload.
code diff:
@@ -64,9 +67,6 @@
emulation.setScreenOrientationOverride(
new SetScreenOrientationOverrideParameters(landscapeOrientation)
.contexts(List.of(contextId)));
-- // Reload the page to apply the orientation change- context.navigate(url, ReadinessState.COMPLETE);
Map<String, Object> currentOrientation = getScreenOrientation(contextId);
assertThat(currentOrientation.get("type")).isEqualTo("landscape-primary");
@@ -124,9 +124,6 @@
new SetScreenOrientationOverrideParameters(landscapeOrientation)
.userContexts(List.of(userContext)));
- // Reload the page to apply the orientation override- context.navigate(url, ReadinessState.COMPLETE);-
Map<String, Object> currentOrientation = getScreenOrientation(contextId);
assertThat(currentOrientation.get("type")).isEqualTo("landscape-primary");
assertThat(currentOrientation.get("angle")).isEqualTo(0);
Remove the inconsistent and unnecessary page reload after the first setScreenOrientationOverride call to make the test accurately reflect the expected dynamic behavior.
-// Reload the page to apply the orientation change-context.navigate(url, ReadinessState.COMPLETE);-
Map<String, Object> currentOrientation = getScreenOrientation(contextId);
assertThat(currentOrientation.get("type")).isEqualTo("landscape-primary");
assertThat(currentOrientation.get("angle")).isEqualTo(0);
// Set portrait-secondary orientation
ScreenOrientation portraitOrientation =
new ScreenOrientation(
ScreenOrientationNatural.PORTRAIT, ScreenOrientationType.PORTRAIT_SECONDARY);
emulation.setScreenOrientationOverride(
new SetScreenOrientationOverrideParameters(portraitOrientation)
.contexts(List.of(contextId)));
currentOrientation = getScreenOrientation(contextId);
assertThat(currentOrientation.get("type")).isEqualTo("portrait-secondary");
assertThat(currentOrientation.get("angle")).isEqualTo(180);
// Clear the override
emulation.setScreenOrientationOverride(
new SetScreenOrientationOverrideParameters(null).contexts(List.of(contextId)));
currentOrientation = getScreenOrientation(contextId);
assertThat(currentOrientation.get("type")).isEqualTo(initialOrientation.get("type"));
assertThat(currentOrientation.get("angle")).isEqualTo(initialOrientation.get("angle"));
Suggestion importance[1-10]: 7
__
Why: The suggestion correctly identifies an inconsistent and likely unnecessary page reload in the test, improving test correctness and consistency.
Medium
✅ Use idiomatic null checks for consistencySuggestion Impact:The commit removed manual null checks and assigned fields using Require.nonNull(), aligning with the suggestion.
code diff:
+import org.openqa.selenium.internal.Require;
public class ScreenOrientation {
private final ScreenOrientationNatural natural;
private final ScreenOrientationType type;
public ScreenOrientation(ScreenOrientationNatural natural, ScreenOrientationType type) {
- if (natural == null) {- throw new IllegalArgumentException("Natural orientation cannot be null");- }- if (type == null) {- throw new IllegalArgumentException("Orientation type cannot be null");- }- this.natural = natural;- this.type = type;+ this.natural = Require.nonNull("natural", natural);+ this.type = Require.nonNull("type", type);
In the ScreenOrientation constructor, replace manual null checks with the idiomatic Require.nonNull() for consistency with the rest of the codebase.
-public ScreenOrientation(ScreenOrientationNatural natural, ScreenOrientationType type) {- if (natural == null) {- throw new IllegalArgumentException("Natural orientation cannot be null");+import org.openqa.selenium.internal.Require;++public class ScreenOrientation {+ // ...+ public ScreenOrientation(ScreenOrientationNatural natural, ScreenOrientationType type) {+ this.natural = Require.nonNull("Natural orientation", natural);+ this.type = Require.nonNull("Orientation type", type);
}
- if (type == null) {- throw new IllegalArgumentException("Orientation type cannot be null");- }- this.natural = natural;- this.type = type;+ // ...
}
Suggestion importance[1-10]: 4
__
Why: The suggestion improves code consistency by proposing the use of the idiomatic Require.nonNull() helper, aligning the new class with existing codebase conventions.
Low
Possible issue
✅ Fetch screen orientation properties atomicallySuggestion Impact:The commit replaced two separate executeScript calls with a single atomic call returning both type and angle, and adjusted the return map accordingly.
Refactor the getScreenOrientation method to fetch screen orientation type and angle in a single, atomic JavaScript execution to prevent potential race conditions.
Why: The suggestion correctly identifies a potential race condition in a test helper method and proposes a more robust, atomic operation which also slightly improves performance.
Low
Learned best practice
Ensure context cleanup with finally
Ensure the created BrowsingContext is closed even if navigation or assertions fail by wrapping its lifecycle in try/finally.
BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
-String contextId = context.getId();+try {+ String contextId = context.getId();-// Navigate to a page first to ensure screen.orientation is available-String url = appServer.whereIs("formPage.html");-context.navigate(url, ReadinessState.COMPLETE);+ // Navigate to a page first to ensure screen.orientation is available+ String url = appServer.whereIs("formPage.html");+ context.navigate(url, ReadinessState.COMPLETE);-Map<String, Object> initialOrientation = getScreenOrientation(contextId);+ Map<String, Object> initialOrientation = getScreenOrientation(contextId);-Emulation emulation = new Emulation(driver);+ Emulation emulation = new Emulation(driver);-// Set landscape-primary orientation-ScreenOrientation landscapeOrientation =- new ScreenOrientation(- ScreenOrientationNatural.LANDSCAPE, ScreenOrientationType.LANDSCAPE_PRIMARY);-emulation.setScreenOrientationOverride(- new SetScreenOrientationOverrideParameters(landscapeOrientation)- .contexts(List.of(contextId)));+ // Set landscape-primary orientation+ ScreenOrientation landscapeOrientation =+ new ScreenOrientation(+ ScreenOrientationNatural.LANDSCAPE, ScreenOrientationType.LANDSCAPE_PRIMARY);+ emulation.setScreenOrientationOverride(+ new SetScreenOrientationOverrideParameters(landscapeOrientation)+ .contexts(List.of(contextId)));-// Reload the page to apply the orientation change-context.navigate(url, ReadinessState.COMPLETE);+ // Reload the page to apply the orientation change+ context.navigate(url, ReadinessState.COMPLETE);-Map<String, Object> currentOrientation = getScreenOrientation(contextId);-assertThat(currentOrientation.get("type")).isEqualTo("landscape-primary");-assertThat(currentOrientation.get("angle")).isEqualTo(0);+ Map<String, Object> currentOrientation = getScreenOrientation(contextId);+ assertThat(currentOrientation.get("type")).isEqualTo("landscape-primary");+ assertThat(currentOrientation.get("angle")).isEqualTo(0);-// Set portrait-secondary orientation-ScreenOrientation portraitOrientation =- new ScreenOrientation(- ScreenOrientationNatural.PORTRAIT, ScreenOrientationType.PORTRAIT_SECONDARY);-emulation.setScreenOrientationOverride(- new SetScreenOrientationOverrideParameters(portraitOrientation)- .contexts(List.of(contextId)));+ // Set portrait-secondary orientation+ ScreenOrientation portraitOrientation =+ new ScreenOrientation(+ ScreenOrientationNatural.PORTRAIT, ScreenOrientationType.PORTRAIT_SECONDARY);+ emulation.setScreenOrientationOverride(+ new SetScreenOrientationOverrideParameters(portraitOrientation)+ .contexts(List.of(contextId)));-currentOrientation = getScreenOrientation(contextId);-assertThat(currentOrientation.get("type")).isEqualTo("portrait-secondary");-assertThat(currentOrientation.get("angle")).isEqualTo(180);+ currentOrientation = getScreenOrientation(contextId);+ assertThat(currentOrientation.get("type")).isEqualTo("portrait-secondary");+ assertThat(currentOrientation.get("angle")).isEqualTo(180);-// Clear the override-emulation.setScreenOrientationOverride(- new SetScreenOrientationOverrideParameters(null).contexts(List.of(contextId)));+ // Clear the override+ emulation.setScreenOrientationOverride(+ new SetScreenOrientationOverrideParameters(null).contexts(List.of(contextId)));-currentOrientation = getScreenOrientation(contextId);-assertThat(currentOrientation.get("type")).isEqualTo(initialOrientation.get("type"));-assertThat(currentOrientation.get("angle")).isEqualTo(initialOrientation.get("angle"));+ currentOrientation = getScreenOrientation(contextId);+ assertThat(currentOrientation.get("type")).isEqualTo(initialOrientation.get("type"));+ assertThat(currentOrientation.get("angle")).isEqualTo(initialOrientation.get("angle"));+} finally {+ context.close();+}
Suggestion importance[1-10]: 6
__
Why:
Relevant best practice - Always wrap creation of external contexts/resources in try/finally and ensure explicit cleanup to prevent leaks on failure.
Low
Possible issue
Omit null field from payload
Modify the SetScreenOrientationOverrideParameters constructor to omit the screenOrientation key from the payload when it is null, instead of explicitly setting it to null.
public SetScreenOrientationOverrideParameters(ScreenOrientation screenOrientation) {
- if (screenOrientation == null) {- map.put("screenOrientation", null);- } else {+ if (screenOrientation != null) {
map.put("screenOrientation", screenOrientation.toMap());
}
+ // If null, omit the key to clear the override
}
Suggestion importance[1-10]: 7
__
Why: The suggestion correctly identifies that omitting a key is often better than sending an explicit null in JSON-RPC protocols, improving robustness and adherence to the BiDi specification.
Medium
Serialize using enum values
In ScreenOrientation.toMap(), use a dedicated getValue() method for serializing the natural and type enums instead of relying on toString().
Why: The suggestion improves code robustness by decoupling serialization logic from the toString() method, which is a good practice even though the current implementation works correctly.
Low
General
Add explicit enum value getter
In the ScreenOrientationNatural enum, add an explicit getValue() accessor for the protocol value and change toString() to return the enum's name for better debugging.
public enum ScreenOrientationNatural {
PORTRAIT("portrait"),
LANDSCAPE("landscape");
private final String value;
ScreenOrientationNatural(String value) {
this.value = value;
}
+ public String getValue() {+ return value;+ }+
@Override
public String toString() {
- return value;+ return name();
}
}
Suggestion importance[1-10]: 5
__
Why: This is a good code quality suggestion that improves maintainability by separating the enum's serialization value from its string representation, preventing potential future bugs.
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
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.
User description
🔗 Related Issues
💥 What does this PR do?
Implements
emulation.setScreenOrientationOverridefrom W3C spec - https://w3c.github.io/webdriver-bidi/#command-emulation-setScreenOrientationOverride🔧 Implementation Notes
💡 Additional Considerations
🔄 Types of changes
PR Type
Enhancement
Description
Implements
emulation.setScreenOrientationOverrideBiDi commandAdds screen orientation enums and parameter classes
Includes comprehensive tests for context and user context
Supports clearing orientation overrides with null parameter
Diagram Walkthrough
File Walkthrough
Emulation.java
Add setScreenOrientationOverride methodjava/src/org/openqa/selenium/bidi/emulation/Emulation.java
setScreenOrientationOverridemethod to Emulation classSetScreenOrientationOverrideParametersand sends BiDicommand
setUserAgentOverridemethodScreenOrientation.java
Create ScreenOrientation model classjava/src/org/openqa/selenium/bidi/emulation/ScreenOrientation.java
toMap()method for BiDi serializationScreenOrientationNatural.java
Create ScreenOrientationNatural enumjava/src/org/openqa/selenium/bidi/emulation/ScreenOrientationNatural.java
toString()for BiDi protocol serializationScreenOrientationType.java
Create ScreenOrientationType enumjava/src/org/openqa/selenium/bidi/emulation/ScreenOrientationType.java
LANDSCAPE_SECONDARY
toString()for BiDi protocol serializationSetScreenOrientationOverrideParameters.java
Create SetScreenOrientationOverrideParameters classjava/src/org/openqa/selenium/bidi/emulation/SetScreenOrientationOverrideParameters.java
AbstractOverrideParametersScreenOrientationobject in constructorcontexts()anduserContexts()for targeting specific contextsSetScreenOrientationOverrideTest.java
Add comprehensive screen orientation override testsjava/test/org/openqa/selenium/bidi/emulation/SetScreenOrientationOverrideTest.java
screen.orientationAPI