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
For more details, refer to the Hybrid Apps documentation. Below is a summary of the challenges addressed by the getContexts
command:
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
- 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
, andheight
). - For iOS:
bundleId
,title
, andurl
.
These enhancements make debugging and interacting with hybrid apps more reliable.
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.
- 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 Appiumcontexts
method, returning a simple context array. - To use the "default" Appium
contexts
method, usedriver.getAppiumContexts()
. For more information, see the Appium Contexts documentation.
Android Webviews:
- Metadata such as
androidWebviewData
is available only whenreturnAndroidDescriptionData
istrue
. - 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 incorrectwebviewPageId
(e.g.,0
) may be returned.
Parameters
Name | Type | Details |
---|---|---|
options optional | GetContextsOptions | The getContexts options (optional) |
options.returnDetailedContexts 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 optional | number | The time in milliseconds to wait between each retry to connect to the webview. Default is 500 ms (optional). ANDROID-ONLY |
options.androidWebviewConnectTimeout optional | number | The maximum amount of time in milliseconds to wait for a web view page to be detected. Default is 5000 ms (optional). ANDROID-ONLY |
options.filterByCurrentAndroidApp 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). NOTE: Be aware that you can also NOT find any Webview based on this "restriction". ANDROID-ONLY |
options.isAndroidWebviewVisible 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 . ANDROID-ONLY |
options.returnAndroidDescriptionData 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). By enabling this option you will get extra data in the response, see the description.data.test.js for more information. ANDROID-ONLY |
Examples
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', ... ]
})
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'
// }
// ]
})
it('should return Android description data for the webview', async () => {
// For Android
await driver.getContexts({returnDetailedContexts: 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'
// }
// ]
})