- From: James Graham <james@hoppipolla.co.uk>
- Date: Wed, 14 Sep 2016 16:21:42 +0100
- To: public-browser-tools-testing@w3.org
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