# getContexts

The WebdriverIO `getContexts` method is an improved version of the default Appium `contexts` (and the previous WebdriverIO `getContexts`) command. It provides detailed and actionable information about available contexts in a mobile app session, addressing the limitations of the default Appium methods.

### How Webviews Work and Why This Method Helps[​](#how-webviews-work-and-why-this-method-helps "Direct link to How Webviews Work and Why This Method Helps")

For more details, refer to the [Hybrid Apps documentation](/docs/api/mobile.md#hybrid-apps). Below is a summary of the challenges addressed by the `getContexts` command:

#### Android Challenges[​](#android-challenges "Direct link to Android Challenges")

* A single webview (e.g., `WEBVIEW_{packageName}`) may contain multiple pages (similar to browser tabs).
* The default Appium methods do not include details about these pages, such as their `title`, `url`, or visibility, making it hard to identify the correct page and leading to potential flakiness.

#### iOS Challenges[​](#ios-challenges "Direct link to iOS Challenges")

* The default Appium method only returns generic webview IDs (e.g., `WEBVIEW_{id}`) without any additional metadata.
* This makes it difficult to determine which webview corresponds to the target app screen.

The enhanced `getContexts` method solves these issues by returning detailed context objects, which include:

* **For Android:** `title`, `url`, `packageName`, `webviewPageId`, and layout details (`screenX`, `screenY`, `width`, and `height`).
* **For iOS:** `bundleId`, `title`, and `url`.

These enhancements make debugging and interacting with hybrid apps more reliable.

### Why Use This Method?[​](#why-use-this-method "Direct link to Why Use This Method?")

By default, the Appium `contexts` method returns only an array of strings representing available contexts:

* **For Android:** `['NATIVE_APP', 'WEBVIEW_com.wdiodemoapp', ...]`
* **For iOS:** `['NATIVE_APP', 'WEBVIEW_84392.1', ...]`

While sufficient for simple scenarios, these default responses lack critical metadata for hybrid app testing:

* **For Android:** The lack of page-specific metadata makes it challenging to interact with the correct webview.
* **For iOS:** Generic webview IDs provide no insight into the content or app screen they represent.

The enhanced `getContexts` method provides:

* Detailed metadata for both Android and iOS.
* Options to filter and customize the returned contexts for better targeting and interaction.

Notes and Limitations

* The enhanced `getContexts` method works on both Android and iOS platforms. However, the returned data may vary depending on the platform and app under test.
* If you do not specify the `returnDetailedContexts` option, the method behaves like the default Appium `contexts` method, returning a simple context array.
* To use the "default" Appium `contexts` method, use `driver.getAppiumContexts()`. For more information, see the [Appium Contexts documentation](/docs/api/appium.md#getappiumcontexts).

#### Android Webviews:[​](#android-webviews "Direct link to Android Webviews:")

* Metadata such as `androidWebviewData` is available only when `returnAndroidDescriptionData` is `true`.
* Using the `getContexts` method on a Chrome browser may occasionally return incomplete data due to mismatched browser/Webview/ChromeDriver versions. In such cases, default values or an incorrect `webviewPageId` (e.g., `0`) may be returned.

## Parameters[​](#parameters "Direct link to Parameters")

| Name                                                        | Type                 | Details                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| ----------------------------------------------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `options`<br />*optional*                                   | `GetContextsOptions` | The `getContexts` options (optional)                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `options.returnDetailedContexts`<br />*optional*            | `boolean`            | By default, we only return the context names based on the default Appium `contexts` API. If you want to get all data, you can set this to `true`. Default is `false` (optional).                                                                                                                                                                                                                                                                                                                        |
| `options.androidWebviewConnectionRetryTime`<br />*optional* | `number`             | The time in milliseconds to wait between each retry to connect to the webview. Default is `500` ms (optional).<br />**ANDROID-ONLY**                                                                                                                                                                                                                                                                                                                                                                    |
| `options.androidWebviewConnectTimeout`<br />*optional*      | `number`             | The maximum amount of time in milliseconds to wait for a web view page to be detected. Default is `5000` ms (optional).<br />**ANDROID-ONLY**                                                                                                                                                                                                                                                                                                                                                           |
| `options.filterByCurrentAndroidApp`<br />*optional*         | `boolean`            | By default, we return all webviews. If you want to filter the webviews by the current Android app that is opened, you can set this to `true`. Default is `false` (optional).<br />**NOTE:** Be aware that you can also NOT find any Webview based on this "restriction".<br />**ANDROID-ONLY**                                                                                                                                                                                                          |
| `options.isAndroidWebviewVisible`<br />*optional*           | `boolean`            | By default, we only return the webviews that are attached and visible. If you want to get all webviews, you can set this to `false` (optional). Default is `true`.<br />**ANDROID-ONLY**                                                                                                                                                                                                                                                                                                                |
| `options.returnAndroidDescriptionData`<br />*optional*      | `boolean`            | By default, no Android Webview (Chrome) description description data. If you want to get all data, you can set this to `true`. Default is `false` (optional).<br />By enabling this option you will get extra data in the response, see the `description.data.test.js` for more information.<br />**ANDROID-ONLY**                                                                                                                                                                                      |
| `options.waitForWebviewMs`<br />*optional*                  | `number`             | The time in milliseconds to wait for webviews to become available before returning contexts. This parameter is passed directly to the Appium `mobile: getContexts` command. Default is `0` ms (optional).<br />**ANDROID-ONLY**<br />This is useful when you know that a webview is loading but needs additional time to become available. This option works at the Appium level, before WebdriverIO's retry logic (`androidWebviewConnectionRetryTime` and `androidWebviewConnectTimeout`) is applied. |

## Examples[​](#examples "Direct link to Examples")

example.test.js

```
it('should return all contexts in the current session with the default Appium `contexts`-method.', async () => {
    // For Android
    await driver.getContexts()
    // Returns ['NATIVE_APP', 'WEBVIEW_com.wdiodemoapp', ...]
    //
    // For iOS, the context will be 'WEBVIEW_{number}'
    await driver.getContexts()
    // Returns [ 'NATIVE_APP', 'WEBVIEW_84392.1', ... ]
})
```

detailed.test.js

```
it('should return all contexts in the current session with detailed info.', async () => {
    // For Android
    await driver.getContexts({returnDetailedContexts: true})
    // Returns [
    //   { id: 'NATIVE_APP' },
    //   {
    //       id: 'WEBVIEW_com.wdiodemoapp',
    //       title: 'WebdriverIO · Next-gen browser and mobile automation test framework for Node.js | WebdriverIO',
    //       url: 'https://webdriver.io/',
    //       packageName: 'com.wdiodemoapp',
    //       webviewPageId: '58B0AA2DBBBBBE9008C35AE42385BB0D'
    //   },
    //   {
    //       id: 'WEBVIEW_chrome',
    //       title: 'Android | Get more done with Google on Android-phones and devices',
    //       url: 'https://www.android.com/',
    //       packageName: 'com.android.chrome',
    //       webviewPageId: '0'
    //   }
    // ]
    //
    // For iOS, the context will be 'WEBVIEW_{number}'
    await driver.getContexts({returnDetailedContexts: true})
    // Returns: [
    //   { id: 'NATIVE_APP' },
    //   {
    //       id: 'WEBVIEW_86150.1',
    //       title: 'WebdriverIO · Next-gen browser and mobile automation test framework for Node.js | WebdriverIO',
    //       url: 'https://webdriver.io/',
    //       bundleId: 'org.reactjs.native.example.wdiodemoapp'
    //   },
    //   {
    //       id: 'WEBVIEW_86152.1',
    //       title: 'Apple',
    //       url: 'https://www.apple.com/',
    //       bundleId: 'com.apple.mobilesafari'
    //   }
    // ]
})
```

description.data.test.js

```
it('should return Android description data for the webview', async () => {
    // For Android
    await driver.getContexts({returnDetailedContexts: true, returnAndroidDescriptionData: true})
    // Returns [
    //   { id: 'NATIVE_APP' },
    //   {
    //       androidWebviewData: {
    //          // Indicates whether the web page is currently attached to a web view.
    //          // `true` means the page is attached and likely active, `false` indicates it is not.
    //          attached: true,
    //          // Indicates whether the web page is empty or not. An empty page typically means that
    //          // there is no significant content loaded in it. `true` indicates the page is empty,
    //          // `false` indicates it has content.
    //          empty: false,
    //          // Indicates whether the page has never been attached to a web view. If `true`, the
    //          // page has never been attached, which could indicate a new or unused page. If `false`,
    //          // the page has been attached at some point.
    //          neverAttached: false,
    //          // Indicates whether the web page is visible on the screen. `true` means the page is
    //          // visible to the user, `false` means it is not.
    //          visible: true,
    //          // This data can be super useful to determine where on the screen the webview is located
    //          // and can come in handy when you want to interact with elements on the screen based on
    //          // coordinates based on the top-left corner of the screen
    //          screenX: 0,
    //          screenY: 151,
    //          height: 2589,
    //          width: 1344
    //       },
    //       id: 'WEBVIEW_com.wdiodemoapp',
    //       title: 'WebdriverIO · Next-gen browser and mobile automation test framework for Node.js | WebdriverIO',
    //       url: 'https://webdriver.io/',
    //       packageName: 'com.wdiodemoapp',
    //       webviewPageId: '58B0AA2DBBBBBE9008C35AE42385BB0D'
    //   }
    // ]
})

wait.for.webview.test.js
t('should wait for webview to become available before retrieving contexts', async () => {
   // For Android
   await driver.getContexts({
       returnDetailedContexts: true,
       // Wait for webview to become available at the Appium level before WebdriverIO's retry logic
       waitForWebviewMs: 3000,  // Wait 3 seconds for webview to become available
   })
)
```

## Support[​](#support "Direct link to Support")

![Support for ios](data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTYuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+CjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iRWJlbmVfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiCgkgd2lkdGg9IjQ5Ni4yNTVweCIgaGVpZ2h0PSI2MDguNzI4cHgiIHZpZXdCb3g9IjAgMCA0OTYuMjU1IDYwOC43MjgiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDQ5Ni4yNTUgNjA4LjcyODsiCgkgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxwYXRoIHN0eWxlPSJmaWxsOiM5OTk5OTk7IiBkPSJNMjczLjgxLDUyLjk3M0MzMTMuODA2LDAuMjU3LDM2OS40MSwwLDM2OS40MSwwczguMjcxLDQ5LjU2Mi0zMS40NjMsOTcuMzA2CgljLTQyLjQyNiw1MC45OC05MC42NDksNDIuNjM4LTkwLjY0OSw0Mi42MzhTMjM4LjI0Myw5OS44NSwyNzMuODEsNTIuOTczeiIvPgo8cGF0aCBzdHlsZT0iZmlsbDojOTk5OTk5OyIgZD0iTTI1Mi4zODUsMTc0LjY2MmMyMC41NzYsMCw1OC43NjQtMjguMjg0LDEwOC40NzEtMjguMjg0Yzg1LjU2MiwwLDExOS4yMjIsNjAuODgzLDExOS4yMjIsNjAuODgzCglzLTY1LjgzMywzMy42NTktNjUuODMzLDExNS4zMzFjMCw5Mi4xMzMsODIuMDEsMTIzLjg4NSw4Mi4wMSwxMjMuODg1cy01Ny4zMjgsMTYxLjM1Ny0xMzQuNzYyLDE2MS4zNTcKCWMtMzUuNTY1LDAtNjMuMjE1LTIzLjk2Ny0xMDAuNjg4LTIzLjk2N2MtMzguMTg4LDAtNzYuMDg0LDI0Ljg2MS0xMDAuNzY2LDI0Ljg2MUM4OS4zMyw2MDguNzMsMCw0NTUuNjY2LDAsMzMyLjYyOAoJYzAtMTIxLjA1Miw3NS42MTItMTg0LjU1NCwxNDYuNTMzLTE4NC41NTRDMTkyLjYzOCwxNDguMDc0LDIyOC40MTYsMTc0LjY2MiwyNTIuMzg1LDE3NC42NjJ6Ii8+Cjwvc3ZnPgo=) ![Support for android](/assets/images/android-d941e94d5839760141de31c8446b67ce.svg)

**Supported platforms:** iOS, Android

note

Refer to the official [Appium driver documentation](https://appium.io/docs/en/latest/ecosystem/) to see which driver versions support this command.
