Re: The ever contentious capabilities for new sessions

On 14/09/16 15:39, Simon Stewart wrote:

>     For browser settings, the options that match would be cumulative, so
>     any browser would set the script timeout to 30s, any firefox would
>     use the same base profile, firefox 49 would set a specific pref, and
>     Chrome would use a specific binary. For matching with the version
>     number one would have to use the specified binary, if any so e.g.
>     {
>     "settings": [
>       {"timeouts": {"script": 30000}},
>       {"match": {"browser": "firefox", "version": 49},
>                  "binary": "/home/user/firefox"}
>       ]
>     }
>     running in firefox would only use the /home/user/firefox binary if
>     that binary was a firefox 49 binary (if intermediary nodes could be
>     required to edit the new session payload we could sidestep this
>     complexity by requiring that they reduce the settings to a list of
>     length 1 with no match clauses representing only the things that are
>     known to work. But that does have the problem that one can't send
>     the same message irrespective of whether a routing intermediary is
>     present).
> This cumulative thing seems more complex than Jason's suggestion, and
> would mean that each browser would need to prefix browser-specific
> options with vendor prefixes. For example, "profile" strikes me as
> something that would fall into this --- imagine asking for a "firefox
> with this profile" and if that wasn't available "chrome". With your
> suggestion (if I understand it properly), we'd attempt to start chrome
> with a firefox profile. Clearly far from ideal….

I don't think I can have explained it properly because that certainly 
wasn't the intent.

The major design goal here is to separate out as much as possible two 
largely orthogonal things. One is routing a request to a specific end 
node, the other is setting up that end node according to what's needed 
for the tests.

Routers only look at the "routing" key (ignoring any other top level key 
they require to perform additional functions like authentication). This 
contains an ordered list of objects describing the preferred end node 
type to select. These object could in principle contain anything that 
the router could select on so if some intermediary wanted to add, say, a 
"platformType" key with values "desktop", "mobile", "tablet" and "tv 
screen in Times Square", that would be fine. However it seems like the 
spec is going to specifically mention four common settings around 
browser, platform and versions of those.

The other part of the proposal is aimed at end nodes only. End nodes 
only look at the "settings" key. This is a list consisting of objects 
that may contain a property called "match". If "match" is missing or 
null the remaining properties on the object are applied as settings 
irrespective of the properties of the end node. Otherwise the user agent 
evaluates the properties of the "match" object against the properties of 
the browser that would be launched given that all previously matched 
settings plus the current set of settings are applied (this complexity 
matters mostly because of version numbers and the ability to provide 
custom binary paths). If those properties are a match for the current 
browser the settings described in the rest of the object will be 
applied. This means that you never get settings for chrome and firefox 
mixed up, for example.

I think this part is easier to understand with an illustration:

Imagine I send

{"settings": [
   {"timeouts": {"script": 30000}},
   {"match": {"browser":"firefox"}
    "profile": "<someFirefoxProfile>"},
   {"match": {"browser": "chrome"},
    "profile": "<someChromeProfile>"},
   {"match": {"browser": "firefox", "platform": "linux",
              "browserVersion": 47},
    "binary": "/usr/bin/firefox",
    "prefs": {"dom.serviceworker.enabled": true}

Let's say geckodriver gets the above message so the browser that will be 
launched is Firefox and that we know we are running on Linux.

So we go through the list in order:
   - {"timeouts": {"script": 30000}} has no "match" clause so it always 
applies. Our final settings object is set to
  {"timeouts": {"script": 30000}}.

  - {"match": {"browser":"firefox"}
     "profile": "<someFirefoxProfile>"} has a "match" clause on the 
browser name which will match, so we also add these settings. The final 
settings object becomes
  {"timeouts": {"script": 30000},
   "profile": "<someFirefoxProfile>"}.

  - {"match": {"browser": "chrome"},
     "profile": "<someChromeProfile>"} has a similar match clause to the 
previous one, but this time doesn't result in a match, so the final 
settings object is unchanged.

  - {"match": {"browser": "firefox", "platform": "linux",
               "browserVersion": 47},
    "binary": "/usr/bin/firefox",
    "prefs": {"dom.serviceworker.enabled": true} is the complex case. 
Browser and platform match, but version is more complex. In this case we 
have to form a candidate settings object:
   {"timeouts": {"script": 30000},
    "profile": "<someFirefoxProfile>"
    "binary": "/usr/bin/firefox",
    "prefs": {"dom.serviceworker.enabled": true}
  Now we inspect this binary and check if it is a Firefox 47 binary. In 
the case that it is the final settings object is the candidate settings 
object, otherwise it remains unchanged from the step before.

The settings we use for configuring the remote end are then those 
described by the final settings object.

I think that this isn't actually any more complex than the other model. 
In particular I have made a point of demonstrating the hardest possible 
cases that other models don't handle well e.g. routing on one set of 
properties by configuring the end nodes based on a different set of 
properties. But in the case where you already know what kind of end node 
you will get you simply send

"settings": [
     {"some setting": "some value"}

(one can imagine a microoptimisation to allow the list to be omitted in 
the case that there is exactly one entry).

Received on Wednesday, 14 September 2016 15:22:07 UTC