Capabilities
============

WebDriver ***capabilities*** are used to communicate the features supported by a session. A client may also use capabilities to define which features it requires the driver to satisfy when creating a new session.

When a WebDriver session is created it returns a set of capabilities describing the negotiated, effective capabilities of the session. Some of the capabilities included in this set are standard and shared between all browsers, but the set may also contain browser-specific capabilities and these are always prefixed.

Capabilities negotiation
------------------------

Capabilities can be used to require a driver that supports a certain subset of features. This can be used to require certain browser features, such as the ability to resize the window dimensions, but is also used in distributed environments to select a particular browser configuration from a matrix of choices.

Selecting a particular web browser or platform only makes sense when you use a remote WebDriver. In this case the client makes contact with WebDriver through one or more intermediary nodes which negotiates which driver to return to you based on the capabilities it receives.

The capabilities object is a selection mechanism that limits which driver configurations the server will return. If you request a Firefox instance using `browserName` and Firefox is not installed on the remote, or macOS from a remote that only supports Linux, you may be out of luck. But occasionally you may not care which specific operating system or web browser your session has: you just want a session that has some *capability*.

The selection process, or the *capabilities negotiation*, is done through `alwaysMatch` and `firstMatch`.

### `alwaysMatch`

As the name suggests, capabilities described inside the `alwaysMatch` capabilities object are features you *require* the session to have. If the server can not provide what features you require, it will fail.

If for example you ask for Firefox version 62 on a system that only has 60 installed, the session creation will fail:


```json
{
  "capabilities": {
    "alwaysMatch": {
      "browserName": "firefox",
      "browserVersion": "60"
    }
  }
}
```

### `firstMatch`

The `firstMatch` field accepts *an array* of capabilities objects which will be matched in turn until one matches what the server can provide, or it will fail.

This can be useful when you want a driver that runs on macOS or Linux, but not Windows:


```json
{
  "capabilities": {
    "firstMatch": [{ "platformName": "macos" }, { "platformName": "linux" }]
  }
}
```

### Combining `alwaysMatch` and `firstMatch`

`firstMatch` can of course be combined with `alwaysMatch` to narrow down the selection. If for example you a driver that runs on macOS or Linux but it *has* to be Firefox:


```json
{
  "capabilities": {
    "alwaysMatch": {
      "browserName": "firefox"
    },
    "firstMatch": [{ "platformName": "macos" }, { "platformName": "linux" }]
  }
}
```


The previous example is exactly equivalent to putting the Firefox requirement in each `firstMatch` arm:


```json
{
  "capabilities": {
    "firstMatch": [
      { "browserName": "firefox", "platformName": "macos" },
      { "browserName": "firefox", "platformName": "linux" }
    ]
  }
}
```


Which you choose of the two preceding examples is not important, but it can matter when pass along browser configuration. To avoid unnecessarily repeating data, such as profiles, it is advisable to make use of `alwaysMatch` so that this data is only transmitted across the wire once:


```json
{
  "capabilities": {
    "alwaysMatch": {
      "browserName": "firefox",
      "moz:firefoxOptions": {
        "profile": "<base64 encoded profile>",
        "args": ["-headless"],
        "prefs": { "dom.ipc.processCount": 8 },
        "log": { "level": "trace" }
      }
    },
    "firstMatch": [{ "platformName": "macos" }, { "platformName": "linux" }]
  }
}
```

List of capabilities
--------------------

* `browserName`
* `browserVersion`
* `platformName`
* `acceptInsecureCerts`: This capability communicates whether expired or invalid TLS certificates are checked when navigating. If the capability is false, an insecure certificate error will be returned as navigation encounters domains with certificate problems. Otherwise, self-signed or otherwise invalid certificates will be implicitly trusted by the browser on navigation. The capability has effect for the lifetime of the session.
* `pageLoadStrategy`
* `proxy`
* `setWindowRect`
* `timeouts`
* `unhandledPromptBehavior`
Vendor-specific capabilities
----------------------------

In addition to the standard capabilities WebDriver allows third-parties to *extend* the set of capabilities to match their needs. Browser vendors and suppliers of drivers typically use extension capabilities to provide configuration to the browser, but they can also be used by intermediaries for arbitrary blobs of information.

* Firefox capabilities (`moz:firefoxOptions`)
* Chrome capabilities (`goog:chromeOptions`)
Legacy capabilities
-------------------

The majority of Selenium clients use `desiredCapabilities` and `requiredCapabilities` to configure the new session. These are very similar to `firstMatch` and `alwaysMatch` described above. Some drivers support these legacy capabilities, but they are deprecated and should be avoided.

Converting a legacy capabilities object into the new style is easy. The first thing you need to know is that `alwaysMatch`/`firstMatch` is *always* wrapped inside a `capabilities` JSON Object, whereas `desiredCapabilities`/`requiredCapabilities` exists at the top level. Generally speaking, anything that has previously gone in `desiredCapabilities` should go in a `firstMatch` branch arm to achieve the same effect.

Take this deprecated capabilities object:


```json
{ "desiredCapabilities": { "browserName": "firefox" } }
```


This would be functionally equivalent in the new style:


```json
{ "capabilities": { "firstMatch": [{ "browserName": "firefox" }] } }
```


But because there is only one `firstMatch` arm, and we know that session creation will fail if the server doesn't have a Firefox installed, it is also equivalent to this:


```json
{ "capabilities": { "alwaysMatch": { "browserName": "firefox" } } }
```

See also
--------

* New Session command
* Delete Session command