skip to content

In the W3C WebDriver spec, which new-session data must an intermediary node forward, and which must it not?

level: seniorimportance: should knowfreq 45%

answer

  1. two mandates, opposite verbs
  2. inside capabilities, or beside it
  3. must not forward against must forward
  4. the spec shows both spellings
  5. a chain of hops makes it visible

basics

~20 s

Custom top-level parameters sitting beside capabilities must be forwarded to subsequent remote end nodes. Extension capabilities the intermediary itself defined must not be. Which half of the request body the data sits in decides its fate.

solid answer

~50 s

The specification states both rules within a few lines of each other and they point in opposite directions. An intermediary node *must not* forward the extension capabilities it defined for its own routing, and it *must forward custom, top-level parameters — that is, non-capabilities — to subsequent remote end nodes*. The spec then shows both spellings for the same job. Its recommended form keeps the intermediary's own non-capability arguments beside `capabilities` as top-level parameters, on the grounds that an argument to the `New Session` command is not a user-agent feature. Its second worked example puts `cloud:user` and `cloud:password` inside `alwaysMatch` instead, and says that form is *also permitted precisely because* an intermediary cannot forward its own extension capabilities onward. Same information, opposite travel: one stops at the hop that understands it, the other is passed along.

code

json · 13 lines
json
{
  "capabilities": {
    "alwaysMatch": {
      "cloud:user": "alice",
      "cloud:password": "hunter2",
      "platformName": "linux"
    },
    "firstMatch": [
      {"browserName": "chrome"},
      {"browserName": "edge"}
    ]
  }
}

go deeper

for a junior

Know that a new-session request has two regions: the capabilities object and whatever sits beside it. That distinction is the whole basis of the answer at every level above this one.

for a middle

Be ready to state both rules and their opposite directions, and to say that placement in the body, not meaning, decides which applies. Naming the spec's own authentication example is a strong addition.

for a senior

Be ready to reason about a chain of more than one hop, where the difference becomes observable: a namespaced value dies at the first owner while a top-level parameter reaches every node in the path.

for a principal

Be ready to weigh the two placements as a policy question for data you would rather not have travel far, knowing that the standard's bound on an extension capability is real but narrow and that client support is often the deciding constraint.

## Two rules, three lines apart, pointing opposite ways The `New Session` section of the W3C WebDriver specification contains both of these: 1. *"An intermediary node is free to define extension capabilities to assist in this process, however, these specific capabilities must not be forwarded to the endpoint node."* 2. *"An intermediary node must forward custom, top-level parameters (i.e. non-capabilities) to subsequent remote end nodes."* Two mandates on the same component, in the same request, with opposite verbs. The discriminator is not what the data means — it is **where in the request body it sits**. ## The shape of the body A `New Session` request body is a JSON object. One member is `capabilities`, holding `alwaysMatch` and `firstMatch`. Anything else at the same level is a **top-level parameter** — a non-capability argument to the command itself. - Inside `capabilities`: describes what the session should *be*. Consumed and removed by whichever hop owns the namespace. - Beside `capabilities`: an argument to the *command*. Forwarded down the chain. The spec spells out the reasoning for the second case: where an intermediary node requires *"additional information unrelated to user agent features"*, it recommends that this information be passed as top-level parameters and not as part of the requested capabilities. A setting that is not about the browser has no business in a structure that describes the browser. ## The spec's own worked pair The specification illustrates the point twice with the same information, moved from one region of the request body to the other. Its recommended form keeps that information beside `capabilities` as top-level members, with the note that an argument to the `New Session` command itself is not one of the user agent's capabilities. Its second example moves the same two values inside `alwaysMatch` as `cloud:user` and `cloud:password`, and introduces it with the reason: *"However, because an intermediary node cannot forward extension capabilities specific to that implementation to an endpoint node, the following is also permitted."* The must-not-forward rule is not an obstacle to this spelling — it is the **justification** for it. Credentials placed in a namespace are guaranteed by the standard to stop at the hop that reads them. The spec then shows what the endpoint node actually receives after merging: two candidate capability sets containing only `browserName` and `platformName`. The `cloud:` pair is simply gone. ## A comparison worth holding in your head | property | extension capability | custom top-level parameter | |---|---|---| | where it sits | inside `alwaysMatch` or a `firstMatch` entry | beside `capabilities` | | key form | must contain a colon | ordinary member name | | forwarding rule | must not be forwarded **by the hop that defined it** | must be forwarded onward by every hop | | reaches a chain of hops | only as far as the hop that owns it; one owned further down travels on | yes, the whole chain | | survives to the endpoint node | the intermediary's own, no; a browser vendor's, yes | yes | Read the last two rows with their qualifier attached: what dies at a hop is the namespace *that hop* defined. An options map belonging to the browser itself crosses every intermediary and arrives at the endpoint node intact. ## Why a chain makes the difference visible With one hop between client and browser the two spellings look interchangeable. Put two hops in the path — a routing front end that dispatches to a session service which then talks to a driver — and they diverge sharply: - A namespaced capability **owned by** the first hop is removed there. The second hop never sees it and cannot act on it; one owned further down passes straight through. - A top-level parameter is forwarded by the first hop, so the second hop receives it and can authenticate or route on it in turn. That is the design intent. A capability is per-session configuration that one component resolves. A top-level parameter is an argument that a whole chain may need, and the specification obliges each hop to keep passing it on. ## What this changes about how you send things For a school-timetabling suite pointed at a service you do not operate, the practical consequences are short: - Where a setting is namespaced for a hop in front of you, expect it to be invisible from that hop onward, and never look for it in the returned capabilities as proof it arrived. - Where a setting is a top-level parameter, expect it to keep travelling, and assume every hop in the path has seen it. - Anything sensitive is safer in the namespaced form on this axis alone, because the standard bounds how far it goes; that is a narrower guarantee than it sounds, but it is a real one. - Do not assume a client library exposes both routes. Many expose capabilities richly and top-level parameters barely at all, which is one practical reason the namespaced spelling is so common in the wild. ## The one-sentence version An extension capability stops at the node that understands it; a custom top-level parameter is passed along. Both rules are mandatory, they are three lines apart in the same section, and the only thing that decides which one applies to your data is whether you put it inside `capabilities` or beside it.

  • Why does the spec recommend top-level parameters for information unrelated to browser features?
    Because `capabilities` is a description of the session the browser should provide, and the matching algorithm treats every member as part of that description. Data that is an argument to the `New Session` command — authentication, routing hints — is not a property of the browser, so putting it there overloads a structure with a defined meaning. The spec says as much and then mandates that such parameters be forwarded onward.
  • If both spellings are permitted, why is the namespaced one so common in practice?
    Mostly client support. Capability objects are first-class in every client library, while arbitrary top-level members of the new-session body often are not exposed at all. The namespaced form also composes cleanly with existing options builders. The specification permits it explicitly, and its stated reason is the must-not-forward rule: an intermediary's own capabilities are guaranteed to stop there.
  • What does the endpoint node see after the spec's cloud: example is merged?
    Two candidate capability sets, one naming Chrome and one naming Edge, each carrying the Linux platform name from `alwaysMatch` — and neither carrying `cloud:user` or `cloud:password`. The spec prints that merged result immediately after the example, which makes it the clearest illustration in the document that an intermediary's own namespace does not survive the hop.

saying these in an interview costs you the question

  • Assumes one forwarding rule covers the whole request body
  • Thinks top-level parameters are stripped like capabilities
  • Believes namespaced credentials reach the browser process
  • Says the specification forbids credentials in capabilities
  • Cannot say which half of the body a value sits in