-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
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
Add methods to options classes for w3c compliant capabilities #9828
Conversation
return (DO) this; | ||
} | ||
|
||
public DO setTimeouts(Map<String, Duration> timeouts) { |
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.
Prefer a setImplicitTimeout
, setPageLoadTimeout
and setScriptTimeout
, and then we don't need to do any validation, and it's really hard to get wrong.
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.
Much better implementation.
} | ||
}); | ||
|
||
setCapability(TIMEOUTS, convertedTimeouts); |
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.
I think this has the potential to get confusing --- somewhere in a framework the implicit timeout is set, and then user code sets the page load timeout: what do we expect to happen to the implicit timeout? I think people will expect both to be set.
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.
splitting up the timeouts as suggested above fixes this issue nicely.
@@ -47,6 +47,10 @@ | |||
String HAS_TOUCHSCREEN = "hasTouchScreen"; | |||
String OVERLAPPING_CHECK_DISABLED = "overlappingCheckDisabled"; | |||
String STRICT_FILE_INTERACTABILITY = "strictFileInteractability"; | |||
String TIMEOUTS = "timeouts"; | |||
String IMPLICIT_TIMEOUT = "implicit"; |
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.
These are really meant to be the keys in the capabilities, not the keys of values within the capabilities
b33b1d2
to
eeaee77
Compare
chromeOptions.setPageLoadTimeout(Duration.ofSeconds(2)); | ||
expectedTimeouts.put("pageLoad", 2000L); | ||
Map<String, Object> mappedOptions2 = chromeOptions.asMap(); | ||
assertThat(expectedTimeouts).isEqualTo(mappedOptions2.get("timeouts")); |
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.
Perhaps:
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.setImplicitWaitTimeout(Duration.ofSeconds(1));
assertThat(chromeOptions.getCapability(TIMEOUTS)).isEqualTo(Map.of("implicit", 1000L);
chromeOptions.setPageLoadTimeout(Duration.ofSeconds(2));
assertThat(chromeOptions.getCapability(TIMEOUTS)).isEqualTo(Map.of("implicit", 1000L, "page", 2000L);
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.
There's no need to convert the options to an intermediate map.
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.
agreed, doesn't make sense if needing to look at existing capabilities
public abstract class AbstractDriverOptions<DO extends AbstractDriverOptions> extends MutableCapabilities { | ||
private Map<String, Long> timeouts = new HashMap<>(); |
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.
I'd be tempted to avoid this variable. Consider a user doing:
options.setCapability(TIMEOUTS, Map.of("implicit", 1000));
options.setPageLoadTimeout(Duration.ofSeconds(10));
I think a user would expect both timeouts to have been set, but the current implementation would only set one. I also think the opposite case (where the timeouts capability is set after calling the specific method) would mean that the user would expect the timeout map they passed in to be used.
One drawback to doing this is that you can't expect the Map
the user passes in to be mutable. You'll need a check like:
Map<String, Long> newTimeouts = new HashMap<>();
Object raw = getCapability(TIMEOUTS);
if (!(raw instanceof Map)) {
((Map<?, ?>) raw).foreach((key, value) -> {
if (key instanceof String && value instanceof Long) {
newTimeouts.put((String) key, (Long) value);
}
}
newTimeouts.put("implicit", timeout.toMillis());
setCapability(TIMEOUTS, Collections.immutableMap(newTimeouts));
))
Finally, it's good practice to make the collection "unmodifiable" when we set it, to prevent users from changing state in unexpected ways.
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.
Ok, I put this in a private getCapabilities()
method. I'm not sure the reason for instanceof Map
conditional. What alternative object is valid that will start a session?
SonarCloud Quality Gate failed. |
|
||
private Map<String, Number> getTimeouts() { | ||
Map<String, Number> newTimeouts = new HashMap<>(); | ||
Object raw = getCapability(TIMEOUTS); |
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.
You need to check that raw
is actually a Map
before casting to it. If not, if the user has set some garbage value (eg: setCapability(TIMEOUTS, "cheese")
chaos will follow.
Description
Adds methods and tests for:
setBrowserVersion()
setPlatformName()
setTimeouts()
edit:
setImplicitWaitTimeout()
setPageLoadTimeout()
setScriptTimeout()
Timeouts has user-facing
Duration
that gets converted to millis when adding it to capabilities.Motivation and Context
It makes sense to have specific methods for known capabilities, and this is backwards compatible.