-
Notifications
You must be signed in to change notification settings - Fork 10
Add an API to set capabilities #10
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
Comments
We will probably never support the latest options for every browser, so I think having a json::Value somewhere is a good idea. Perhaps JSON inside Capabilities and have a method on it that'll take a string key and JSON value, and a method that'll take some typed Gecko- or ChromeDriverCapabilities and merge with the JSON inside? I'd be fine with a first implementation that just accepts a JSON blob, with the option to add methods taking typed objects later. Would you like to work on this issue further, perhaps as part of the ChromeDriver PR? |
I'll probably do something like this for the chrome tests to work on travis. |
ref for merge implementation serde-rs/json#377 (comment) |
I like the sound of something fluent, like your builder idea. How about: struct Capabilities {
...
}
impl Capabilities {
// Actually empty collection
fn empty() -> Capabilities { ... }
// I really like the sound of your generic Serializable idea if you can get it
// to compile without too much trouble.
fn always(&mut self, key: &str, value: Option<serde_json::Value>) -> &mut Self {
...
}
}
impl Default for Capabilities {
// Default will include e.g. goog:chromeOptions workaround we need for
// ChromeDriver to behave.
fn default() -> Capabilties { ... }
}
// Usage example:
let caps =
Capabilities::default()
.always("foo", json!{ bar: 12 });
let session = driver.session(caps); |
Should the builder api be in the |
Not the best naming but still /// Extend a capability requirement with a new object.
///
/// Extending a capability that does not exist, or attempting to extend non objects will have
/// the same effect as calling [always_match()](#method.always_match).
pub fn extend_always_match(&mut self, name: &str, capability: JsonValue) {
if let JsonValue::Object(capability) = capability {
if let Some(&mut JsonValue::Object(ref mut map)) = self.capabilities.alwaysMatch.get_mut(name) {
map.extend(capability);
return;
}
self.capabilities.alwaysMatch.insert(name.to_string(), JsonValue::Object(capability));
} else {
self.capabilities.alwaysMatch.insert(name.to_string(), capability);
}
} For example this adds more options for chrome without discarding our default values. let mut session_params: NewSessionCmd = Default::default();
session_params.extend_always_match("goog:chromeOptions", json!({
"args": ["--no-sandbox", "--headless"],
})); I've been reading the spec but the semantics of alwaysMatch and firstMatch is not very clear, this description helps though w3c/webdriver#1215 (comment) |
Yes, that link is very helpful for understanding the semantics! Roughly it seems like
Thinking about it again, your approach of having it on On naming, I'm happy with any of: I doubt many people new to WebDriver would understand any of the names without looking at the documentation or the specs, so I have a slight preference for the shorter ones to make the common case simplest to type and read. The longer ones are a bit more explicit, of course. Bear in mind that if you pick a short version, there could be another method |
I don't have a very concrete example to propose for this yet. But we need some way to build the NewSessionCmd object that allows setting the capabilities and desired capabilities.
In #9 I took the cheap way out and just used the
json!
macro to craft the capabilities. But we need something that can be used in a public api like a builder for the capabilities object.Storage can be implemented via a new type (this uses the code in #9 as an example)
Maybe something like the following method in
NewSessionCmd
but have not taken into consideration thefirstMatch
attribute in the spec. Probably should have a look at it first.My other doubt here is the type of the supplied value argument. Should we take a
serde_json::Value
or more generically anything that implementsSerialize
? Since Value does implement Serialize maybe we should start with just Value.TODO
The text was updated successfully, but these errors were encountered: