webdriverio 9.6.3 → 9.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -47,4 +47,7 @@ export * from './browser/waitUntil.js';
47
47
  */
48
48
  export * from './mobile/swipe.js';
49
49
  export * from './mobile/tap.js';
50
+ export * from './mobile/getContext.js';
51
+ export * from './mobile/getContexts.js';
52
+ export * from './mobile/switchContext.js';
50
53
  //# sourceMappingURL=browser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/commands/browser.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAA;AAC/B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,qBAAqB,CAAA;AACnC,cAAc,sBAAsB,CAAA;AACpC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,mBAAmB,CAAA;AACjC,cAAc,uBAAuB,CAAA;AACrC,cAAc,sBAAsB,CAAA;AACpC,cAAc,oBAAoB,CAAA;AAClC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,2BAA2B,CAAA;AACzC,cAAc,sBAAsB,CAAA;AACpC,cAAc,sBAAsB,CAAA;AACpC,cAAc,2BAA2B,CAAA;AACzC,cAAc,yBAAyB,CAAA;AACvC,cAAc,2BAA2B,CAAA;AACzC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,mBAAmB,CAAA;AACjC,cAAc,mBAAmB,CAAA;AACjC,cAAc,2BAA2B,CAAA;AACzC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,wBAAwB,CAAA;AACtC,cAAc,oBAAoB,CAAA;AAClC,cAAc,sBAAsB,CAAA;AACpC,cAAc,qBAAqB,CAAA;AACnC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,sBAAsB,CAAA;AACpC,cAAc,sBAAsB,CAAA;AACpC,cAAc,kCAAkC,CAAA;AAChD,cAAc,6BAA6B,CAAA;AAC3C,cAAc,qBAAqB,CAAA;AACnC,cAAc,yBAAyB,CAAA;AACvC,cAAc,yBAAyB,CAAA;AACvC,cAAc,0BAA0B,CAAA;AACxC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,2BAA2B,CAAA;AACzC,cAAc,0BAA0B,CAAA;AACxC,cAAc,uBAAuB,CAAA;AACrC,cAAc,0BAA0B,CAAA;AACxC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,0BAA0B,CAAA;AACxC,cAAc,yBAAyB,CAAA;AACvC,cAAc,kBAAkB,CAAA;AAChC,cAAc,wBAAwB,CAAA;AACtC;;GAEG;AACH,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA"}
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/commands/browser.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAA;AAC/B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,qBAAqB,CAAA;AACnC,cAAc,sBAAsB,CAAA;AACpC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,mBAAmB,CAAA;AACjC,cAAc,uBAAuB,CAAA;AACrC,cAAc,sBAAsB,CAAA;AACpC,cAAc,oBAAoB,CAAA;AAClC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,2BAA2B,CAAA;AACzC,cAAc,sBAAsB,CAAA;AACpC,cAAc,sBAAsB,CAAA;AACpC,cAAc,2BAA2B,CAAA;AACzC,cAAc,yBAAyB,CAAA;AACvC,cAAc,2BAA2B,CAAA;AACzC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,mBAAmB,CAAA;AACjC,cAAc,mBAAmB,CAAA;AACjC,cAAc,2BAA2B,CAAA;AACzC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,wBAAwB,CAAA;AACtC,cAAc,oBAAoB,CAAA;AAClC,cAAc,sBAAsB,CAAA;AACpC,cAAc,qBAAqB,CAAA;AACnC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,sBAAsB,CAAA;AACpC,cAAc,sBAAsB,CAAA;AACpC,cAAc,kCAAkC,CAAA;AAChD,cAAc,6BAA6B,CAAA;AAC3C,cAAc,qBAAqB,CAAA;AACnC,cAAc,yBAAyB,CAAA;AACvC,cAAc,yBAAyB,CAAA;AACvC,cAAc,0BAA0B,CAAA;AACxC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,2BAA2B,CAAA;AACzC,cAAc,0BAA0B,CAAA;AACxC,cAAc,uBAAuB,CAAA;AACrC,cAAc,0BAA0B,CAAA;AACxC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,0BAA0B,CAAA;AACxC,cAAc,yBAAyB,CAAA;AACvC,cAAc,kBAAkB,CAAA;AAChC,cAAc,wBAAwB,CAAA;AACtC;;GAEG;AACH,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,wBAAwB,CAAA;AACtC,cAAc,yBAAyB,CAAA;AACvC,cAAc,2BAA2B,CAAA"}
@@ -0,0 +1,107 @@
1
+ import type { DetailedContext } from '@wdio/protocols';
2
+ /**
3
+ * Retrieve the context of the current session.
4
+ *
5
+ * This method enhances the default Appium `context`/WebdriverIO `getContext` command by providing an option to
6
+ * return detailed context information, making it easier to work with hybrid apps that use webviews.
7
+ *
8
+ * ### How Contexts Work
9
+ * Refer to [Hybrid Apps documentation](/docs/api/mobile#hybrid-apps) for more information. Below is an explanation of the challenges associated with the `getContext` command:
10
+ *
11
+ * #### For Android:
12
+ * - Webviews can contain multiple pages (like browser tabs), and identifying the correct page requires additional metadata
13
+ * such as `title` or `url`.
14
+ * - The default Appium methods only provide basic context names (e.g., `WEBVIEW_{packageName}`) without detailed information
15
+ * about the pages inside the webview.
16
+ *
17
+ * #### For iOS:
18
+ * - Each webview is identified by a generic `WEBVIEW_{id}` string, which doesn’t indicate its contents or the app screen
19
+ * it belongs to.
20
+ *
21
+ * ### Why Use This Method?
22
+ * - **Default Behavior**:
23
+ * - Returns the current context as a string (e.g., `NATIVE_APP` or `WEBVIEW_{id}`).
24
+ * - **Detailed Context**:
25
+ * - When `returnDetailedContext` is enabled, retrieves metadata such as:
26
+ * - **Android**: `packageName`, `title`, `url`, and `webviewPageId`.
27
+ * - **iOS**: `bundleId`, `title`, and `url`.
28
+ * - **Android-Specific Options**:
29
+ * - Retry intervals and timeouts can be customized to handle delays in webview initialization.
30
+ *
31
+ * :::info Notes and Limitations
32
+ *
33
+ * - If `returnDetailedContext` is not enabled, the method behaves like the default Appium `getContext` method.
34
+ * - If you want to use the "default" Appium `context` method, you can use the `driver.getAppiumContext()` method, see
35
+ * also the [Appium Contexts](/docs/api/appium#getappiumcontext) command.
36
+ * - **Android:** Android-specific options (`androidWebviewConnectionRetryTime` and `androidWebviewConnectTimeout`) have no effect on iOS.
37
+ * - Logs warnings if multiple or no detailed contexts are found:
38
+ * - `We found more than 1 detailed context for the current context '{context}'. We will return the first context.`
39
+ * - `We did not get back any detailed context for the current context '{context}'. We will return the current context as a string.`
40
+ *
41
+ * :::
42
+ *
43
+ * <example>
44
+ :default.test.js
45
+ it('should return the current context with the default Appium `context` method', async () => {
46
+ // For Android
47
+ await driver.getContext()
48
+ // Returns 'WEBVIEW_com.wdiodemoapp' or 'NATIVE_APP'
49
+ //
50
+ // For iOS, the context will be 'WEBVIEW_{number}'
51
+ await driver.getContext()
52
+ // Returns 'WEBVIEW_94703.19' or 'NATIVE_APP'
53
+ })
54
+ * </example>
55
+ *
56
+ * <example>
57
+ :detailed.test.js
58
+ it('should return the context of the current session with more detailed information', async () => {
59
+ // For Android
60
+ await driver.getContext({ returnDetailedContext: true})
61
+ // Returns or `NATIVE_APP`, or
62
+ // {
63
+ // id: 'WEBVIEW_com.wdiodemoapp',
64
+ // title: 'WebdriverIO · Next-gen browser and mobile automation test framework for Node.js | WebdriverIO',
65
+ // url: 'https://webdriver.io/',
66
+ // packageName: 'com.wdiodemoapp',
67
+ // webviewPageId: '5C0425CF67E9B169245F48FF21172912'
68
+ // }
69
+ //
70
+ // For iOS, the context will be 'WEBVIEW_{number}'
71
+ await driver.getContext({ returnDetailedContext: true})
72
+ // Returns or `NATIVE_APP`, or
73
+ // {
74
+ // id: 'WEBVIEW_64981.1',
75
+ // title: 'WebdriverIO · Next-gen browser and mobile automation test framework for Node.js | WebdriverIO',
76
+ // url: 'https://webdriver.io/',
77
+ // bundleId: 'org.reactjs.native.example.wdiodemoapp'
78
+ // }
79
+ })
80
+ * </example>
81
+ *
82
+ * <example>
83
+ :customize.retry.test.js
84
+ it('should be able to cusomize the retry intervals and timeouts to handle delayed webview initialization', async () => {
85
+ // For Android
86
+ await driver.getContext({
87
+ returnDetailedContext: true,
88
+ // NOTE: The following options are Android-specific
89
+ // For Android we might need to wait a bit longer to connect to the webview, so we can provide some additional options
90
+ androidWebviewConnectionRetryTime: 1*1000, // Retry every 1 second
91
+ androidWebviewConnectTimeout: 10*1000, // Timeout after 10 seconds
92
+ })
93
+ })
94
+ * </example>
95
+ *
96
+ * @param {GetContextsOptions=} options The `getContext` options (optional)
97
+ * @param {boolean=} options.returnDetailedContext By default, we only return the context name based on the default Appium `context` API, which is only a string. If you want to get back detailed context information, set this to `true`. Default is `false` (optional).
98
+ * @param {number=} options.androidWebviewConnectionRetryTime The time in milliseconds to wait between each retry to connect to the webview. Default is `500` ms (optional). <br /><strong>ANDROID-ONLY</strong>
99
+ * @param {number=} options.androidWebviewConnectTimeout The maximum amount of time in milliseconds to wait for a web view page to be detected. Default is `5000` ms (optional). <br /><strong>ANDROID-ONLY</strong>
100
+ * @skipUsage
101
+ */
102
+ export declare function getContext(this: WebdriverIO.Browser, options?: {
103
+ returnDetailedContext?: boolean;
104
+ androidWebviewConnectionRetryTime?: number;
105
+ androidWebviewConnectTimeout?: number;
106
+ }): Promise<string | DetailedContext>;
107
+ //# sourceMappingURL=getContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getContext.d.ts","sourceRoot":"","sources":["../../../src/commands/mobile/getContext.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAW,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAM/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmGG;AACH,wBAAsB,UAAU,CAC5B,IAAI,EAAE,WAAW,CAAC,OAAO,EACzB,OAAO,CAAC,EAAE;IACN,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,iCAAiC,CAAC,EAAE,MAAM,CAAC;IAC3C,4BAA4B,CAAC,EAAE,MAAM,CAAC;CACzC,GACF,OAAO,CAAC,MAAM,GAAG,eAAe,CAAC,CAgBnC"}
@@ -0,0 +1,158 @@
1
+ import type { AppiumDetailedCrossPlatformContexts, GetContextsOptions } from '../../types.js';
2
+ import type { Context } from '@wdio/protocols';
3
+ /**
4
+ * The WebdriverIO `getContexts` method is an improved version of the default Appium `contexts`
5
+ * (and the previous WebdriverIO `getContexts`) command. It provides detailed and actionable information
6
+ * about available contexts in a mobile app session, addressing the limitations of the default Appium methods.
7
+ *
8
+ * ### How Webviews Work and Why This Method Helps
9
+ * For more details, refer to the [Hybrid Apps documentation](/docs/api/mobile#hybrid-apps). Below is a summary of the challenges addressed by the `getContexts` command:
10
+ *
11
+ * #### Android Challenges
12
+ * - A single webview (e.g., `WEBVIEW_{packageName}`) may contain multiple pages (similar to browser tabs).
13
+ * - The default Appium methods do not include details about these pages, such as their `title`, `url`, or visibility,
14
+ * making it hard to identify the correct page and leading to potential flakiness.
15
+ *
16
+ * #### iOS Challenges
17
+ * - The default Appium method only returns generic webview IDs (e.g., `WEBVIEW_{id}`) without any additional metadata.
18
+ * - This makes it difficult to determine which webview corresponds to the target app screen.
19
+ *
20
+ * The enhanced `getContexts` method solves these issues by returning detailed context objects, which include:
21
+ * - **For Android:** `title`, `url`, `packageName`, `webviewPageId`, and layout details (`screenX`, `screenY`, `width`, and `height`).
22
+ * - **For iOS:** `bundleId`, `title`, and `url`.
23
+ *
24
+ * These enhancements make debugging and interacting with hybrid apps more reliable.
25
+ *
26
+ * ### Why Use This Method?
27
+ * By default, the Appium `contexts` method returns only an array of strings representing available contexts:
28
+ * - **For Android:** `['NATIVE_APP', 'WEBVIEW_com.wdiodemoapp', ...]`
29
+ * - **For iOS:** `['NATIVE_APP', 'WEBVIEW_84392.1', ...]`
30
+ *
31
+ * While sufficient for simple scenarios, these default responses lack critical metadata for hybrid app testing:
32
+ * - **For Android:** The lack of page-specific metadata makes it challenging to interact with the correct webview.
33
+ * - **For iOS:** Generic webview IDs provide no insight into the content or app screen they represent.
34
+ *
35
+ * The enhanced `getContexts` method provides:
36
+ * - Detailed metadata for both Android and iOS.
37
+ * - Options to filter and customize the returned contexts for better targeting and interaction.
38
+ *
39
+ * :::info Notes and Limitations
40
+ *
41
+ * - 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.
42
+ * - If you do not specify the `returnDetailedContexts` option, the method behaves like the default Appium `contexts` method, returning a simple context array.
43
+ * - To use the "default" Appium `contexts` method, use `driver.getAppiumContexts()`. For more information, see the [Appium Contexts documentation](/docs/api/appium#getappiumcontexts).
44
+ *
45
+ * #### Android Webviews:
46
+ * - Metadata such as `androidWebviewData` is available only when `returnAndroidDescriptionData` is `true`.
47
+ * - 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.
48
+ *
49
+ * :::
50
+ *
51
+ * <example>
52
+ :example.test.js
53
+ it('should return all contexts in the current session with the default Appium `contexts`-method.', async () => {
54
+ // For Android
55
+ await driver.getContexts()
56
+ // Returns ['NATIVE_APP', 'WEBVIEW_com.wdiodemoapp', ...]
57
+ //
58
+ // For iOS, the context will be 'WEBVIEW_{number}'
59
+ await driver.getContexts()
60
+ // Returns [ 'NATIVE_APP', 'WEBVIEW_84392.1', ... ]
61
+ })
62
+ * </example>
63
+ *
64
+ * <example>
65
+ :detailed.test.js
66
+ it('should return all contexts in the current session with detailed info.', async () => {
67
+ // For Android
68
+ await driver.getContexts({returnDetailedContexts: true})
69
+ // Returns [
70
+ // { id: 'NATIVE_APP' },
71
+ // {
72
+ // id: 'WEBVIEW_com.wdiodemoapp',
73
+ // title: 'WebdriverIO · Next-gen browser and mobile automation test framework for Node.js | WebdriverIO',
74
+ // url: 'https://webdriver.io/',
75
+ // packageName: 'com.wdiodemoapp',
76
+ // webviewPageId: '58B0AA2DBBBBBE9008C35AE42385BB0D'
77
+ // },
78
+ // {
79
+ // id: 'WEBVIEW_chrome',
80
+ // title: 'Android | Get more done with Google on Android-phones and devices',
81
+ // url: 'https://www.android.com/',
82
+ // packageName: 'com.android.chrome',
83
+ // webviewPageId: '0'
84
+ // }
85
+ // ]
86
+ //
87
+ // For iOS, the context will be 'WEBVIEW_{number}'
88
+ await driver.getContexts({returnDetailedContexts: true})
89
+ // Returns: [
90
+ // { id: 'NATIVE_APP' },
91
+ // {
92
+ // id: 'WEBVIEW_86150.1',
93
+ // title: 'WebdriverIO · Next-gen browser and mobile automation test framework for Node.js | WebdriverIO',
94
+ // url: 'https://webdriver.io/',
95
+ // bundleId: 'org.reactjs.native.example.wdiodemoapp'
96
+ // },
97
+ // {
98
+ // id: 'WEBVIEW_86152.1',
99
+ // title: 'Apple',
100
+ // url: 'https://www.apple.com/',
101
+ // bundleId: 'com.apple.mobilesafari'
102
+ // }
103
+ // ]
104
+ })
105
+ * </example>
106
+ *
107
+ * <example>
108
+ :description.data.test.js
109
+ it('should return Android description data for the webview', async () => {
110
+ // For Android
111
+ await driver.getContexts({returnDetailedContexts: true})
112
+ // Returns [
113
+ // { id: 'NATIVE_APP' },
114
+ // {
115
+ // androidWebviewData: {
116
+ // // Indicates whether the web page is currently attached to a web view.
117
+ // // `true` means the page is attached and likely active, `false` indicates it is not.
118
+ // attached: true,
119
+ // // Indicates whether the web page is empty or not. An empty page typically means that
120
+ // // there is no significant content loaded in it. `true` indicates the page is empty,
121
+ // // `false` indicates it has content.
122
+ // empty: false,
123
+ // // Indicates whether the page has never been attached to a web view. If `true`, the
124
+ // // page has never been attached, which could indicate a new or unused page. If `false`,
125
+ // // the page has been attached at some point.
126
+ // neverAttached: false,
127
+ // // Indicates whether the web page is visible on the screen. `true` means the page is
128
+ // // visible to the user, `false` means it is not.
129
+ // visible: true,
130
+ // // This data can be super useful to determine where on the screen the webview is located
131
+ // // and can come in handy when you want to interact with elements on the screen based on
132
+ // // coordinates based on the top-left corner of the screen
133
+ // screenX: 0,
134
+ // screenY: 151,
135
+ // height: 2589,
136
+ // width: 1344
137
+ // },
138
+ // id: 'WEBVIEW_com.wdiodemoapp',
139
+ // title: 'WebdriverIO · Next-gen browser and mobile automation test framework for Node.js | WebdriverIO',
140
+ // url: 'https://webdriver.io/',
141
+ // packageName: 'com.wdiodemoapp',
142
+ // webviewPageId: '58B0AA2DBBBBBE9008C35AE42385BB0D'
143
+ // }
144
+ // ]
145
+ })
146
+ * </example>
147
+ *
148
+ * @param {GetContextsOptions=} options The `getContexts` options (optional)
149
+ * @param {boolean=} options.returnDetailedContexts 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).
150
+ * @param {number=} options.androidWebviewConnectionRetryTime The time in milliseconds to wait between each retry to connect to the webview. Default is `500` ms (optional). <br /><strong>ANDROID-ONLY</strong>
151
+ * @param {number=} options.androidWebviewConnectTimeout The maximum amount of time in milliseconds to wait for a web view page to be detected. Default is `5000` ms (optional). <br /><strong>ANDROID-ONLY</strong>
152
+ * @param {boolean=} options.filterByCurrentAndroidApp 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 /><strong>NOTE:</strong> Be aware that you can also NOT find any Webview based on this "restriction". <br /><strong>ANDROID-ONLY</strong>
153
+ * @param {boolean=} options.isAndroidWebviewVisible 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 /><strong>ANDROID-ONLY</strong>
154
+ * @param {boolean=} options.returnAndroidDescriptionData 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 /><strong>ANDROID-ONLY</strong>
155
+ * @skipUsage
156
+ */
157
+ export declare function getContexts(this: WebdriverIO.Browser, options?: GetContextsOptions): Promise<Context[] | AppiumDetailedCrossPlatformContexts>;
158
+ //# sourceMappingURL=getContexts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getContexts.d.ts","sourceRoot":"","sources":["../../../src/commands/mobile/getContexts.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAA0B,mCAAmC,EAAE,kBAAkB,EAAsB,MAAM,gBAAgB,CAAA;AACzI,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAI9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyJG;AACH,wBAAsB,WAAW,CAC7B,IAAI,EAAE,WAAW,CAAC,OAAO,EACzB,OAAO,CAAC,EAAE,kBAAkB,GAC7B,OAAO,CAAC,OAAO,EAAE,GAAG,mCAAmC,CAAC,CAsB1D"}
@@ -0,0 +1,112 @@
1
+ import type { SwitchContextOptions } from '../../types.js';
2
+ /**
3
+ * Switch to a specific context using a given Webview `name`, `title`, or `url`.
4
+ *
5
+ * This method enhances the default Appium `context` command by offering more flexibility and precision
6
+ * for switching between native and webview contexts in hybrid mobile applications.
7
+ *
8
+ * ### How Contexts Work
9
+ * For an overview of Hybrid Apps and webviews, refer to the [Hybrid Apps documentation](/docs/api/mobile#hybrid-apps).
10
+ * Below is a summary of how the `switchContext` command addresses common challenges:
11
+ *
12
+ * #### Android Challenges
13
+ * - Webviews often contain multiple pages (similar to browser tabs). Identifying the correct page requires additional
14
+ * metadata such as `title` or `url`, which is not provided by default Appium methods.
15
+ * - Default Appium methods return only basic context names (e.g., `WEBVIEW_{packageName}`) without details about
16
+ * the content or pages within the webview.
17
+ * - Switching contexts on Android involves two steps, which are handled automatically by this method:
18
+ * 1. Switch to the Webview context using `WEBVIEW_{packageName}`.
19
+ * 2. Select the appropriate page within the Webview using the `switchToWindow` method.
20
+ *
21
+ * #### iOS Challenges
22
+ * - Webviews are identified by generic IDs (e.g., `WEBVIEW_{id}`), which do not provide information about the content
23
+ * or the app screen they correspond to.
24
+ * - Determining the correct webview for interaction often requires trial and error.
25
+ *
26
+ * The `switchContext` method simplifies this process by retrieving detailed metadata (e.g., `title`, `url`, and visibility)
27
+ * to ensure accurate and reliable context switching.
28
+ *
29
+ * ### Why Use This Method?
30
+ * - **Simplified Switching**: If you know the `title` or `url` of the desired webview, this method eliminates the need for
31
+ * additional calls to `getContexts` or combining multiple methods like `switchContext({id})` and `getTitle()`.
32
+ * - **Automatic Context Matching**: Finds the best match for a context based on:
33
+ * - Platform-specific identifiers (`bundleId` for iOS, `packageName` for Android).
34
+ * - Exact or partial matches for `title` or `url` (supports both strings and regular expressions).
35
+ * - Android-specific checks to ensure webviews are attached and visible.
36
+ * - **Fine-Grained Control**: Custom retry intervals and timeouts (Android-only) allow you to handle delays in webview initialization.
37
+ * - **Default Appium Method Access**: If needed, you can use the default Appium `switchContext` command via `driver.switchAppiumContext()`.
38
+ *
39
+ * :::info Notes and Limitations
40
+ *
41
+ * - If the `title` or `url` of the desired webview is known, this method can automatically locate and switch to the matching context without additional `getContexts` calls.
42
+ * - Android-specific options like `androidWebviewConnectionRetryTime` and `androidWebviewConnectTimeout` are not applicable to iOS.
43
+ * - Logs reasons for context-matching failures to assist with debugging.
44
+ * - When using an object as input, either `title` or `url` is required.
45
+ *
46
+ * :::
47
+ *
48
+ * <example>
49
+ :example.test.js
50
+ it('should switch to a webview by name and uses the default Appium `context`-method', async () => {
51
+ // For Android, the context will be '`WEBVIEW_{packageName}`'
52
+ await driver.switchContext('WEBVIEW_com.wdiodemoapp')
53
+ // For iOS, the context will be 'WEBVIEW_{number}'
54
+ await driver.switchContext('WEBVIEW_94703.19')
55
+ })
56
+ * </example>
57
+ *
58
+ * <example>
59
+ :exact.title.test.js
60
+ it('should switch to a webview and match a webview based on an EXACT match of the `title` of the webview', async () => {
61
+ await driver.switchContext({
62
+ // In this case the title needs to be an exact match
63
+ title: 'Webview Title',
64
+ })
65
+ })
66
+ * </example>
67
+ *
68
+ * <example>
69
+ :exact.url.test.js
70
+ it('should switch to a webview and match a webview based on an EXACT match of the `title` of the webview', async () => {
71
+ await driver.switchContext({
72
+ // In this case the url needs to be an exact match
73
+ url: 'https://webdriver.io',
74
+ })
75
+ })
76
+ * </example>
77
+ *
78
+ * <example>
79
+ :regex.title.url.test.js
80
+ it('should switch to a webview and match a webview based on regex match of the `title` and `url` of the webview', async () => {
81
+ await driver.switchContext({
82
+ // The title should NOT end with 'foo'
83
+ title: /^(?!.*foo$)/,
84
+ // Matches any string that contains the substring `docs/api/mobile/switchContext`
85
+ url: /.*docs\/api\/mobile\/switchContext/,
86
+ })
87
+ })
88
+ * </example>
89
+ *
90
+ * <example>
91
+ :android.context.waits.test.js
92
+ it('should switch to a webview for Android but wait longer to connect and find a webview based on provided options', async () => {
93
+ await driver.switchContext({
94
+ // In this case the title need to be an exact match
95
+ title: 'Webview Title',
96
+ // For Android we might need to wait a bit longer to connect to the webview, so we can provide some additional options
97
+ androidWebviewConnectionRetryTime: 1*1000, // Retry every 1 second
98
+ androidWebviewConnectTimeout: 10*1000, // Timeout after 10 seconds
99
+ })
100
+ })
101
+ * </example>
102
+ *
103
+ * @param {string|SwitchContextOptions} context The name of the context to switch to. An object with more context options can be provided.
104
+ * @param {SwitchContextOptions} options switchContext command options
105
+ * @param {string|RegExp=} options.title The title of the page to switch to. This will be the content of the title-tag of a webviewpage. You can use a string that needs to fully match or or a regular expression.<br /><strong>IMPORTANT:</strong> When you use options then or the `title` or the `url` property is required.
106
+ * @param {string|RegExp=} options.url The url of the page to switch to. This will be the `url` of a webviewpage. You can use a string that needs to fully match or or a regular expression.<br /><strong>IMPORTANT:</strong> When you use options then or the `title` or the `url` property is required.
107
+ * @param {number=} options.androidWebviewConnectionRetryTime The time in milliseconds to wait between each retry to connect to the webview. Default is `500` ms (optional). <br /><strong>ANDROID-ONLY</strong> and will only be used when a `title` or `url` is provided.
108
+ * @param {number=} options.androidWebviewConnectTimeout The maximum amount of time in milliseconds to wait for a web view page to be detected. Default is `5000` ms (optional). <br /><strong>ANDROID-ONLY</strong> and will only be used when a `title` or `url` is provided.
109
+ * @skipUsage
110
+ */
111
+ export declare function switchContext(this: WebdriverIO.Browser, options: string | SwitchContextOptions): Promise<void>;
112
+ //# sourceMappingURL=switchContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"switchContext.d.ts","sourceRoot":"","sources":["../../../src/commands/mobile/switchContext.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAmF,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAI3I;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4GG;AACH,wBAAsB,aAAa,CAC/B,IAAI,EAAE,WAAW,CAAC,OAAO,EACzB,OAAO,EAAE,MAAM,GAAG,oBAAoB,iBAuBzC"}
@@ -3,4 +3,7 @@ export * from './mobile/longPress.js';
3
3
  export * from './mobile/pinch.js';
4
4
  export * from './mobile/tap.js';
5
5
  export * from './mobile/zoom.js';
6
+ export * from './mobile/getContext.js';
7
+ export * from './mobile/getContexts.js';
8
+ export * from './mobile/switchContext.js';
6
9
  //# sourceMappingURL=mobile.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mobile.d.ts","sourceRoot":"","sources":["../../src/commands/mobile.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAA;AACvC,cAAc,uBAAuB,CAAA;AACrC,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,kBAAkB,CAAA"}
1
+ {"version":3,"file":"mobile.d.ts","sourceRoot":"","sources":["../../src/commands/mobile.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAA;AACvC,cAAc,uBAAuB,CAAA;AACrC,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,kBAAkB,CAAA;AAChC,cAAc,wBAAwB,CAAA;AACtC,cAAc,yBAAyB,CAAA;AACvC,cAAc,2BAA2B,CAAA"}
package/build/index.cjs CHANGED
@@ -90,14 +90,14 @@ exports.Key = {
90
90
  ZenkakuHankaku: "\uE040"
91
91
  };
92
92
  exports.remote = async function(params, remoteModifier) {
93
- const { remote } = await import("./index.js");
93
+ const { remote } = await import("./node.js");
94
94
  return remote(params, remoteModifier);
95
95
  };
96
96
  exports.attach = async function(attachOptions) {
97
- const { attach } = await import("./index.js");
97
+ const { attach } = await import("./node.js");
98
98
  return attach(attachOptions);
99
99
  };
100
100
  exports.multiremote = async function(params, { automationProtocol } = {}) {
101
- const { multiremote } = await import("./index.js");
101
+ const { multiremote } = await import("./node.js");
102
102
  return multiremote(params, { automationProtocol });
103
103
  };