appium-novawindows2-driver 0.1.13 → 0.2.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.
package/README.md CHANGED
@@ -1,557 +1,530 @@
1
- NovaWindows2 Driver
2
- ===================
3
-
4
- NovaWindows2 Driver is a custom Appium driver designed to tackle the limitations of existing Windows automation solutions like WinAppDriver. NovaWindows2 Driver supports testing Universal Windows Platform (UWP), Windows Forms (WinForms), Windows Presentation Foundation (WPF), and Classic Windows (Win32) apps on Windows 10 PCs. Built to improve performance and reliability for traditional desktop applications, it offers:
5
-
6
- Faster XPath locator performance Reduces element lookup times, even in complex UIs.
7
- RawView element supportAccess elements typically hidden from the default ControlView/ContentView.
8
- Enhanced text input handlingSolves keyboard layout issues while improving input speed.
9
- Platform-specific commandsSupports direct window manipulation, advanced UI interactions, and more.
10
- It’s designed to handle real-world scenarios where traditional drivers fall short from tricky dropdowns to missing elements and unreliable clicks — making it an ideal choice for automating legacy Windows apps.
11
-
12
- > **Note**
13
- >
14
- > This driver is built for Appium 2/3 and is not compatible with Appium 1. To install
15
- > the driver, simply run:
16
- > `appium driver install --source=npm appium-novawindows2-driver`
17
-
18
-
19
- ## Usage
20
-
21
- Beside of standard Appium requirements NovaWindows2 Driver adds the following prerequisites:
22
-
23
- - Appium Windows Driver only supports Windows 10 and later as the host.
24
-
25
- > **Note**
26
- >
27
- > The driver currently uses a PowerShell session as a back-end, and
28
- > should not require Developer Mode to be on, or any other software.
29
- > There's a plan to update to a better, .NET-based backend for improved
30
- > realiability and better code and error management, as well as supporting
31
- > more features, that are currently not possible using PowerShell alone.
32
- > It is unlikely for the prerequisites to change, as this is one of the
33
- > main goals of NovaWindows2 driver – seamless setup on any PC.
34
-
35
- NovaWindows2 Driver supports the following capabilities:
36
-
37
- Capability Name | Description
38
- --- | ---
39
- platformName | Must be set to `Windows` (case-insensitive).
40
- automationName | Must be set to `NovaWindows2` (case-insensitive).
41
- smoothPointerMove | CSS-like easing function (including valid Bezier curve). This controls the smooth movement of the mouse for `delayBeforeClick` ms. Example: `ease-in`, `cubic-bezier(0.42, 0, 0.58, 1)`.
42
- delayBeforeClick | Time in milliseconds before a click is performed.
43
- delayAfterClick | Time in milliseconds after a click is performed.
44
- appTopLevelWindow | The handle of an existing application top-level window to attach to. It can be a number or string (not necessarily hexadecimal). Example: `12345`, `0x12345`.
45
- shouldCloseApp | Whether to close the window of the application in test after the session finishes. Default is `true`.
46
- appArguments | Optional string of arguments to pass to the app on launch.
47
- appWorkingDir | Optional working directory path for the application.
48
- prerun | An object containing either `script` or `command` key. The value of each key must be a valid PowerShell script or command to be executed prior to the WinAppDriver session startup. See [Power Shell commands execution](#power-shell-commands-execution) for more details. Example: `{script: 'Get-Process outlook -ErrorAction SilentlyContinue'}`
49
- postrun | An object containing either `script` or `command` key. The value of each key must be a valid PowerShell script or command to be executed after WinAppDriver session is stopped. See [Power Shell commands execution](#power-shell-commands-execution) for more details.
50
- isolatedScriptExecution | Whether PowerShell scripts are executed in an isolated session. Default is `false`.
51
-
52
- Please note that more capabilities will be added as the development of this driver progresses. Since it is still in its early stages, some features may be missing or subject to change. If you need a specific capability or encounter any issues, please feel free to open an issue.
53
-
54
- ## Example
55
-
56
- ```python
57
- # Python3 + PyTest
58
- import pytest
59
-
60
- from appium import webdriver
61
- from appium.options.windows import WindowsOptions
62
-
63
- def generate_options():
64
- uwp_options = WindowsOptions()
65
- # How to get the app ID for Universal Windows Apps (UWP):
66
- # https://www.securitylearningacademy.com/mod/book/view.php?id=13829&chapterid=678
67
- uwp_options.app = 'Microsoft.WindowsCalculator_8wekyb3d8bbwe!App'
68
- uwp_options.automation_name = 'NovaWindows2'
69
-
70
- classic_options = WindowsOptions()
71
- classic_options.app = 'C:\\Windows\\System32\\notepad.exe'
72
- classic_options.automation_name = 'NovaWindows2'
73
-
74
- use_existing_app_options = WindowsOptions()
75
- # Active window handles could be retrieved from any compatible UI inspector app:
76
- # https://docs.microsoft.com/en-us/windows/win32/winauto/inspect-objects
77
- # or https://accessibilityinsights.io/.
78
- # Also, it is possible to use the corresponding WinApi calls for this purpose:
79
- # https://referencesource.microsoft.com/#System/services/monitoring/system/diagnosticts/ProcessManager.cs,db7ac68b7cb40db1
80
- #
81
- # This capability could be used to create a workaround for UWP apps startup:
82
- # https://github.com/microsoft/WinAppDriver/blob/master/Samples/C%23/StickyNotesTest/StickyNotesSession.cs
83
- use_existing_app_options.app_top_level_window = hex(12345)
84
- use_existing_app_options.automation_name = 'NovaWindows2'
85
-
86
- return [uwp_options, classic_options, use_existing_app_options]
87
-
88
-
89
- @pytest.fixture(params=generate_options())
90
- def driver(request):
91
- drv = webdriver.Remote('http://127.0.0.1:4723', options=request.param)
92
- yield drv
93
- drv.quit()
94
-
95
-
96
- def test_app_source_could_be_retrieved(driver):
97
- assert len(driver.page_source) > 0
98
- ```
99
-
100
-
101
- ## Power Shell commands execution
102
-
103
- Just like in Appium Windows Driver (version 1.15.0 and above) there is a possibility to
104
- run custom Power Shell scriptsfrom your client code. This feature is potentially insecure
105
- and thus needs to beexplicitly enabled when executing the server by providing `power_shell`
106
- key to the listof enabled insecure features. Refer to [Appium Security document](https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/security.md) for more details.
107
- It is possible to ether execute a single Power Shell command or a whole script
108
- and get its stdout in response. If the script execution returns non-zero exit code then an exception
109
- is going to be thrown. The exception message will contain the actual stderr. Unlike, Appium Windows Driver,
110
- there is no difference if you paste the script with `command` or `script` argument. For ease of use, you can pass the script as a string when executing a PowerShell command directly via the driver. Note: This shorthand does not work when using the prerun or postrun capabilities, which require full object syntax.
111
- Here's an example code of how to control the Notepad process:
112
-
113
- ```java
114
- // java
115
- String psScript =
116
- "$sig = '[DllImport(\"user32.dll\")] public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);'\n" +
117
- "Add-Type -MemberDefinition $sig -name NativeMethods -namespace Win32\n" +
118
- "Start-Process Notepad\n" +
119
- "$hwnd = @(Get-Process Notepad)[0].MainWindowHandle\n" +
120
- "[Win32.NativeMethods]::ShowWindowAsync($hwnd, 2)\n" +
121
- "[Win32.NativeMethods]::ShowWindowAsync($hwnd, 4)\n" +
122
- "Stop-Process -Name Notepad";
123
- driver.executeScript("powerShell", psScript);
124
- ```
125
-
126
- Another example, which demonstrates how to use the command output:
127
-
128
- ```python
129
- # python
130
- cmd = 'Get-Process outlook -ErrorAction SilentlyContinue'
131
- proc_info = driver.execute_script('powerShell', cmd)
132
- if proc_info:
133
- print('Outlook is running')
134
- else:
135
- print('Outlook is not running')
136
- ```
137
-
138
- > **Note**
139
- >
140
- > NovaWindows Driver runs on a single PowerShell session,
141
- > therefore you may share variables between executed PowerShell
142
- > scripts. Unless the PowerShell session exits or crashes for some
143
- > reason, you should be able to reuse the variables that you create.
144
-
145
-
146
- ## Element Location
147
-
148
- Appium Windows Driver supports the same location strategies [the WinAppDriver supports](https://github.com/microsoft/WinAppDriver/blob/master/Docs/AuthoringTestScripts.md#supported-locators-to-find-ui-elements), but also includes Windows UIAutomation conditoons:
149
-
150
- Name | Description | Example
151
- --- | --- | ---
152
- accessibility id | This strategy is AutomationId attribute in inspect.exe | AppNameTitle
153
- class name | This strategy is ClassName attribute in inspect.exe | TextBlock
154
- id | This strategy is RuntimeId (decimal) attribute in inspect.exe | 42.333896.3.1
155
- name | This strategy is Name attribute in inspect.exe | Calculator
156
- tag name | This strategy is LocalizedControlType (upper camel case) attribute in inspect.exe since Appium Windows Driver 2.1.1 | Text
157
- xpath | This strategy allows to create custom XPath queries on any attribute exposed by inspect.exe. Only XPath 1.0 is supported | (//Button)[2]
158
- windows uiautomation | This strategy allows to create custom Windows UIAutomation conditions on any attribute exposed by inspect.exe. Both C# and PowerShell syntax is supported | new PropertyCondition(AutomationElement.HelpTextProperty, "Info")
159
-
160
- ## Platform-Specific Extensions
161
-
162
- Beside of standard W3C APIs the driver provides the below custom command extensions to execute platform specific scenarios. Use the following source code examples in order to invoke them from your client code:
163
-
164
- > **Note**
165
- >
166
- > In most cases, commands implemented in NovaWindows driver can be used
167
- > more intuitively by just the element as a second argument and the value
168
- > (if such is needed) as the thrid argument and so on. For example:
169
- > `driver.executeScript("windows: setValue", element, "valueToSet")` or
170
- > `driver.executeScript("windows: invoke", element)`. Commands that are created
171
- > as fallbacks to Appium Windows Driver should work as is. Open an issue if some
172
- > command that you need is missing or is not behaving as it should.
173
-
174
- ```java
175
- // Java 11+
176
- var result = driver.executeScript("windows: <methodName>", Map.of(
177
- "arg1", "value1",
178
- "arg2", "value2"
179
- // you may add more pairs if needed or skip providing the map completely
180
- // if all arguments are defined as optional
181
- ));
182
- ```
183
-
184
- ```js
185
- // WebdriverIO
186
- const result = await driver.executeScript('windows: <methodName>', [{
187
- arg1: "value1",
188
- arg2: "value2",
189
- }]);
190
- ```
191
-
192
- ```python
193
- # Python
194
- result = driver.execute_script('windows: <methodName>', {
195
- 'arg1': 'value1',
196
- 'arg2': 'value2',
197
- })
198
- ```
199
-
200
- ```ruby
201
- # Ruby
202
- result = @driver.execute_script 'windows: <methodName>', {
203
- arg1: 'value1',
204
- arg2: 'value2',
205
- }
206
- ```
207
-
208
- ```csharp
209
- // Dotnet
210
- object result = driver.ExecuteScript("windows: <methodName>", new Dictionary<string, object>() {
211
- {"arg1", "value1"},
212
- {"arg2", "value2"}
213
- });
214
- ```
215
-
216
- ### windows: click
217
-
218
- This is a shortcut for a single mouse click gesture.
219
-
220
- #### Arguments
221
-
222
- Name | Type | Required | Description | Example
223
- --- | --- | --- | --- | ---
224
- elementId | string | no | Hexadecimal identifier of the element to click on. If this parameter is missing then given coordinates will be parsed as absolute ones. Otherwise they are parsed as relative to the top left corner of this element. | 123e4567-e89b-12d3-a456-426614174000
225
- x | number | no | Integer horizontal coordinate of the click point. Both x and y coordinates must be provided or none of them if elementId is present. In such case the gesture will be performed at the center point of the given element. The screen scale (if customized) is **not** taken into consideration while calculating the coordinate. The coordinate is always calculated for the [virtual screen](https://learn.microsoft.com/en-us/windows/win32/gdi/the-virtual-screen). | 100
226
- y | number | no | Integer vertical coordinate of the click point. Both x and y coordinates must be provided or none of them if elementId is present. In such case the gesture will be performed at the center point of the given element. The screen scale (if customized) is **not** taken into consideration while calculating the coordinate. The coordinate is always calculated for the [virtual screen](https://learn.microsoft.com/en-us/windows/win32/gdi/the-virtual-screen). | 100
227
- button | string | no | Name of the mouse button to be clicked. An exception is thrown if an unknown button name is provided. Supported button names are: left, middle, right, back, forward. The default value is `left` | right
228
- modifierKeys | string[] or string | no | List of possible keys or a single key name to depress while the click is being performed. Supported key names are: Shift, Ctrl, Alt, Win. For example, in order to keep Ctrl+Alt depressed while clicking, provide the value of ['ctrl', 'alt'] | win
229
- durationMs | number | no | The number of milliseconds to wait between pressing and releasing the mouse button. By default no delay is applied, which simulates a regular click. | 500
230
- times | number | no | How many times the click must be performed. One by default. | 2
231
- interClickDelayMs | number | no | Duration of the pause between each click gesture. Only makes sense if `times` is greater than one. 100ms by default. | 10
232
-
233
- ### windows: scroll
234
-
235
- This is a shortcut for a mouse wheel scroll gesture. The API is a thin wrapper over the [SendInput](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendinput#:~:text=The%20SendInput%20function%20inserts%20the,or%20other%20calls%20to%20SendInput.)
236
- WinApi call. It emulates the mouse cursor movement and/or horizontal/vertical rotation of the mouse wheel.
237
- Thus make sure the target control is ready to receive mouse wheel events (e.g. is focused) before invoking it.
238
-
239
- #### Arguments
240
-
241
- Name | Type | Required | Description | Example
242
- --- | --- | --- | --- | ---
243
- elementId | string | no | Same as in [windows: click](#windows-click) | 123e4567-e89b-12d3-a456-426614174000
244
- x | number | no | Same as in [windows: click](#windows-click) | 100
245
- y | number | no | Same as in [windows: click](#windows-click) | 100
246
- deltaX | number | no | The amount of horizontal wheel movement measured in wheel clicks. A positive value indicates that the wheel was rotated to the right; a negative value indicates that the wheel was rotated to the left. Either this value or deltaY must be provided, but not both. | -5
247
- deltaY | number | no | The amount of vertical wheel movement measured in wheel clicks. A positive value indicates that the wheel was rotated forward, away from the user; a negative value indicates that the wheel was rotated backward, toward the user. Either this value or deltaX must be provided, but not both. | 5
248
- modifierKeys | string[] or string | no | Same as in [windows: click](#windows-click) | win
249
-
250
- ### windows: hover
251
-
252
- This is a shortcut for a hover gesture.
253
-
254
- #### Arguments
255
-
256
- Name | Type | Required | Description | Example
257
- --- | --- | --- | --- | ---
258
- startElementId | string | no | Same as in [windows: click](#windows-click) | 123e4567-e89b-12d3-a456-426614174000
259
- startX | number | no | Same as in [windows: click](#windows-click) | 100
260
- startY | number | no | Same as in [windows: click](#windows-click) | 100
261
- endElementId | string | no | Same as in [windows: click](#windows-click) | 123e4567-e89b-12d3-a456-426614174000
262
- endX | number | no | Same as in [windows: click](#windows-click) | 100
263
- endY | number | no | Same as in [windows: click](#windows-click) | 100
264
- modifierKeys | string[] or string | no | Same as in [windows: click](#windows-click) | win
265
- durationMs | number | no | The number of milliseconds between moving the cursor from the starting to the ending hover point. 500ms by default. | 700
266
-
267
- ### windows: keys
268
-
269
- This is a shortcut for a customized keyboard input. Selenium keys should also work as modifier keys, unless forceUnicode option is set to true.
270
-
271
- #### Arguments
272
-
273
- Name | Type | Required | Description | Example
274
- --- | --- | --- | --- | ---
275
- actions | KeyAction[] or KeyAction | yes | One or more [KeyAction](#keyaction) dictionaries | ```json [{"virtualKeyCode": 0x10, "down": true}, {'text': "appium likes you"}, {"virtualKeyCode": 0x10, "down": false}]```
276
- forceUnicode | boolean | no | Forces the characters to be sent as unicode characters. Note that they won't work in keyboard shortcut combinations, but it makes them keyboard-layout independent. | true
277
-
278
- ##### KeyAction
279
-
280
- Name | Type | Required | Description | Example
281
- --- | --- | --- | --- | ---
282
- pause | number | no | Allows to set a delay in milliseconds between key input series. Either this property or `text` or `virtualKeyCode` must be provided. | 100
283
- text | string | no | Non-empty string of Unicode text to type (surrogate characters like smileys are not supported). Either this property or `pause` or `virtualKeyCode` must be provided. | Привіт Світ!
284
- virtualKeyCode | number | no | Valid virtual key code. The list of supported key codes is available at [Virtual-Key Codes](https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes) page. Either this property or `pause` or `text` must be provided. | 0x10
285
- down | boolean | no | This property only makes sense in combination with `virtualKeyCode`. If set to `true` then the corresponding key will be depressed, `false` - released. By default the key is just pressed once. ! Do not forget to release depressed keys in your automated tests. | true
286
-
287
- ### windows: setClipboard
288
-
289
- Sets Windows clipboard content to the given text or a PNG image.
290
-
291
- #### Arguments
292
-
293
- Name | Type | Required | Description | Example
294
- --- | --- | --- | --- | ---
295
- b64Content | string | yes | Base64-encoded content of the clipboard to be set | `QXBwaXVt`
296
- contentType | 'plaintext' or 'image' | no | Set to 'plaintext' in order to set the given text to the clipboard (the default value). Set to 'image' if `b64Content` contains a base64-encoded payload of a PNG image. | image
297
-
298
- ### windows: getClipboard
299
-
300
- Retrieves Windows clipboard content.
301
-
302
- #### Arguments
303
-
304
- Name | Type | Required | Description | Example
305
- --- | --- | --- | --- | ---
306
- contentType | 'plaintext' or 'image' | no | Set to 'plaintext' in order to set the given text to the clipboard (the default value). Set to 'image' to retrieve a base64-encoded payload of a PNG image. | image
307
-
308
- #### Returns
309
-
310
- Base-64 encoded content of the Windows clipboard.
311
-
312
- ### windows: pushCacheRequest
313
-
314
- This is an asynchronous function that sends cache requests based on specific conditions. This is useful for revealing RawView elements in the element tree. Note that cached elements aren't supported by NovaWindows driver yet.
315
-
316
- #### Arguments
317
-
318
- Name | Type | Required | Description | Example
319
- --- | --- | --- | --- | ---
320
- treeFilter | string | yes | Defines the filter that is applied when walking the automation tree. You can use any UI Automation conditions. For simplicity, you can omit the namespace and/or the Condition word at the end. | `RawView`
321
- treeScope | string | no | Defines the scope of the automation tree to be cached. It determines how far to search for elements, such as just the element itself, its children, descendants or the entire subtree. | `SubTree`
322
- automationElementMode | string | no | Specifies the mode of automation element (e.g., None, Full). Determines whether the UI element is fully cached or only partially cached. | `Full`
323
-
324
- ### windows: invoke
325
-
326
- Invokes a UI element pattern, simulating an interaction like clicking or activating the element.
327
-
328
- #### Arguments
329
-
330
- Position | Type | Description | Example
331
- | --- | --- | --- | --- |
332
- 1 | `Element` | The UI element on which the `InvokePattern` is called to simulate activation. | `element`
333
-
334
- ### windows: expand
335
-
336
- Expands a UI element that supports the `ExpandPattern`, typically used for elements that can be expanded (like trees or combo boxes).
337
-
338
- #### Arguments
339
-
340
- Position | Type | Description | Example
341
- | --- | --- | --- | --- |
342
- 1 | `Element` | The UI element on which the `ExpandPattern` is called to expand the element. | `element`
343
-
344
- ### windows: collapse
345
-
346
- Collapses a UI element that supports the `CollapsePattern`, typically used for collapsible elements (like tree nodes).
347
-
348
- #### Arguments
349
-
350
- Position | Type | Description | Example
351
- | --- | --- | --- | --- |
352
- 1 | `Element` | The UI element on which the `CollapsePattern` is called to collapse the element. | `element`
353
-
354
- ### windows: scrollIntoView
355
-
356
- Scrolls the UI element into view using the `ScrollItemPattern`, ensuring that the element is visible within its container.
357
-
358
- #### Arguments
359
-
360
- Position | Type | Description | Example
361
- | --- | --- | --- | --- |
362
- 1 | `Element` | The UI element on which the `ScrollItemPattern` is called to bring the element into view. | `element`
363
-
364
- ### windows: isMultiple
365
-
366
- Checks if a UI element supports multiple selection using the `SelectionPattern`. Returns `true` if the element supports multiple selections, otherwise `false`.
367
-
368
- #### Arguments
369
-
370
- Position | Type | Description | Example
371
- | --- | --- | --- | --- |
372
- 1 | `Element` | The UI element to check for multiple selection support. | `element`
373
-
374
- #### Returns
375
-
376
- - `boolean`: `true` if the element supports multiple selection, otherwise `false`.
377
-
378
- ### windows: selectedItem
379
-
380
- Gets the selected item from a UI element that supports the `SelectionPattern`.
381
-
382
- #### Arguments
383
-
384
- Position | Type | Description | Example
385
- | --- | --- | --- | --- |
386
- 1 | `Element` | The UI element from which to retrieve the selected item. | `element`
387
-
388
- #### Returns
389
-
390
- - `Element`: The selected item of the element as an Appium element.
391
-
392
- ### windows: allSelectedItems
393
-
394
- Gets all selected items from a UI element that supports the `SelectionPattern`, useful for lists or combo boxes.
395
-
396
- #### Arguments
397
-
398
- Position | Type | Description | Example
399
- | --- | --- | --- | --- |
400
- 1 | `Element` | The UI element from which to retrieve all selected items. | `element`
401
-
402
- #### Returns
403
-
404
- - `Element[]`: An array of selected items as Appium elements.
405
-
406
- ### windows: addToSelection
407
-
408
- Adds an element to the current selection on a UI element that supports the `SelectionPattern`.
409
-
410
- #### Arguments
411
-
412
- Position | Type | Description | Example
413
- | --- | --- | --- | --- |
414
- 1 | `Element` | The UI element to add to the selection. | `element`
415
-
416
- ### windows: removeFromSelection
417
-
418
- Removes an element from the current selection on a UI element that supports the `SelectionPattern`.
419
-
420
- #### Arguments
421
-
422
- Position | Type | Description | Example
423
- | --- | --- | --- | --- |
424
- 1 | `Element` | The UI element to remove from the selection. | `element`
425
-
426
- ### windows: select
427
-
428
- Selects a UI element using the `SelectionPattern`, simulating the action of choosing the element in a selection context.
429
-
430
- #### Arguments
431
-
432
- Position | Type | Description | Example
433
- | --- | --- | --- | --- |
434
- 1 | `Element` | The UI element to select. | `element`
435
-
436
- ### windows: toggle
437
-
438
- Toggles a UI element’s state using the `TogglePattern`, typically used for elements like checkboxes or radio buttons.
439
-
440
- #### Arguments
441
-
442
- Position | Type | Description | Example
443
- | --- | --- | --- | --- |
444
- 1 | `Element` | The UI element to toggle. | `element`
445
-
446
- ### windows: setValue
447
-
448
- Sets the value of a UI element using the `ValuePattern` (for elements like text boxes, sliders, etc.).
449
-
450
- #### Arguments
451
-
452
- Position | Type | Description | Example
453
- | --- | --- | --- | --- |
454
- 1 | `Element` | The UI element whose value will be set. | `element`
455
- 2 | `string` | The value to be set on the element. | `"new value"`
456
-
457
- ### windows: getValue
458
-
459
- Gets the current value of a UI element that supports the `ValuePattern` (e.g., a text box).
460
-
461
- #### Arguments
462
-
463
- Position | Type | Description | Example
464
- | --- | --- | --- | --- |
465
- 1 | `Element` | The UI element from which to retrieve the value. | `element`
466
-
467
- ### windows: maximize
468
-
469
- Maximizes a window or UI element using the `WindowPattern`.
470
-
471
- #### Arguments
472
-
473
- Position | Type | Description | Example
474
- | --- | --- | --- | --- |
475
- 1 | `Element` | The window or UI element to maximize. | `element`
476
-
477
- ### windows: minimize
478
-
479
- Minimizes a window or UI element using the `WindowPattern`.
480
-
481
- #### Arguments
482
-
483
- Position | Type | Description | Example
484
- | --- | --- | --- | --- |
485
- 1 | `Element` | The window or UI element to minimize. | `element`
486
-
487
- ### windows: restore
488
-
489
- Restores a window or UI element to its normal state (if it was maximized or minimized) using the `WindowPattern`.
490
-
491
- #### Arguments
492
-
493
- Position | Type | Description | Example
494
- | --- | --- | --- | --- |
495
- 1 | `Element` | The window or UI element to restore. | `element`
496
-
497
- ### windows: close
498
-
499
- Closes a window or UI element using the `WindowPattern`.
500
-
501
- #### Arguments
502
-
503
- Position | Type | Description | Example
504
- | --- | --- | --- | --- |
505
- 1 | `Element` | The window or UI element to close. | `element`
506
-
507
- ### windows: setFocus
508
-
509
- Sets focus to the specified UI element using UIAutomationElement's `SetFocus` method.
510
-
511
- #### Arguments
512
-
513
- Position | Type | Description | Example
514
- | --- | --- | --- | --- |
515
- 1 | `Element` | The UI element to set focus on. | `element`
516
-
517
- ### windows: startRecordingScreen
518
-
519
- To be implemented.
520
-
521
- ### windows: stopRecordingScreen
522
-
523
- To be implemented.
524
-
525
- ### windows: deleteFile
526
-
527
- To be implemented.
528
-
529
- ### windows: deleteFolder
530
-
531
- To be implemented.
532
-
533
- ### windows: launchApp
534
-
535
- To be implemented.
536
-
537
- ### windows: closeApp
538
-
539
- To be implemented.
540
-
541
- ### windows: clickAndDrag
542
-
543
- To be implemented.
544
-
545
- ## Development
546
-
547
- it is recommended to use Matt Bierner's [Comment tagged templates](https://marketplace.visualstudio.com/items?itemName=bierner.comment-tagged-templates)
548
- Visual Studio Code plugin so it highlights the powershell and C code used throughout the project.
549
-
550
- ```bash
551
- # Checkout the current repository and run
552
- npm install
553
- # Run linting to check for code quality
554
- npm run lint
555
- # Transpile TypeScript files to build the project
556
- npm run build
557
- ```
1
+ NovaWindows2 Driver
2
+ ===================
3
+
4
+ NovaWindows2 Driver is a custom Appium driver designed to tackle the limitations of existing Windows automation solutions like WinAppDriver. It supports testing Universal Windows Platform (UWP), Windows Forms (WinForms), Windows Presentation Foundation (WPF), and Classic Windows (Win32) apps on Windows 10 and later.
5
+
6
+ Built to improve performance and reliability for traditional desktop applications, it offers:
7
+ - **Faster XPath locator performance** Reduces element lookup times, even in complex UIs.
8
+ - **RawView element support**Access elements typically hidden from the default ControlView/ContentView.
9
+ - **Enhanced text input handling** Fast text entry with support for various keyboard layouts.
10
+ - **Platform-specific commands** Supports direct window manipulation, advanced UI interactions, and more.
11
+ - **Seamless Setup** — Designed to work without Developer Mode or additional software.
12
+
13
+ ---
14
+
15
+ ## 📑 Table of Contents
16
+ - [Getting Started](#-getting-started)
17
+ - [Configuration](#-configuration)
18
+ - [Example Usage](#-example-usage)
19
+ - [Key Features](#-key-features)
20
+ - [Element Location](#element-location)
21
+ - [Attribute Retrieval](#attribute-retrieval)
22
+ - [PowerShell Execution](#powershell-execution)
23
+ - [Platform-Specific Extensions](#-platform-specific-extensions)
24
+ - [Mouse & Pointer](#mouse--pointer)
25
+ - [Keyboard](#keyboard)
26
+ - [Element Operations](#element-operations)
27
+ - [Selection Management](#selection-management)
28
+ - [Window Management](#window-management)
29
+ - [System & State](#system--state)
30
+ - [Development](#-development)
31
+
32
+ ---
33
+
34
+ ## 🚀 Getting Started
35
+
36
+ ### Installation
37
+ The driver is built for Appium 3. To install it, run:
38
+ ```bash
39
+ appium driver install --source=npm appium-novawindows2-driver
40
+ ```
41
+
42
+ ### Prerequisites
43
+ - **Host OS**: Windows 10 or later.
44
+ - No Developer Mode or extra dependencies required.
45
+
46
+ ---
47
+
48
+ ## ⚙️ Configuration
49
+
50
+ NovaWindows2 Driver supports the following capabilities:
51
+
52
+ | Capability Name | Description | Default | Example |
53
+ | :--- | :--- | :--- | :--- |
54
+ | `platformName` | Must be set to `Windows` (case-insensitive). | (Required) | `Windows` |
55
+ | `automationName` | Must be set to `NovaWindows2` (case-insensitive). | (Required) | `NovaWindows2` |
56
+ | `smoothPointerMove` | CSS-like easing function (including valid Bezier curve). This controls the smooth movement of the mouse for `delayBeforeClick` ms. | (None) | `ease-in`, `cubic-bezier(0.42, 0, 0.58, 1)` |
57
+ | `delayBeforeClick` | Time in milliseconds before a click is performed. | `0` | `500` |
58
+ | `delayAfterClick` | Time in milliseconds after a click is performed. | `0` | `500` |
59
+ | `appTopLevelWindow` | The handle of an existing application top-level window to attach to. It can be a number or string (not necessarily hexadecimal). | (None) | `12345`, `0x12345` |
60
+ | `shouldCloseApp` | Whether to close the window of the application in test after the session finishes. | `true` | `false` |
61
+ | `appArguments` | Optional string of arguments to pass to the app on launch. | (None) | `--debug` |
62
+ | `appWorkingDir` | Optional working directory path for the application. | (None) | `C:\Temp` |
63
+ | `prerun` | An object containing either `script` or `command` key. The value of each key must be a valid PowerShell script or command to be executed prior to the WinAppDriver session startup. See [Power Shell commands execution](#powershell-execution) for more details. | (None) | `{script: 'Get-Process outlook -ErrorAction SilentlyContinue'}` |
64
+ | `postrun` | An object containing either `script` or `command` key. The value of each key must be a valid PowerShell script or command to be executed after WinAppDriver session is stopped. See [Power Shell commands execution](#powershell-execution) for more details. | (None) | `{command: '...'}` |
65
+ | `isolatedScriptExecution` | Whether PowerShell scripts are executed in an isolated session. | `false` | `true` |
66
+ | `appWaitForLaunchRetries` | Number of retries when waiting for the app to launch. | `20` | `5` |
67
+ | `appWaitForLaunchRetryIntervalMs` | Interval (ms) between app launch check retries. | `500` | `500` |
68
+ | `powerShellCommandTimeout` | Timeout (ms) for PowerShell script execution. | `60000` | `30000` |
69
+ | `convertAbsoluteXPathToRelativeFromElement` | Convert absolute XPath to relative when searching from an element. | `true` | `true` |
70
+ | `includeContextElementInSearch` | Include the context element itself in the search. | `true` | `true` |
71
+ | `releaseModifierKeys` | Whether to release modifier keys after `sendKeys`. | `true` | `true` |
72
+
73
+ ---
74
+
75
+ ## 💡 Example Usage
76
+
77
+ Check out the [examples/refactor](examples/refactor) directory for comprehensive examples.
78
+
79
+ ### Python (Appium-Python-Client)
80
+ ```python
81
+ from appium import webdriver
82
+ from appium.options.windows import WindowsOptions
83
+
84
+ options = WindowsOptions()
85
+ options.app = 'C:\\Windows\\System32\\notepad.exe'
86
+ options.automation_name = 'NovaWindows2'
87
+
88
+ driver = webdriver.Remote('http://127.0.0.1:4723', options=options)
89
+ # ... tests ...
90
+ driver.quit()
91
+ ```
92
+
93
+ ---
94
+
95
+ ## ✨ Key Features
96
+
97
+ ### Element Location
98
+ Appium Windows Driver supports the same location strategies [the WinAppDriver supports](https://github.com/microsoft/WinAppDriver/blob/master/Docs/AuthoringTestScripts.md#supported-locators-to-find-ui-elements), but also includes Windows UIAutomation conditions:
99
+
100
+ | Name | Description | Example |
101
+ | :--- | :--- | :--- |
102
+ | `accessibility id` | This strategy is `AutomationId` attribute in inspect.exe | `CalculatorResults` |
103
+ | `class name` | This strategy is `ClassName` attribute in inspect.exe | `TextBlock` |
104
+ | `id` | This strategy is `RuntimeId` (decimal) attribute in inspect.exe | `42.333896.3.1` |
105
+ | `name` | This strategy is `Name` attribute in inspect.exe | `Calculator` |
106
+ | `tag name` | This strategy is `LocalizedControlType` (upper camel case) attribute in inspect.exe | `Text` |
107
+ | `xpath` | Custom XPath 1.0 queries on any attribute exposed by inspect.exe. | `(//Button)[2]` |
108
+ | `windows uiautomation` | UIAutomation conditions (C# or PowerShell syntax). | `new PropertyCondition(...)` |
109
+
110
+ ### Attribute Retrieval
111
+ Retrieve comprehensive details about UI elements using standard or bulk methods.
112
+
113
+ - **Bulk Retrieval**: Use the `"all"` keyword to get 80+ properties in a single JSON object.
114
+ - **Dotted Names**: Access pattern-specific properties directly (e.g., `Window.CanMaximize`, `LegacyIAccessible.Name`).
115
+
116
+ ```js
117
+ // getAttributes returns all properties as a JSON string
118
+ const allAttributes = await element.getAttribute("all");
119
+ ```
120
+
121
+ ### PowerShell Execution
122
+ Execute internal PowerShell scripts or commands directly from your test. This requires the `power_shell` insecure feature to be enabled on the Appium server.
123
+
124
+ It is possible to execute a single PowerShell command or a whole script. Note that `powerShell` is case-insensitive.
125
+
126
+ ```javascript
127
+ // Execute a command string
128
+ await driver.executeScript('powerShell', { command: 'Get-Process Notepad' });
129
+
130
+ // Execute a script string
131
+ await driver.executeScript('powerShell', { script: '$p = Get-Process Notepad; $p.Kill();' });
132
+
133
+ // Shorthand (executes as command/script depending on context)
134
+ await driver.executeScript('powerShell', 'Get-Process');
135
+ ```
136
+
137
+ ---
138
+
139
+ ## 🛠 Platform-Specific Extensions
140
+
141
+ All extensions are invoked via `driver.executeScript("windows: <methodName>", ...args)`.
142
+ Below are the detailed descriptions and arguments for each command.
143
+
144
+ > **Note**
145
+ > In most cases, commands can be used more intuitively by passing the element as the first argument (if required) and other parameters subsequently.
146
+
147
+ ### Mouse & Pointer
148
+
149
+ #### `windows: click`
150
+ This is a shortcut for a single mouse click gesture.
151
+
152
+ | Name | Type | Required | Description | Example |
153
+ | :--- | :--- | :--- | :--- | :--- |
154
+ | `elementId` | `string` | no | Hexadecimal identifier of the element to click on. If this parameter is missing then given coordinates will be parsed as absolute ones. Otherwise they are parsed as relative to the top left corner of this element. | `123e4567-e89b...` |
155
+ | `x` | `number` | no | Integer horizontal coordinate of the click point. Both x and y coordinates must be provided or none of them if elementId is present. | `100` |
156
+ | `y` | `number` | no | Integer vertical coordinate of the click point. Both x and y coordinates must be provided or none of them if elementId is present. | `100` |
157
+ | `button` | `string` | no | Name of the mouse button to be clicked. Supported button names are: `left`, `middle`, `right`, `back`, `forward`. The default value is `left`. | `right` |
158
+ | `modifierKeys` | `string[]` \| `string` | no | List of possible keys or a single key name to depress while the click is being performed. Supported key names are: `Shift`, `Ctrl`, `Alt`, `Win`. | `['ctrl', 'alt']` |
159
+ | `durationMs` | `number` | no | The number of milliseconds to wait between pressing and releasing the mouse button. By default no delay is applied. | `500` |
160
+ | `times` | `number` | no | How many times the click must be performed. One by default. | `2` |
161
+ | `interClickDelayMs` | `number` | no | Duration of the pause between each click gesture. Only makes sense if `times` is greater than one. 100ms by default. | `10` |
162
+
163
+ #### Usage
164
+ ```python
165
+ driver.execute_script('windows: click', {
166
+ 'elementId': element.id,
167
+ 'button': 'right',
168
+ 'times': 2,
169
+ 'modifierKeys': ['ctrl', 'alt']
170
+ })
171
+ ```
172
+
173
+ #### `windows: scroll`
174
+ This is a shortcut for a mouse wheel scroll gesture. The API is a thin wrapper over the SendInput WinApi call.
175
+
176
+ | Name | Type | Required | Description | Example |
177
+ | :--- | :--- | :--- | :--- | :--- |
178
+ | `elementId` | `string` | no | Same as in `windows: click`. | `123e4567-e89b...` |
179
+ | `x` | `number` | no | Same as in `windows: click`. | `100` |
180
+ | `y` | `number` | no | Same as in `windows: click`. | `100` |
181
+ | `deltaX` | `number` | no | The amount of horizontal wheel movement measured in wheel clicks. Positive = right, Negative = left. | `-5` |
182
+ | `deltaY` | `number` | no | The amount of vertical wheel movement. Positive = forward (away), Negative = backward (toward). | `5` |
183
+ | `modifierKeys` | `string[]` \| `string` | no | Same as in `windows: click`. | `win` |
184
+
185
+ #### Usage
186
+ ```python
187
+ driver.execute_script('windows: scroll', {
188
+ 'elementId': element.id,
189
+ 'deltaY': -5, # Scroll down 5 clicks
190
+ 'modifierKeys': 'shift'
191
+ })
192
+ ```
193
+
194
+ #### `windows: hover`
195
+ This is a shortcut for a hover gesture.
196
+
197
+ | Name | Type | Required | Description | Example |
198
+ | :--- | :--- | :--- | :--- | :--- |
199
+ | `startElementId` | `string` | no | Same as in `windows: click`. | `123e4567-e89b...` |
200
+ | `startX` | `number` | no | Same as in `windows: click`. | `100` |
201
+ | `startY` | `number` | no | Same as in `windows: click`. | `100` |
202
+ | `endElementId` | `string` | no | Same as in `windows: click`. | `123e4567-e89b...` |
203
+ | `endX` | `number` | no | Same as in `windows: click`. | `200` |
204
+ | `endY` | `number` | no | Same as in `windows: click`. | `200` |
205
+ | `modifierKeys` | `string[]` \| `string` | no | Same as in `windows: click`. | `shift` |
206
+ | `durationMs` | `number` | no | The number of milliseconds between moving the cursor from the starting to the ending hover point. 500ms by default. | `700` |
207
+
208
+ #### Usage
209
+ ```python
210
+ driver.execute_script('windows: hover', {
211
+ 'startElementId': element1.id,
212
+ 'endElementId': element2.id,
213
+ 'durationMs': 1000
214
+ })
215
+ ```
216
+
217
+ ### Keyboard
218
+
219
+ #### `windows: keys`
220
+ This is a shortcut for a customized keyboard input. Selenium keys should also work as modifier keys.
221
+
222
+ | Name | Type | Required | Description | Example |
223
+ | :--- | :--- | :--- | :--- | :--- |
224
+ | `actions` | `KeyAction[]` \| `KeyAction` | yes | One or more KeyAction dictionaries. | `[{'virtualKeyCode': 0x10, 'down': true}]` |
225
+ | `forceUnicode` | `boolean` | no | Forces the characters to be sent as unicode characters. | `true` |
226
+
227
+ ##### KeyAction Dictionary
228
+
229
+ | Name | Type | Required | Description | Example |
230
+ | :--- | :--- | :--- | :--- | :--- |
231
+ | `pause` | `number` | no | Allows to set a delay in milliseconds between key input series. | `100` |
232
+ | `text` | `string` | no | Non-empty string of Unicode text to type. | `Hello` |
233
+ | `virtualKeyCode` | `number` | no | Valid virtual key code. | `0x10` |
234
+ | `down` | `boolean` | no | If set to `true` then the corresponding key will be depressed, `false` - released. | `true` |
235
+
236
+ #### Usage
237
+ ```python
238
+ driver.execute_script('windows: keys', {
239
+ 'actions': [
240
+ {'virtualKeyCode': 0x10, 'down': True}, # Shift Down
241
+ {'text': 'Hello World'},
242
+ {'virtualKeyCode': 0x10, 'down': False} # Shift Up
243
+ ]
244
+ })
245
+ ```
246
+
247
+ ### System & State
248
+
249
+ #### `windows: setClipboard`
250
+ Sets Windows clipboard content to the given text or a PNG image.
251
+
252
+ | Name | Type | Required | Description | Example |
253
+ | :--- | :--- | :--- | :--- | :--- |
254
+ | `b64Content` | `string` | yes | Base64-encoded content of the clipboard to be set. | `QXBwaXVt` |
255
+ | `contentType` | `string` | no | Set to `plaintext` (default) or `image`. | `image` |
256
+
257
+ #### Usage
258
+ ```python
259
+ driver.execute_script('windows: setClipboard', {
260
+ 'b64Content': 'SGVsbG8=', # "Hello" in Base64
261
+ 'contentType': 'plaintext'
262
+ })
263
+ ```
264
+
265
+ #### `windows: getClipboard`
266
+ Retrieves Windows clipboard content.
267
+
268
+ | Name | Type | Required | Description | Example |
269
+ | :--- | :--- | :--- | :--- | :--- |
270
+ | `contentType` | `string` | no | Set to `plaintext` (default) or `image`. | `image` |
271
+
272
+ #### Usage
273
+ ```python
274
+ content = driver.execute_script('windows: getClipboard', {
275
+ 'contentType': 'plaintext'
276
+ })
277
+ print(content)
278
+ ```
279
+
280
+ #### `windows: pushCacheRequest`
281
+ This is an asynchronous function that sends cache requests based on specific conditions.
282
+
283
+ | Name | Type | Required | Description | Example |
284
+ | :--- | :--- | :--- | :--- | :--- |
285
+ | `treeFilter` | `string` | yes | Defines the filter that is applied when walking the automation tree. | `RawView` |
286
+ | `treeScope` | `string` | no | Defines the scope of the automation tree to be cached. | `SubTree` |
287
+ | `automationElementMode` | `string` | no | Specifies the mode of automation element (e.g., `None`, `Full`). | `Full` |
288
+
289
+ #### Usage
290
+ ```python
291
+ driver.execute_script('windows: pushCacheRequest', {
292
+ 'treeFilter': 'RawView',
293
+ 'treeScope': 'SubTree'
294
+ })
295
+ ```
296
+
297
+ ### Element Operations
298
+
299
+ #### `windows: invoke`
300
+ Invokes a UI element pattern, simulating an interaction like clicking or activating the element.
301
+
302
+ | Position | Type | Description | Example |
303
+ | :--- | :--- | :--- | :--- |
304
+ | 1 | `Element` | The UI element on which the `InvokePattern` is called. | `element` |
305
+
306
+ #### Usage
307
+ ```python
308
+ driver.execute_script('windows: invoke', element)
309
+ ```
310
+
311
+ #### `windows: expand`
312
+ Expands a UI element that supports the `ExpandPattern`.
313
+
314
+ | Position | Type | Description | Example |
315
+ | :--- | :--- | :--- | :--- |
316
+ | 1 | `Element` | The UI element to expand. | `element` |
317
+
318
+ #### Usage
319
+ ```python
320
+ driver.execute_script('windows: expand', element)
321
+ ```
322
+
323
+ #### `windows: collapse`
324
+ Collapses a UI element that supports the `CollapsePattern`.
325
+
326
+ | Position | Type | Description | Example |
327
+ | :--- | :--- | :--- | :--- |
328
+ | 1 | `Element` | The UI element to collapse. | `element` |
329
+
330
+ #### Usage
331
+ ```python
332
+ driver.execute_script('windows: collapse', element)
333
+ ```
334
+
335
+ #### `windows: setValue`
336
+ Sets the value of a UI element using the `ValuePattern`.
337
+
338
+ | Position | Type | Description | Example |
339
+ | :--- | :--- | :--- | :--- |
340
+ | 1 | `Element` | The UI element whose value will be set. | `element` |
341
+ | 2 | `string` | The value to be set. | `"new value"` |
342
+
343
+ #### Usage
344
+ ```python
345
+ driver.execute_script('windows: setValue', element, 'New Value')
346
+ ```
347
+
348
+ #### `windows: getValue`
349
+ Gets the current value of a UI element that supports the `ValuePattern`.
350
+
351
+ | Position | Type | Description | Example |
352
+ | :--- | :--- | :--- | :--- |
353
+ | 1 | `Element` | The UI element from which to retrieve the value. | `element` |
354
+
355
+ #### Usage
356
+ ```python
357
+ value = driver.execute_script('windows: getValue', element)
358
+ ```
359
+
360
+ #### `windows: scrollIntoView`
361
+ Scrolls the UI element into view using the `ScrollItemPattern`.
362
+
363
+ | Position | Type | Description | Example |
364
+ | :--- | :--- | :--- | :--- |
365
+ | 1 | `Element` | The UI element to bring into view. | `element` |
366
+
367
+ #### Usage
368
+ ```python
369
+ driver.execute_script('windows: scrollIntoView', element)
370
+ ```
371
+
372
+ #### `windows: toggle`
373
+ Toggles a UI element’s state using the `TogglePattern`.
374
+
375
+ | Position | Type | Description | Example |
376
+ | :--- | :--- | :--- | :--- |
377
+ | 1 | `Element` | The UI element to toggle. | `element` |
378
+
379
+ #### Usage
380
+ ```python
381
+ driver.execute_script('windows: toggle', element)
382
+ ```
383
+
384
+ ### Selection Management
385
+
386
+ #### `windows: select`
387
+ Selects a UI element using the `SelectionPattern`.
388
+
389
+ | Position | Type | Description | Example |
390
+ | :--- | :--- | :--- | :--- |
391
+ | 1 | `Element` | The UI element to select. | `element` |
392
+
393
+ #### Usage
394
+ ```python
395
+ driver.execute_script('windows: select', element)
396
+ ```
397
+
398
+ #### `windows: addToSelection`
399
+ Adds an element to the current selection on a UI element that supports the `SelectionPattern`.
400
+
401
+ | Position | Type | Description | Example |
402
+ | :--- | :--- | :--- | :--- |
403
+ | 1 | `Element` | The UI element to add to the selection. | `element` |
404
+
405
+ #### Usage
406
+ ```python
407
+ driver.execute_script('windows: addToSelection', element)
408
+ ```
409
+
410
+ #### `windows: removeFromSelection`
411
+ Removes an element from the current selection on a UI element that supports the `SelectionPattern`.
412
+
413
+ | Position | Type | Description | Example |
414
+ | :--- | :--- | :--- | :--- |
415
+ | 1 | `Element` | The UI element to remove from the selection. | `element` |
416
+
417
+ #### Usage
418
+ ```python
419
+ driver.execute_script('windows: removeFromSelection', element)
420
+ ```
421
+
422
+ #### `windows: isMultiple`
423
+ Checks if a UI element supports multiple selection using the `SelectionPattern`.
424
+
425
+ | Position | Type | Description | Example |
426
+ | :--- | :--- | :--- | :--- |
427
+ | 1 | `Element` | The UI element to check. | `element` |
428
+
429
+ #### Usage
430
+ ```python
431
+ is_multi = driver.execute_script('windows: isMultiple', element)
432
+ ```
433
+
434
+ #### `windows: selectedItem`
435
+ Gets the selected item from a UI element that supports the `SelectionPattern`.
436
+
437
+ | Position | Type | Description | Example |
438
+ | :--- | :--- | :--- | :--- |
439
+ | 1 | `Element` | The UI element from which to retrieve the selected item. | `element` |
440
+
441
+ #### Usage
442
+ ```python
443
+ selected_el = driver.execute_script('windows: selectedItem', element)
444
+ ```
445
+
446
+ #### `windows: allSelectedItems`
447
+ Gets all selected items from a UI element that supports the `SelectionPattern`.
448
+
449
+ | Position | Type | Description | Example |
450
+ | :--- | :--- | :--- | :--- |
451
+ | 1 | `Element` | The UI element from which to retrieve all selected items. | `element` |
452
+
453
+ #### Usage
454
+ ```python
455
+ selected_els = driver.execute_script('windows: allSelectedItems', element)
456
+ ```
457
+
458
+ ### Window Management
459
+
460
+ #### `windows: maximize`
461
+ Maximizes a window or UI element using the `WindowPattern`.
462
+
463
+ | Position | Type | Description | Example |
464
+ | :--- | :--- | :--- | :--- |
465
+ | 1 | `Element` | The window or UI element to maximize. | `element` |
466
+
467
+ #### Usage
468
+ ```python
469
+ driver.execute_script('windows: maximize', element)
470
+ ```
471
+
472
+ #### `windows: minimize`
473
+ Minimizes a window or UI element using the `WindowPattern`.
474
+
475
+ | Position | Type | Description | Example |
476
+ | :--- | :--- | :--- | :--- |
477
+ | 1 | `Element` | The window or UI element to minimize. | `element` |
478
+
479
+ #### Usage
480
+ ```python
481
+ driver.execute_script('windows: minimize', element)
482
+ ```
483
+
484
+ #### `windows: restore`
485
+ Restores a window or UI element to its normal state using the `WindowPattern`.
486
+
487
+ | Position | Type | Description | Example |
488
+ | :--- | :--- | :--- | :--- |
489
+ | 1 | `Element` | The window or UI element to restore. | `element` |
490
+
491
+ #### Usage
492
+ ```python
493
+ driver.execute_script('windows: restore', element)
494
+ ```
495
+
496
+ #### `windows: close`
497
+ Closes a window or UI element using the `WindowPattern`.
498
+
499
+ | Position | Type | Description | Example |
500
+ | :--- | :--- | :--- | :--- |
501
+ | 1 | `Element` | The window or UI element to close. | `element` |
502
+
503
+ #### Usage
504
+ ```python
505
+ driver.execute_script('windows: close', element)
506
+ ```
507
+
508
+ #### `windows: setFocus`
509
+ Sets focus to the specified UI element using UIAutomationElement's `SetFocus` method.
510
+
511
+ | Position | Type | Description | Example |
512
+ | :--- | :--- | :--- | :--- |
513
+ | 1 | `Element` | The UI element to set focus on. | `element` |
514
+
515
+ #### Usage
516
+ ```python
517
+ driver.execute_script('windows: setFocus', element)
518
+ ```
519
+
520
+ ---
521
+
522
+ ## 🛠 Development
523
+
524
+ Recommended VS Code plugin: [Comment tagged templates](https://marketplace.visualstudio.com/items?itemName=bierner.comment-tagged-templates) for syntax highlighting.
525
+
526
+ ```bash
527
+ npm install # Setup dependencies
528
+ npm run lint # Code quality check
529
+ npm run build # Transpile TypeScript to JS
530
+ ```