appium-desktop-driver 1.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/LICENSE +202 -0
- package/README.md +609 -0
- package/ROADMAP.md +175 -0
- package/build/lib/commands/actions.d.ts +12 -0
- package/build/lib/commands/actions.d.ts.map +1 -0
- package/build/lib/commands/actions.js +242 -0
- package/build/lib/commands/actions.js.map +1 -0
- package/build/lib/commands/app.d.ts +18 -0
- package/build/lib/commands/app.d.ts.map +1 -0
- package/build/lib/commands/app.js +280 -0
- package/build/lib/commands/app.js.map +1 -0
- package/build/lib/commands/device.d.ts +11 -0
- package/build/lib/commands/device.d.ts.map +1 -0
- package/build/lib/commands/device.js +236 -0
- package/build/lib/commands/device.js.map +1 -0
- package/build/lib/commands/element.d.ts +16 -0
- package/build/lib/commands/element.d.ts.map +1 -0
- package/build/lib/commands/element.js +233 -0
- package/build/lib/commands/element.js.map +1 -0
- package/build/lib/commands/extension.d.ts +124 -0
- package/build/lib/commands/extension.d.ts.map +1 -0
- package/build/lib/commands/extension.js +715 -0
- package/build/lib/commands/extension.js.map +1 -0
- package/build/lib/commands/functions.d.ts +3 -0
- package/build/lib/commands/functions.d.ts.map +1 -0
- package/build/lib/commands/functions.js +194 -0
- package/build/lib/commands/functions.js.map +1 -0
- package/build/lib/commands/index.d.ts +178 -0
- package/build/lib/commands/index.d.ts.map +1 -0
- package/build/lib/commands/index.js +54 -0
- package/build/lib/commands/index.js.map +1 -0
- package/build/lib/commands/powershell.d.ts +6 -0
- package/build/lib/commands/powershell.d.ts.map +1 -0
- package/build/lib/commands/powershell.js +202 -0
- package/build/lib/commands/powershell.js.map +1 -0
- package/build/lib/commands/screen-recorder.d.ts +40 -0
- package/build/lib/commands/screen-recorder.d.ts.map +1 -0
- package/build/lib/commands/screen-recorder.js +183 -0
- package/build/lib/commands/screen-recorder.js.map +1 -0
- package/build/lib/commands/system.d.ts +4 -0
- package/build/lib/commands/system.d.ts.map +1 -0
- package/build/lib/commands/system.js +8 -0
- package/build/lib/commands/system.js.map +1 -0
- package/build/lib/constants.d.ts +3 -0
- package/build/lib/constants.d.ts.map +1 -0
- package/build/lib/constants.js +6 -0
- package/build/lib/constants.js.map +1 -0
- package/build/lib/constraints.d.ts +58 -0
- package/build/lib/constraints.d.ts.map +1 -0
- package/build/lib/constraints.js +60 -0
- package/build/lib/constraints.js.map +1 -0
- package/build/lib/driver.d.ts +36 -0
- package/build/lib/driver.d.ts.map +1 -0
- package/build/lib/driver.js +209 -0
- package/build/lib/driver.js.map +1 -0
- package/build/lib/enums.d.ts +89 -0
- package/build/lib/enums.d.ts.map +1 -0
- package/build/lib/enums.js +83 -0
- package/build/lib/enums.js.map +1 -0
- package/build/lib/mcp/appium-manager.d.ts +8 -0
- package/build/lib/mcp/appium-manager.d.ts.map +1 -0
- package/build/lib/mcp/appium-manager.js +160 -0
- package/build/lib/mcp/appium-manager.js.map +1 -0
- package/build/lib/mcp/config.d.ts +7 -0
- package/build/lib/mcp/config.d.ts.map +1 -0
- package/build/lib/mcp/config.js +14 -0
- package/build/lib/mcp/config.js.map +1 -0
- package/build/lib/mcp/constants.d.ts +3 -0
- package/build/lib/mcp/constants.d.ts.map +1 -0
- package/build/lib/mcp/constants.js +6 -0
- package/build/lib/mcp/constants.js.map +1 -0
- package/build/lib/mcp/errors.d.ts +2 -0
- package/build/lib/mcp/errors.d.ts.map +1 -0
- package/build/lib/mcp/errors.js +10 -0
- package/build/lib/mcp/errors.js.map +1 -0
- package/build/lib/mcp/index.d.ts +3 -0
- package/build/lib/mcp/index.d.ts.map +1 -0
- package/build/lib/mcp/index.js +113 -0
- package/build/lib/mcp/index.js.map +1 -0
- package/build/lib/mcp/session.d.ts +24 -0
- package/build/lib/mcp/session.d.ts.map +1 -0
- package/build/lib/mcp/session.js +77 -0
- package/build/lib/mcp/session.js.map +1 -0
- package/build/lib/mcp/tools/advanced.d.ts +4 -0
- package/build/lib/mcp/tools/advanced.d.ts.map +1 -0
- package/build/lib/mcp/tools/advanced.js +119 -0
- package/build/lib/mcp/tools/advanced.js.map +1 -0
- package/build/lib/mcp/tools/app.d.ts +4 -0
- package/build/lib/mcp/tools/app.d.ts.map +1 -0
- package/build/lib/mcp/tools/app.js +64 -0
- package/build/lib/mcp/tools/app.js.map +1 -0
- package/build/lib/mcp/tools/clipboard.d.ts +4 -0
- package/build/lib/mcp/tools/clipboard.d.ts.map +1 -0
- package/build/lib/mcp/tools/clipboard.js +41 -0
- package/build/lib/mcp/tools/clipboard.js.map +1 -0
- package/build/lib/mcp/tools/find.d.ts +4 -0
- package/build/lib/mcp/tools/find.d.ts.map +1 -0
- package/build/lib/mcp/tools/find.js +119 -0
- package/build/lib/mcp/tools/find.js.map +1 -0
- package/build/lib/mcp/tools/index.d.ts +4 -0
- package/build/lib/mcp/tools/index.d.ts.map +1 -0
- package/build/lib/mcp/tools/index.js +24 -0
- package/build/lib/mcp/tools/index.js.map +1 -0
- package/build/lib/mcp/tools/inspect.d.ts +4 -0
- package/build/lib/mcp/tools/inspect.d.ts.map +1 -0
- package/build/lib/mcp/tools/inspect.js +106 -0
- package/build/lib/mcp/tools/inspect.js.map +1 -0
- package/build/lib/mcp/tools/interact.d.ts +4 -0
- package/build/lib/mcp/tools/interact.d.ts.map +1 -0
- package/build/lib/mcp/tools/interact.js +121 -0
- package/build/lib/mcp/tools/interact.js.map +1 -0
- package/build/lib/mcp/tools/patterns.d.ts +4 -0
- package/build/lib/mcp/tools/patterns.d.ts.map +1 -0
- package/build/lib/mcp/tools/patterns.js +136 -0
- package/build/lib/mcp/tools/patterns.js.map +1 -0
- package/build/lib/mcp/tools/session.d.ts +4 -0
- package/build/lib/mcp/tools/session.d.ts.map +1 -0
- package/build/lib/mcp/tools/session.js +55 -0
- package/build/lib/mcp/tools/session.js.map +1 -0
- package/build/lib/mcp/tools/window.d.ts +4 -0
- package/build/lib/mcp/tools/window.d.ts.map +1 -0
- package/build/lib/mcp/tools/window.js +134 -0
- package/build/lib/mcp/tools/window.js.map +1 -0
- package/build/lib/powershell/common.d.ts +39 -0
- package/build/lib/powershell/common.d.ts.map +1 -0
- package/build/lib/powershell/common.js +121 -0
- package/build/lib/powershell/common.js.map +1 -0
- package/build/lib/powershell/conditions.d.ts +24 -0
- package/build/lib/powershell/conditions.d.ts.map +1 -0
- package/build/lib/powershell/conditions.js +131 -0
- package/build/lib/powershell/conditions.js.map +1 -0
- package/build/lib/powershell/converter.d.ts +3 -0
- package/build/lib/powershell/converter.d.ts.map +1 -0
- package/build/lib/powershell/converter.js +273 -0
- package/build/lib/powershell/converter.js.map +1 -0
- package/build/lib/powershell/core.d.ts +8 -0
- package/build/lib/powershell/core.d.ts.map +1 -0
- package/build/lib/powershell/core.js +30 -0
- package/build/lib/powershell/core.js.map +1 -0
- package/build/lib/powershell/elements.d.ts +70 -0
- package/build/lib/powershell/elements.d.ts.map +1 -0
- package/build/lib/powershell/elements.js +523 -0
- package/build/lib/powershell/elements.js.map +1 -0
- package/build/lib/powershell/index.d.ts +8 -0
- package/build/lib/powershell/index.d.ts.map +1 -0
- package/build/lib/powershell/index.js +24 -0
- package/build/lib/powershell/index.js.map +1 -0
- package/build/lib/powershell/regex.d.ts +19 -0
- package/build/lib/powershell/regex.d.ts.map +1 -0
- package/build/lib/powershell/regex.js +68 -0
- package/build/lib/powershell/regex.js.map +1 -0
- package/build/lib/powershell/types.d.ts +155 -0
- package/build/lib/powershell/types.d.ts.map +1 -0
- package/build/lib/powershell/types.js +141 -0
- package/build/lib/powershell/types.js.map +1 -0
- package/build/lib/util.d.ts +17 -0
- package/build/lib/util.d.ts.map +1 -0
- package/build/lib/util.js +76 -0
- package/build/lib/util.js.map +1 -0
- package/build/lib/winapi/types/index.d.ts +8 -0
- package/build/lib/winapi/types/index.d.ts.map +1 -0
- package/build/lib/winapi/types/index.js +24 -0
- package/build/lib/winapi/types/index.js.map +1 -0
- package/build/lib/winapi/types/input.d.ts +11 -0
- package/build/lib/winapi/types/input.d.ts.map +1 -0
- package/build/lib/winapi/types/input.js +12 -0
- package/build/lib/winapi/types/input.js.map +1 -0
- package/build/lib/winapi/types/keyeventf.d.ts +13 -0
- package/build/lib/winapi/types/keyeventf.d.ts.map +1 -0
- package/build/lib/winapi/types/keyeventf.js +14 -0
- package/build/lib/winapi/types/keyeventf.js.map +1 -0
- package/build/lib/winapi/types/mouseeventf.d.ts +34 -0
- package/build/lib/winapi/types/mouseeventf.d.ts.map +1 -0
- package/build/lib/winapi/types/mouseeventf.js +37 -0
- package/build/lib/winapi/types/mouseeventf.js.map +1 -0
- package/build/lib/winapi/types/scancode.d.ts +95 -0
- package/build/lib/winapi/types/scancode.d.ts.map +1 -0
- package/build/lib/winapi/types/scancode.js +96 -0
- package/build/lib/winapi/types/scancode.js.map +1 -0
- package/build/lib/winapi/types/systemmetric.d.ts +214 -0
- package/build/lib/winapi/types/systemmetric.d.ts.map +1 -0
- package/build/lib/winapi/types/systemmetric.js +215 -0
- package/build/lib/winapi/types/systemmetric.js.map +1 -0
- package/build/lib/winapi/types/virtualkey.d.ts +353 -0
- package/build/lib/winapi/types/virtualkey.d.ts.map +1 -0
- package/build/lib/winapi/types/virtualkey.js +354 -0
- package/build/lib/winapi/types/virtualkey.js.map +1 -0
- package/build/lib/winapi/types/xmousebutton.d.ts +7 -0
- package/build/lib/winapi/types/xmousebutton.d.ts.map +1 -0
- package/build/lib/winapi/types/xmousebutton.js +8 -0
- package/build/lib/winapi/types/xmousebutton.js.map +1 -0
- package/build/lib/winapi/user32.d.ts +56 -0
- package/build/lib/winapi/user32.d.ts.map +1 -0
- package/build/lib/winapi/user32.js +592 -0
- package/build/lib/winapi/user32.js.map +1 -0
- package/build/lib/xpath/core.d.ts +8 -0
- package/build/lib/xpath/core.d.ts.map +1 -0
- package/build/lib/xpath/core.js +593 -0
- package/build/lib/xpath/core.js.map +1 -0
- package/build/lib/xpath/functions.d.ts +4 -0
- package/build/lib/xpath/functions.d.ts.map +1 -0
- package/build/lib/xpath/functions.js +271 -0
- package/build/lib/xpath/functions.js.map +1 -0
- package/build/lib/xpath/index.d.ts +3 -0
- package/build/lib/xpath/index.d.ts.map +1 -0
- package/build/lib/xpath/index.js +19 -0
- package/build/lib/xpath/index.js.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,715 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.execute = execute;
|
|
4
|
+
exports.pushCacheRequest = pushCacheRequest;
|
|
5
|
+
exports.patternInvoke = patternInvoke;
|
|
6
|
+
exports.patternExpand = patternExpand;
|
|
7
|
+
exports.patternCollapse = patternCollapse;
|
|
8
|
+
exports.patternScrollIntoView = patternScrollIntoView;
|
|
9
|
+
exports.patternIsMultiple = patternIsMultiple;
|
|
10
|
+
exports.patternGetSelectedItem = patternGetSelectedItem;
|
|
11
|
+
exports.patternGetAllSelectedItems = patternGetAllSelectedItems;
|
|
12
|
+
exports.patternAddToSelection = patternAddToSelection;
|
|
13
|
+
exports.patternRemoveFromSelection = patternRemoveFromSelection;
|
|
14
|
+
exports.patternSelect = patternSelect;
|
|
15
|
+
exports.patternToggle = patternToggle;
|
|
16
|
+
exports.patternSetValue = patternSetValue;
|
|
17
|
+
exports.patternGetValue = patternGetValue;
|
|
18
|
+
exports.patternMaximize = patternMaximize;
|
|
19
|
+
exports.patternMinimize = patternMinimize;
|
|
20
|
+
exports.patternRestore = patternRestore;
|
|
21
|
+
exports.patternClose = patternClose;
|
|
22
|
+
exports.windowsCloseApp = windowsCloseApp;
|
|
23
|
+
exports.windowsLaunchApp = windowsLaunchApp;
|
|
24
|
+
exports.focusElement = focusElement;
|
|
25
|
+
exports.getClipboardBase64 = getClipboardBase64;
|
|
26
|
+
exports.setClipboardFromBase64 = setClipboardFromBase64;
|
|
27
|
+
exports.executePowerShellScript = executePowerShellScript;
|
|
28
|
+
exports.executeKeys = executeKeys;
|
|
29
|
+
exports.executeClick = executeClick;
|
|
30
|
+
exports.executeHover = executeHover;
|
|
31
|
+
exports.executeScroll = executeScroll;
|
|
32
|
+
exports.startRecordingScreen = startRecordingScreen;
|
|
33
|
+
exports.stopRecordingScreen = stopRecordingScreen;
|
|
34
|
+
exports.deleteFile = deleteFile;
|
|
35
|
+
exports.deleteFolder = deleteFolder;
|
|
36
|
+
exports.executeClickAndDrag = executeClickAndDrag;
|
|
37
|
+
exports.windowsGetDeviceTime = windowsGetDeviceTime;
|
|
38
|
+
exports.getWindowElement = getWindowElement;
|
|
39
|
+
const base_driver_1 = require("@appium/base-driver");
|
|
40
|
+
const node_os_1 = require("node:os");
|
|
41
|
+
const node_path_1 = require("node:path");
|
|
42
|
+
const constants_1 = require("../constants");
|
|
43
|
+
const enums_1 = require("../enums");
|
|
44
|
+
const powershell_1 = require("../powershell");
|
|
45
|
+
const util_1 = require("../util");
|
|
46
|
+
const screen_recorder_1 = require("./screen-recorder");
|
|
47
|
+
const types_1 = require("../winapi/types");
|
|
48
|
+
const user32_1 = require("../winapi/user32");
|
|
49
|
+
const PLATFORM_COMMAND_PREFIX = 'windows:';
|
|
50
|
+
const EXTENSION_COMMANDS = Object.freeze({
|
|
51
|
+
cacheRequest: 'pushCacheRequest',
|
|
52
|
+
invoke: 'patternInvoke',
|
|
53
|
+
expand: 'patternExpand',
|
|
54
|
+
collapse: 'patternCollapse',
|
|
55
|
+
isMultiple: 'patternIsMultiple',
|
|
56
|
+
scrollIntoView: 'patternScrollIntoView',
|
|
57
|
+
selectedItem: 'patternGetSelectedItem',
|
|
58
|
+
allSelectedItems: 'patternGetAllSelectedItems',
|
|
59
|
+
addToSelection: 'patternAddToSelection',
|
|
60
|
+
removeFromSelection: 'patternRemoveFromSelection',
|
|
61
|
+
select: 'patternSelect',
|
|
62
|
+
toggle: 'patternToggle',
|
|
63
|
+
setValue: 'patternSetValue',
|
|
64
|
+
getValue: 'patternGetValue',
|
|
65
|
+
maximize: 'patternMaximize',
|
|
66
|
+
minimize: 'patternMinimize',
|
|
67
|
+
restore: 'patternRestore',
|
|
68
|
+
close: 'patternClose',
|
|
69
|
+
closeApp: 'windowsCloseApp',
|
|
70
|
+
launchApp: 'windowsLaunchApp',
|
|
71
|
+
keys: 'executeKeys',
|
|
72
|
+
click: 'executeClick',
|
|
73
|
+
hover: 'executeHover',
|
|
74
|
+
scroll: 'executeScroll',
|
|
75
|
+
setFocus: 'focusElement',
|
|
76
|
+
getClipboard: 'getClipboardBase64',
|
|
77
|
+
setClipboard: 'setClipboardFromBase64',
|
|
78
|
+
startRecordingScreen: 'startRecordingScreen',
|
|
79
|
+
stopRecordingScreen: 'stopRecordingScreen',
|
|
80
|
+
deleteFile: 'deleteFile',
|
|
81
|
+
deleteFolder: 'deleteFolder',
|
|
82
|
+
clickAndDrag: 'executeClickAndDrag',
|
|
83
|
+
getDeviceTime: 'windowsGetDeviceTime',
|
|
84
|
+
getWindowElement: 'getWindowElement',
|
|
85
|
+
});
|
|
86
|
+
const ContentType = Object.freeze({
|
|
87
|
+
PLAINTEXT: 'plaintext',
|
|
88
|
+
IMAGE: 'image',
|
|
89
|
+
});
|
|
90
|
+
const TREE_FILTER_COMMAND = (0, util_1.$ /* ps1 */) `$cacheRequest.Pop(); $cacheRequest.TreeFilter = ${0}; $cacheRequest.Push()`;
|
|
91
|
+
const TREE_SCOPE_COMMAND = (0, util_1.$ /* ps1 */) `$cacheRequest.Pop(); $cacheRequest.TreeScope = ${0}; $cacheRequest.Push()`;
|
|
92
|
+
const AUTOMATION_ELEMENT_MODE = (0, util_1.$ /* ps1 */) `$cacheRequest.Pop(); $cacheRequest.AutomationElementMode = ${0}; $cacheRequest.Push()`;
|
|
93
|
+
const SET_PLAINTEXT_CLIPBOARD_FROM_BASE64 = (0, util_1.$ /* ps1 */) `Set-Clipboard -Value ([System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String(${0})))`;
|
|
94
|
+
const GET_PLAINTEXT_CLIPBOARD_BASE64 = /* ps1 */ `[Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes((Get-Clipboard)))`;
|
|
95
|
+
const SET_IMAGE_CLIPBOARD_FROM_BASE64 = (0, util_1.$ /* ps1 */) `$b = [Convert]::FromBase64String(${0}); $s = New-Object IO.MemoryStream; $s.Write($b, 0, $b.Length); $s.Position = 0; $i = [System.Windows.Media.Imaging.BitmapFrame]::Create($s); [Windows.Clipboard]::SetImage($i); $s.Close()`;
|
|
96
|
+
const GET_IMAGE_CLIPBOARD_BASE64 = (0, powershell_1.pwsh /* ps1 */) `
|
|
97
|
+
[Windows.Clipboard]::GetImage() | ForEach-Object {
|
|
98
|
+
if ($_ -ne $null) {
|
|
99
|
+
$stream = New-Object IO.MemoryStream
|
|
100
|
+
$encoder = New-Object Windows.Media.Imaging.PngBitmapEncoder
|
|
101
|
+
$encoder.Frames.Add([Windows.Media.Imaging.BitmapFrame]::Create($_))
|
|
102
|
+
$encoder.Save($stream)
|
|
103
|
+
$stream.Position = 0
|
|
104
|
+
$bytes = $stream.ToArray()
|
|
105
|
+
$base64String = [Convert]::ToBase64String($bytes)
|
|
106
|
+
$stream.Close()
|
|
107
|
+
Write-Output $base64String
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
`;
|
|
111
|
+
async function execute(script, args) {
|
|
112
|
+
if (script.startsWith(PLATFORM_COMMAND_PREFIX)) {
|
|
113
|
+
script = script.replace(PLATFORM_COMMAND_PREFIX, '').trim();
|
|
114
|
+
this.log.info(`Executing command '${PLATFORM_COMMAND_PREFIX} ${script}'...`);
|
|
115
|
+
if (!Object.hasOwn(EXTENSION_COMMANDS, script)) {
|
|
116
|
+
throw new base_driver_1.errors.UnknownCommandError(`Unknown command '${PLATFORM_COMMAND_PREFIX} ${script}'.`);
|
|
117
|
+
}
|
|
118
|
+
return await this[EXTENSION_COMMANDS[script]](...args);
|
|
119
|
+
}
|
|
120
|
+
if (script === 'powerShell') {
|
|
121
|
+
this.assertFeatureEnabled(constants_1.POWER_SHELL_FEATURE);
|
|
122
|
+
return await this.executePowerShellScript(args[0]);
|
|
123
|
+
}
|
|
124
|
+
if (script === 'return window.name') {
|
|
125
|
+
return await this.sendPowerShellCommand(powershell_1.AutomationElement.automationRoot.buildGetPropertyCommand(powershell_1.Property.NAME));
|
|
126
|
+
}
|
|
127
|
+
throw new base_driver_1.errors.NotImplementedError();
|
|
128
|
+
}
|
|
129
|
+
;
|
|
130
|
+
const TREE_SCOPE_REGEX = new powershell_1.PropertyRegexMatcher('System.Windows.Automation.TreeScope', ...Object.values(powershell_1.TreeScope)).toRegex('i');
|
|
131
|
+
const AUTOMATION_ELEMENT_MODE_REGEX = new powershell_1.PropertyRegexMatcher('System.Windows.Automation.AutomationElementMode', ...Object.values(powershell_1.AutomationElementMode)).toRegex('i');
|
|
132
|
+
async function pushCacheRequest(cacheRequest) {
|
|
133
|
+
if (Object.keys(cacheRequest).every((key) => cacheRequest[key] === undefined)) {
|
|
134
|
+
throw new base_driver_1.errors.InvalidArgumentError('At least one property of the cache request must be set.');
|
|
135
|
+
}
|
|
136
|
+
if (cacheRequest.treeFilter) {
|
|
137
|
+
await this.sendPowerShellCommand(TREE_FILTER_COMMAND.format((0, powershell_1.convertStringToCondition)(cacheRequest.treeFilter)));
|
|
138
|
+
}
|
|
139
|
+
if (cacheRequest.treeScope) {
|
|
140
|
+
const treeScope = TREE_SCOPE_REGEX.exec(cacheRequest.treeScope)?.[1];
|
|
141
|
+
if (!treeScope || (Number(cacheRequest.treeScope) < 1 && Number(cacheRequest.treeScope) > 16)) {
|
|
142
|
+
throw new base_driver_1.errors.InvalidArgumentError(`Invalid value '${cacheRequest.treeScope}' passed to TreeScope for cache request.`);
|
|
143
|
+
}
|
|
144
|
+
await this.sendPowerShellCommand(TREE_SCOPE_COMMAND.format(isNaN(Number(cacheRequest.treeScope)) ? /* ps1 */ `[TreeScope]::${cacheRequest.treeScope}` : cacheRequest.treeScope));
|
|
145
|
+
}
|
|
146
|
+
if (cacheRequest.automationElementMode) {
|
|
147
|
+
const treeScope = AUTOMATION_ELEMENT_MODE_REGEX.exec(cacheRequest.automationElementMode)?.[1];
|
|
148
|
+
if (!treeScope || (Number(cacheRequest.automationElementMode) < 0 && Number(cacheRequest.automationElementMode) > 1)) {
|
|
149
|
+
throw new base_driver_1.errors.InvalidArgumentError(`Invalid value '${cacheRequest.automationElementMode}' passed to AutomationElementMode for cache request.`);
|
|
150
|
+
}
|
|
151
|
+
let automationElementMode;
|
|
152
|
+
if (isNaN(Number(cacheRequest.automationElementMode))) {
|
|
153
|
+
automationElementMode = /* ps1 */ `[AutomationElementMode]::${cacheRequest.automationElementMode}`;
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
automationElementMode = cacheRequest.automationElementMode;
|
|
157
|
+
}
|
|
158
|
+
await this.sendPowerShellCommand(AUTOMATION_ELEMENT_MODE.format(automationElementMode));
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
async function patternInvoke(element) {
|
|
162
|
+
await this.sendPowerShellCommand(new powershell_1.FoundAutomationElement(element[base_driver_1.W3C_ELEMENT_KEY]).buildInvokeCommand());
|
|
163
|
+
}
|
|
164
|
+
async function patternExpand(element) {
|
|
165
|
+
await this.sendPowerShellCommand(new powershell_1.FoundAutomationElement(element[base_driver_1.W3C_ELEMENT_KEY]).buildExpandCommand());
|
|
166
|
+
}
|
|
167
|
+
async function patternCollapse(element) {
|
|
168
|
+
await this.sendPowerShellCommand(new powershell_1.FoundAutomationElement(element[base_driver_1.W3C_ELEMENT_KEY]).buildCollapseCommand());
|
|
169
|
+
}
|
|
170
|
+
async function patternScrollIntoView(element) {
|
|
171
|
+
await this.sendPowerShellCommand(new powershell_1.FoundAutomationElement(element[base_driver_1.W3C_ELEMENT_KEY]).buildScrollIntoViewCommand());
|
|
172
|
+
}
|
|
173
|
+
async function patternIsMultiple(element) {
|
|
174
|
+
const result = await this.sendPowerShellCommand(new powershell_1.FoundAutomationElement(element[base_driver_1.W3C_ELEMENT_KEY]).buildIsMultipleSelectCommand());
|
|
175
|
+
return result.toLowerCase() === 'true' ? true : false;
|
|
176
|
+
}
|
|
177
|
+
async function patternGetSelectedItem(element) {
|
|
178
|
+
const result = await this.sendPowerShellCommand(new powershell_1.FoundAutomationElement(element[base_driver_1.W3C_ELEMENT_KEY]).buildGetSelectionCommand());
|
|
179
|
+
const elId = result.split('\n').filter(Boolean)[0];
|
|
180
|
+
if (!elId) {
|
|
181
|
+
throw new base_driver_1.errors.NoSuchElementError();
|
|
182
|
+
}
|
|
183
|
+
return { [base_driver_1.W3C_ELEMENT_KEY]: elId };
|
|
184
|
+
}
|
|
185
|
+
async function patternGetAllSelectedItems(element) {
|
|
186
|
+
const result = await this.sendPowerShellCommand(new powershell_1.FoundAutomationElement(element[base_driver_1.W3C_ELEMENT_KEY]).buildGetSelectionCommand());
|
|
187
|
+
return result.split('\n').filter(Boolean).map((elId) => ({ [base_driver_1.W3C_ELEMENT_KEY]: elId }));
|
|
188
|
+
}
|
|
189
|
+
async function patternAddToSelection(element) {
|
|
190
|
+
await this.sendPowerShellCommand(new powershell_1.FoundAutomationElement(element[base_driver_1.W3C_ELEMENT_KEY]).buildAddToSelectionCommand());
|
|
191
|
+
}
|
|
192
|
+
async function patternRemoveFromSelection(element) {
|
|
193
|
+
await this.sendPowerShellCommand(new powershell_1.FoundAutomationElement(element[base_driver_1.W3C_ELEMENT_KEY]).buildRemoveFromSelectionCommand());
|
|
194
|
+
}
|
|
195
|
+
async function patternSelect(element) {
|
|
196
|
+
await this.sendPowerShellCommand(new powershell_1.FoundAutomationElement(element[base_driver_1.W3C_ELEMENT_KEY]).buildSelectCommand());
|
|
197
|
+
}
|
|
198
|
+
async function patternToggle(element) {
|
|
199
|
+
await this.sendPowerShellCommand(new powershell_1.FoundAutomationElement(element[base_driver_1.W3C_ELEMENT_KEY]).buildToggleCommand());
|
|
200
|
+
}
|
|
201
|
+
async function patternSetValue(element, value) {
|
|
202
|
+
try {
|
|
203
|
+
await this.sendPowerShellCommand(new powershell_1.FoundAutomationElement(element[base_driver_1.W3C_ELEMENT_KEY]).buildSetValueCommand(value));
|
|
204
|
+
}
|
|
205
|
+
catch {
|
|
206
|
+
await this.sendPowerShellCommand(new powershell_1.FoundAutomationElement(element[base_driver_1.W3C_ELEMENT_KEY]).buildSetRangeValueCommand(value));
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
async function patternGetValue(element) {
|
|
210
|
+
return await this.sendPowerShellCommand(new powershell_1.FoundAutomationElement(element[base_driver_1.W3C_ELEMENT_KEY]).buildGetValueCommand());
|
|
211
|
+
}
|
|
212
|
+
async function patternMaximize(element) {
|
|
213
|
+
await this.sendPowerShellCommand(new powershell_1.FoundAutomationElement(element[base_driver_1.W3C_ELEMENT_KEY]).buildMaximizeCommand());
|
|
214
|
+
}
|
|
215
|
+
async function patternMinimize(element) {
|
|
216
|
+
await this.sendPowerShellCommand(new powershell_1.FoundAutomationElement(element[base_driver_1.W3C_ELEMENT_KEY]).buildMinimizeCommand());
|
|
217
|
+
}
|
|
218
|
+
async function patternRestore(element) {
|
|
219
|
+
await this.sendPowerShellCommand(new powershell_1.FoundAutomationElement(element[base_driver_1.W3C_ELEMENT_KEY]).buildRestoreCommand());
|
|
220
|
+
}
|
|
221
|
+
async function patternClose(element) {
|
|
222
|
+
await this.sendPowerShellCommand(new powershell_1.FoundAutomationElement(element[base_driver_1.W3C_ELEMENT_KEY]).buildCloseCommand());
|
|
223
|
+
}
|
|
224
|
+
async function windowsCloseApp() {
|
|
225
|
+
return await this.closeApp();
|
|
226
|
+
}
|
|
227
|
+
async function windowsLaunchApp() {
|
|
228
|
+
return await this.launchApp();
|
|
229
|
+
}
|
|
230
|
+
async function focusElement(element) {
|
|
231
|
+
await this.sendPowerShellCommand(new powershell_1.FoundAutomationElement(element[base_driver_1.W3C_ELEMENT_KEY]).buildSetFocusCommand());
|
|
232
|
+
}
|
|
233
|
+
async function getClipboardBase64(contentType) {
|
|
234
|
+
if (!contentType || (contentType && typeof contentType === 'object')) {
|
|
235
|
+
contentType = contentType?.contentType ?? ContentType.PLAINTEXT;
|
|
236
|
+
}
|
|
237
|
+
switch (contentType.toLowerCase()) {
|
|
238
|
+
case ContentType.PLAINTEXT:
|
|
239
|
+
return await this.sendPowerShellCommand(GET_PLAINTEXT_CLIPBOARD_BASE64);
|
|
240
|
+
case ContentType.IMAGE:
|
|
241
|
+
return await this.sendPowerShellCommand(GET_IMAGE_CLIPBOARD_BASE64);
|
|
242
|
+
default:
|
|
243
|
+
throw new base_driver_1.errors.InvalidArgumentError(`Unsupported content type '${contentType}'.`);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
async function setClipboardFromBase64(args) {
|
|
247
|
+
if (!args || typeof args !== 'object' || !args.b64Content) {
|
|
248
|
+
throw new base_driver_1.errors.InvalidArgumentError(`'b64Content' must be provided.`);
|
|
249
|
+
}
|
|
250
|
+
const contentType = args.contentType ?? ContentType.PLAINTEXT;
|
|
251
|
+
switch (contentType.toLowerCase()) {
|
|
252
|
+
case ContentType.PLAINTEXT:
|
|
253
|
+
return await this.sendPowerShellCommand(SET_PLAINTEXT_CLIPBOARD_FROM_BASE64.format(`'${args.b64Content}'`));
|
|
254
|
+
case ContentType.IMAGE:
|
|
255
|
+
return await this.sendPowerShellCommand(SET_IMAGE_CLIPBOARD_FROM_BASE64.format(`'${args.b64Content}'`));
|
|
256
|
+
default:
|
|
257
|
+
throw new base_driver_1.errors.InvalidArgumentError(`Unsupported content type '${contentType}'.`);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
async function executePowerShellScript(script) {
|
|
261
|
+
if (script && typeof script === 'object') {
|
|
262
|
+
if (script.script) {
|
|
263
|
+
script = script.script;
|
|
264
|
+
}
|
|
265
|
+
else if (script.command) {
|
|
266
|
+
script = script.command;
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
throw new base_driver_1.errors.InvalidArgumentError('Either script or command must be provided.');
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
const scriptToExecute = (0, powershell_1.pwsh) `${script}`;
|
|
273
|
+
if (this.caps.isolatedScriptExecution) {
|
|
274
|
+
return await this.sendIsolatedPowerShellCommand(scriptToExecute);
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
return await this.sendPowerShellCommand(scriptToExecute);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
async function executeKeys(keyActions) {
|
|
281
|
+
if (!Array.isArray(keyActions.actions)) {
|
|
282
|
+
keyActions.actions = [keyActions.actions];
|
|
283
|
+
}
|
|
284
|
+
keyActions.forceUnicode ??= false;
|
|
285
|
+
for (const action of keyActions.actions) {
|
|
286
|
+
if (Number(!!action.pause) + Number(!!action.text) + Number(!!action.virtualKeyCode) !== 1) {
|
|
287
|
+
throw new base_driver_1.errors.InvalidArgumentError('Either pause, text or virtualKeyCode should be set.');
|
|
288
|
+
}
|
|
289
|
+
if (action.pause) {
|
|
290
|
+
await (0, util_1.sleep)(action.pause);
|
|
291
|
+
continue;
|
|
292
|
+
}
|
|
293
|
+
if (action.virtualKeyCode) {
|
|
294
|
+
if (action.down === undefined) {
|
|
295
|
+
(0, user32_1.sendKeyboardEvents)([{
|
|
296
|
+
wVk: action.virtualKeyCode,
|
|
297
|
+
wScan: 0,
|
|
298
|
+
dwFlags: 0,
|
|
299
|
+
time: 0,
|
|
300
|
+
dwExtraInfo: 0,
|
|
301
|
+
}, {
|
|
302
|
+
wVk: action.virtualKeyCode,
|
|
303
|
+
wScan: 0,
|
|
304
|
+
dwFlags: types_1.KeyEventFlags.KEYEVENTF_KEYUP,
|
|
305
|
+
time: 0,
|
|
306
|
+
dwExtraInfo: 0,
|
|
307
|
+
}]);
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
(0, user32_1.sendKeyboardEvents)([{
|
|
311
|
+
wVk: action.virtualKeyCode,
|
|
312
|
+
wScan: 0,
|
|
313
|
+
dwFlags: action.down ? 0 : types_1.KeyEventFlags.KEYEVENTF_KEYUP,
|
|
314
|
+
time: 0,
|
|
315
|
+
dwExtraInfo: 0,
|
|
316
|
+
}]);
|
|
317
|
+
}
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
320
|
+
for (const key of action.text ?? []) {
|
|
321
|
+
if (action.down !== undefined) {
|
|
322
|
+
if (action.down) {
|
|
323
|
+
(0, user32_1.keyDown)(key, keyActions.forceUnicode);
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
(0, user32_1.keyUp)(key, keyActions.forceUnicode);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
else {
|
|
330
|
+
(0, user32_1.keyDown)(key, keyActions.forceUnicode);
|
|
331
|
+
(0, user32_1.keyUp)(key, keyActions.forceUnicode);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
async function executeClick(clickArgs) {
|
|
337
|
+
const { elementId, x, y, button = enums_1.ClickType.LEFT, modifierKeys = [], durationMs = 0, times = 1, interClickDelayMs = 100, } = clickArgs;
|
|
338
|
+
if ((x != null) !== (y != null)) {
|
|
339
|
+
throw new base_driver_1.errors.InvalidArgumentError('Both x and y must be provided if either is set.');
|
|
340
|
+
}
|
|
341
|
+
let pos;
|
|
342
|
+
if (elementId) {
|
|
343
|
+
if (await this.sendPowerShellCommand(/* ps1 */ `$null -eq ${new powershell_1.FoundAutomationElement(elementId).toString()}`)) {
|
|
344
|
+
const condition = new powershell_1.PropertyCondition(powershell_1.Property.RUNTIME_ID, new powershell_1.PSInt32Array(elementId.split('.').map(Number)));
|
|
345
|
+
const elId = await this.sendPowerShellCommand(powershell_1.AutomationElement.automationRoot.findFirst(powershell_1.TreeScope.SUBTREE, condition).buildCommand());
|
|
346
|
+
if (elId.trim() === '') {
|
|
347
|
+
throw new base_driver_1.errors.NoSuchElementError();
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
const rectJson = await this.sendPowerShellCommand(new powershell_1.FoundAutomationElement(elementId).buildGetElementRectCommand());
|
|
351
|
+
const rect = JSON.parse(rectJson.replaceAll(/(?:infinity)/gi, 0x7FFFFFFF.toString()));
|
|
352
|
+
pos = [
|
|
353
|
+
rect.x + (x ?? Math.trunc(rect.width / 2)),
|
|
354
|
+
rect.y + (y ?? Math.trunc(rect.height / 2)),
|
|
355
|
+
];
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
359
|
+
pos = [x, y];
|
|
360
|
+
}
|
|
361
|
+
const clickTypeToButtonMapping = {
|
|
362
|
+
[enums_1.ClickType.LEFT]: 0,
|
|
363
|
+
[enums_1.ClickType.MIDDLE]: 1,
|
|
364
|
+
[enums_1.ClickType.RIGHT]: 2,
|
|
365
|
+
[enums_1.ClickType.BACK]: 3,
|
|
366
|
+
[enums_1.ClickType.FORWARD]: 4
|
|
367
|
+
};
|
|
368
|
+
const mouseButton = clickTypeToButtonMapping[button];
|
|
369
|
+
const processesModifierKeys = Array.isArray(modifierKeys) ? modifierKeys : [modifierKeys];
|
|
370
|
+
await (0, user32_1.mouseMoveAbsolute)(pos[0], pos[1], 0);
|
|
371
|
+
for (let i = 0; i < times; i++) {
|
|
372
|
+
if (i !== 0) {
|
|
373
|
+
await (0, util_1.sleep)(interClickDelayMs);
|
|
374
|
+
}
|
|
375
|
+
if (processesModifierKeys.some((key) => key.toLowerCase() === 'ctrl')) {
|
|
376
|
+
(0, user32_1.keyDown)(enums_1.Key.CONTROL);
|
|
377
|
+
}
|
|
378
|
+
if (processesModifierKeys.some((key) => key.toLowerCase() === 'alt')) {
|
|
379
|
+
(0, user32_1.keyDown)(enums_1.Key.ALT);
|
|
380
|
+
}
|
|
381
|
+
if (processesModifierKeys.some((key) => key.toLowerCase() === 'shift')) {
|
|
382
|
+
(0, user32_1.keyDown)(enums_1.Key.SHIFT);
|
|
383
|
+
}
|
|
384
|
+
if (processesModifierKeys.some((key) => key.toLowerCase() === 'win')) {
|
|
385
|
+
(0, user32_1.keyDown)(enums_1.Key.META);
|
|
386
|
+
}
|
|
387
|
+
(0, user32_1.mouseDown)(mouseButton);
|
|
388
|
+
if (durationMs > 0) {
|
|
389
|
+
await (0, util_1.sleep)(durationMs);
|
|
390
|
+
}
|
|
391
|
+
(0, user32_1.mouseUp)(mouseButton);
|
|
392
|
+
if (processesModifierKeys.some((key) => key.toLowerCase() === 'ctrl')) {
|
|
393
|
+
(0, user32_1.keyUp)(enums_1.Key.CONTROL);
|
|
394
|
+
}
|
|
395
|
+
if (processesModifierKeys.some((key) => key.toLowerCase() === 'alt')) {
|
|
396
|
+
(0, user32_1.keyUp)(enums_1.Key.ALT);
|
|
397
|
+
}
|
|
398
|
+
if (processesModifierKeys.some((key) => key.toLowerCase() === 'shift')) {
|
|
399
|
+
(0, user32_1.keyUp)(enums_1.Key.SHIFT);
|
|
400
|
+
}
|
|
401
|
+
if (processesModifierKeys.some((key) => key.toLowerCase() === 'win')) {
|
|
402
|
+
(0, user32_1.keyUp)(enums_1.Key.META);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
if (this.caps.delayAfterClick) {
|
|
406
|
+
await (0, util_1.sleep)(this.caps.delayAfterClick ?? 0);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
async function executeHover(hoverArgs) {
|
|
410
|
+
const { startElementId, startX, startY, endElementId, endX, endY, modifierKeys = [], durationMs = 500, } = hoverArgs;
|
|
411
|
+
if ((startX != null) !== (startY != null)) {
|
|
412
|
+
throw new base_driver_1.errors.InvalidArgumentError('Both startX and startY must be provided if either is set.');
|
|
413
|
+
}
|
|
414
|
+
if ((endX != null) !== (endY != null)) {
|
|
415
|
+
throw new base_driver_1.errors.InvalidArgumentError('Both endX and endY must be provided if either is set.');
|
|
416
|
+
}
|
|
417
|
+
const processesModifierKeys = Array.isArray(modifierKeys) ? modifierKeys : [modifierKeys];
|
|
418
|
+
let startPos;
|
|
419
|
+
if (startElementId) {
|
|
420
|
+
if (await this.sendPowerShellCommand(/* ps1 */ `$null -eq ${new powershell_1.FoundAutomationElement(startElementId).toString()}`)) {
|
|
421
|
+
const condition = new powershell_1.PropertyCondition(powershell_1.Property.RUNTIME_ID, new powershell_1.PSInt32Array(startElementId.split('.').map(Number)));
|
|
422
|
+
const elId = await this.sendPowerShellCommand(powershell_1.AutomationElement.automationRoot.findFirst(powershell_1.TreeScope.SUBTREE, condition).buildCommand());
|
|
423
|
+
if (elId.trim() === '') {
|
|
424
|
+
throw new base_driver_1.errors.NoSuchElementError();
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
const rectJson = await this.sendPowerShellCommand(new powershell_1.FoundAutomationElement(startElementId).buildGetElementRectCommand());
|
|
428
|
+
const rect = JSON.parse(rectJson.replaceAll(/(?:infinity)/gi, 0x7FFFFFFF.toString()));
|
|
429
|
+
startPos = [
|
|
430
|
+
rect.x + (startX ?? rect.width / 2),
|
|
431
|
+
rect.y + (startY ?? rect.height / 2)
|
|
432
|
+
];
|
|
433
|
+
}
|
|
434
|
+
else {
|
|
435
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
436
|
+
startPos = [startX, startY];
|
|
437
|
+
}
|
|
438
|
+
let endPos;
|
|
439
|
+
if (endElementId) {
|
|
440
|
+
if (await this.sendPowerShellCommand(/* ps1 */ `$null -eq ${new powershell_1.FoundAutomationElement(endElementId).toString()}`)) {
|
|
441
|
+
const condition = new powershell_1.PropertyCondition(powershell_1.Property.RUNTIME_ID, new powershell_1.PSInt32Array(endElementId.split('.').map(Number)));
|
|
442
|
+
const elId = await this.sendPowerShellCommand(powershell_1.AutomationElement.automationRoot.findFirst(powershell_1.TreeScope.SUBTREE, condition).buildCommand());
|
|
443
|
+
if (elId.trim() === '') {
|
|
444
|
+
throw new base_driver_1.errors.NoSuchElementError();
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
const rectJson = await this.sendPowerShellCommand(new powershell_1.FoundAutomationElement(endElementId).buildGetElementRectCommand());
|
|
448
|
+
const rect = JSON.parse(rectJson.replaceAll(/(?:infinity)/gi, 0x7FFFFFFF.toString()));
|
|
449
|
+
endPos = [
|
|
450
|
+
rect.x + (endX ?? rect.width / 2),
|
|
451
|
+
rect.y + (endY ?? rect.height / 2)
|
|
452
|
+
];
|
|
453
|
+
}
|
|
454
|
+
else {
|
|
455
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
456
|
+
endPos = [endX, endY];
|
|
457
|
+
}
|
|
458
|
+
await (0, user32_1.mouseMoveAbsolute)(startPos[0], startPos[1], 0);
|
|
459
|
+
if (processesModifierKeys.some((key) => key.toLowerCase() === 'ctrl')) {
|
|
460
|
+
(0, user32_1.keyDown)(enums_1.Key.CONTROL);
|
|
461
|
+
}
|
|
462
|
+
if (processesModifierKeys.some((key) => key.toLowerCase() === 'alt')) {
|
|
463
|
+
(0, user32_1.keyDown)(enums_1.Key.ALT);
|
|
464
|
+
}
|
|
465
|
+
if (processesModifierKeys.some((key) => key.toLowerCase() === 'shift')) {
|
|
466
|
+
(0, user32_1.keyDown)(enums_1.Key.SHIFT);
|
|
467
|
+
}
|
|
468
|
+
if (processesModifierKeys.some((key) => key.toLowerCase() === 'win')) {
|
|
469
|
+
(0, user32_1.keyDown)(enums_1.Key.META);
|
|
470
|
+
}
|
|
471
|
+
await (0, user32_1.mouseMoveAbsolute)(endPos[0], endPos[1], durationMs, this.caps.smoothPointerMove);
|
|
472
|
+
if (processesModifierKeys.some((key) => key.toLowerCase() === 'ctrl')) {
|
|
473
|
+
(0, user32_1.keyUp)(enums_1.Key.CONTROL);
|
|
474
|
+
}
|
|
475
|
+
if (processesModifierKeys.some((key) => key.toLowerCase() === 'alt')) {
|
|
476
|
+
(0, user32_1.keyUp)(enums_1.Key.ALT);
|
|
477
|
+
}
|
|
478
|
+
if (processesModifierKeys.some((key) => key.toLowerCase() === 'shift')) {
|
|
479
|
+
(0, user32_1.keyUp)(enums_1.Key.SHIFT);
|
|
480
|
+
}
|
|
481
|
+
if (processesModifierKeys.some((key) => key.toLowerCase() === 'win')) {
|
|
482
|
+
(0, user32_1.keyUp)(enums_1.Key.META);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
async function executeScroll(scrollArgs) {
|
|
486
|
+
const { elementId, x, y, deltaX, deltaY, modifierKeys = [], } = scrollArgs;
|
|
487
|
+
if (!!elementId && ((x !== null && x !== undefined) || (y !== null && y !== undefined))) {
|
|
488
|
+
throw new base_driver_1.errors.InvalidArgumentError('Either elementId or x and y must be provided.');
|
|
489
|
+
}
|
|
490
|
+
if ((x !== null && x !== undefined) !== (y !== null && y !== undefined)) {
|
|
491
|
+
throw new base_driver_1.errors.InvalidArgumentError('Both x and y must be provided.');
|
|
492
|
+
}
|
|
493
|
+
const processesModifierKeys = Array.isArray(modifierKeys) ? modifierKeys : [modifierKeys];
|
|
494
|
+
let pos;
|
|
495
|
+
if (elementId) {
|
|
496
|
+
if (await this.sendPowerShellCommand(/* ps1 */ `$null -eq ${new powershell_1.FoundAutomationElement(elementId).toString()}`)) {
|
|
497
|
+
const condition = new powershell_1.PropertyCondition(powershell_1.Property.RUNTIME_ID, new powershell_1.PSInt32Array(elementId.split('.').map(Number)));
|
|
498
|
+
const elId = await this.sendPowerShellCommand(powershell_1.AutomationElement.automationRoot.findFirst(powershell_1.TreeScope.SUBTREE, condition).buildCommand());
|
|
499
|
+
if (elId.trim() === '') {
|
|
500
|
+
throw new base_driver_1.errors.NoSuchElementError();
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
const rectJson = await this.sendPowerShellCommand(new powershell_1.FoundAutomationElement(elementId).buildGetElementRectCommand());
|
|
504
|
+
const rect = JSON.parse(rectJson.replaceAll(/(?:infinity)/gi, 0x7FFFFFFF.toString()));
|
|
505
|
+
pos = [rect.x + (rect.width / 2), rect.y + (rect.height / 2)];
|
|
506
|
+
}
|
|
507
|
+
else {
|
|
508
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
509
|
+
pos = [x, y];
|
|
510
|
+
}
|
|
511
|
+
await (0, user32_1.mouseMoveAbsolute)(pos[0], pos[1], 0);
|
|
512
|
+
if (processesModifierKeys.some((key) => key.toLowerCase() === 'ctrl')) {
|
|
513
|
+
(0, user32_1.keyDown)(enums_1.Key.CONTROL);
|
|
514
|
+
}
|
|
515
|
+
if (processesModifierKeys.some((key) => key.toLowerCase() === 'alt')) {
|
|
516
|
+
(0, user32_1.keyDown)(enums_1.Key.ALT);
|
|
517
|
+
}
|
|
518
|
+
if (processesModifierKeys.some((key) => key.toLowerCase() === 'shift')) {
|
|
519
|
+
(0, user32_1.keyDown)(enums_1.Key.SHIFT);
|
|
520
|
+
}
|
|
521
|
+
if (processesModifierKeys.some((key) => key.toLowerCase() === 'win')) {
|
|
522
|
+
(0, user32_1.keyDown)(enums_1.Key.META);
|
|
523
|
+
}
|
|
524
|
+
(0, user32_1.mouseScroll)(deltaX ?? 0, deltaY ?? 0);
|
|
525
|
+
if (processesModifierKeys.some((key) => key.toLowerCase() === 'ctrl')) {
|
|
526
|
+
(0, user32_1.keyUp)(enums_1.Key.CONTROL);
|
|
527
|
+
}
|
|
528
|
+
if (processesModifierKeys.some((key) => key.toLowerCase() === 'alt')) {
|
|
529
|
+
(0, user32_1.keyUp)(enums_1.Key.ALT);
|
|
530
|
+
}
|
|
531
|
+
if (processesModifierKeys.some((key) => key.toLowerCase() === 'shift')) {
|
|
532
|
+
(0, user32_1.keyUp)(enums_1.Key.SHIFT);
|
|
533
|
+
}
|
|
534
|
+
if (processesModifierKeys.some((key) => key.toLowerCase() === 'win')) {
|
|
535
|
+
(0, user32_1.keyUp)(enums_1.Key.META);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
async function startRecordingScreen(args) {
|
|
539
|
+
const { outputPath, timeLimit, videoFps: fps, videoFilter, preset, captureCursor, captureClicks, audioInput, forceRestart = true, } = args ?? {};
|
|
540
|
+
if (this._screenRecorder?.isRunning()) {
|
|
541
|
+
this.log.debug('The screen recording is already running');
|
|
542
|
+
if (!forceRestart) {
|
|
543
|
+
this.log.debug('Doing nothing');
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
this.log.debug('Forcing the active screen recording to stop');
|
|
547
|
+
await this._screenRecorder.stop(true);
|
|
548
|
+
}
|
|
549
|
+
else if (this._screenRecorder) {
|
|
550
|
+
this.log.debug('Clearing the recent screen recording');
|
|
551
|
+
await this._screenRecorder.stop(true);
|
|
552
|
+
}
|
|
553
|
+
this._screenRecorder = null;
|
|
554
|
+
if (outputPath) {
|
|
555
|
+
const ext = (0, node_path_1.extname)(outputPath).toLowerCase();
|
|
556
|
+
if (ext !== `.${screen_recorder_1.DEFAULT_EXT}`) {
|
|
557
|
+
throw new base_driver_1.errors.InvalidArgumentError(`outputPath must be a path to a .${screen_recorder_1.DEFAULT_EXT} file, got: '${outputPath}'`);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
const videoPath = outputPath ?? (0, node_path_1.join)((0, node_os_1.tmpdir)(), `novawindows-recording-${Date.now()}.${screen_recorder_1.DEFAULT_EXT}`);
|
|
561
|
+
this._screenRecorder = new screen_recorder_1.ScreenRecorder(videoPath, this.log, {
|
|
562
|
+
fps: fps !== undefined ? parseInt(String(fps), 10) : undefined,
|
|
563
|
+
timeLimit: timeLimit !== undefined ? parseInt(String(timeLimit), 10) : undefined,
|
|
564
|
+
preset,
|
|
565
|
+
captureCursor,
|
|
566
|
+
captureClicks,
|
|
567
|
+
videoFilter,
|
|
568
|
+
audioInput,
|
|
569
|
+
});
|
|
570
|
+
try {
|
|
571
|
+
await this._screenRecorder.start();
|
|
572
|
+
}
|
|
573
|
+
catch (e) {
|
|
574
|
+
this._screenRecorder = null;
|
|
575
|
+
throw e;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
async function stopRecordingScreen(args) {
|
|
579
|
+
if (!this._screenRecorder) {
|
|
580
|
+
this.log.debug('No screen recording has been started. Doing nothing');
|
|
581
|
+
return '';
|
|
582
|
+
}
|
|
583
|
+
this.log.debug('Retrieving the resulting video data');
|
|
584
|
+
const videoPath = await this._screenRecorder.stop();
|
|
585
|
+
if (!videoPath) {
|
|
586
|
+
this.log.debug('No video data is found. Returning an empty string');
|
|
587
|
+
return '';
|
|
588
|
+
}
|
|
589
|
+
const { remotePath, ...uploadOpts } = args ?? {};
|
|
590
|
+
return await (0, screen_recorder_1.uploadRecordedMedia)(videoPath, remotePath, uploadOpts);
|
|
591
|
+
}
|
|
592
|
+
async function deleteFile(args) {
|
|
593
|
+
this.assertFeatureEnabled(constants_1.MODIFY_FS_FEATURE);
|
|
594
|
+
if (!args || typeof args !== 'object' || !args.path) {
|
|
595
|
+
throw new base_driver_1.errors.InvalidArgumentError("'path' must be provided.");
|
|
596
|
+
}
|
|
597
|
+
const escapedPath = args.path.replace(/'/g, "''");
|
|
598
|
+
const useLiteralPath = /[[\][]?]/.test(args.path);
|
|
599
|
+
const pathParam = useLiteralPath ? `-LiteralPath '${escapedPath}'` : `-Path '${escapedPath}'`;
|
|
600
|
+
await this.sendPowerShellCommand(`Remove-Item ${pathParam} -Force -ErrorAction Stop`);
|
|
601
|
+
}
|
|
602
|
+
async function deleteFolder(args) {
|
|
603
|
+
this.assertFeatureEnabled(constants_1.MODIFY_FS_FEATURE);
|
|
604
|
+
if (!args || typeof args !== 'object' || !args.path) {
|
|
605
|
+
throw new base_driver_1.errors.InvalidArgumentError("'path' must be provided.");
|
|
606
|
+
}
|
|
607
|
+
const { path: pathArg, recursive = true } = args;
|
|
608
|
+
const escapedPath = pathArg.replace(/'/g, "''");
|
|
609
|
+
const useLiteralPath = /[[\][]?]/.test(pathArg);
|
|
610
|
+
const pathParam = useLiteralPath ? `-LiteralPath '${escapedPath}'` : `-Path '${escapedPath}'`;
|
|
611
|
+
const recurseFlag = recursive ? ' -Recurse' : '';
|
|
612
|
+
await this.sendPowerShellCommand(`Remove-Item ${pathParam} -Force${recurseFlag} -ErrorAction Stop`);
|
|
613
|
+
}
|
|
614
|
+
async function executeClickAndDrag(dragArgs) {
|
|
615
|
+
const { startElementId, startX, startY, endElementId, endX, endY, modifierKeys = [], durationMs = 500, button = enums_1.ClickType.LEFT, } = dragArgs ?? {};
|
|
616
|
+
if ((startX != null) !== (startY != null)) {
|
|
617
|
+
throw new base_driver_1.errors.InvalidArgumentError('Both startX and startY must be provided if either is set.');
|
|
618
|
+
}
|
|
619
|
+
if ((endX != null) !== (endY != null)) {
|
|
620
|
+
throw new base_driver_1.errors.InvalidArgumentError('Both endX and endY must be provided if either is set.');
|
|
621
|
+
}
|
|
622
|
+
const processesModifierKeys = Array.isArray(modifierKeys) ? modifierKeys : [modifierKeys];
|
|
623
|
+
const clickTypeToButtonMapping = {
|
|
624
|
+
[enums_1.ClickType.LEFT]: 0,
|
|
625
|
+
[enums_1.ClickType.MIDDLE]: 1,
|
|
626
|
+
[enums_1.ClickType.RIGHT]: 2,
|
|
627
|
+
[enums_1.ClickType.BACK]: 3,
|
|
628
|
+
[enums_1.ClickType.FORWARD]: 4,
|
|
629
|
+
};
|
|
630
|
+
const mouseButton = clickTypeToButtonMapping[button];
|
|
631
|
+
let startPos;
|
|
632
|
+
if (startElementId) {
|
|
633
|
+
if (await this.sendPowerShellCommand(/* ps1 */ `$null -eq ${new powershell_1.FoundAutomationElement(startElementId).toString()}`)) {
|
|
634
|
+
const condition = new powershell_1.PropertyCondition(powershell_1.Property.RUNTIME_ID, new powershell_1.PSInt32Array(startElementId.split('.').map(Number)));
|
|
635
|
+
const elId = await this.sendPowerShellCommand(powershell_1.AutomationElement.automationRoot.findFirst(powershell_1.TreeScope.SUBTREE, condition).buildCommand());
|
|
636
|
+
if (elId.trim() === '') {
|
|
637
|
+
throw new base_driver_1.errors.NoSuchElementError();
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
const rectJson = await this.sendPowerShellCommand(new powershell_1.FoundAutomationElement(startElementId).buildGetElementRectCommand());
|
|
641
|
+
const rect = JSON.parse(rectJson.replaceAll(/(?:infinity)/gi, 0x7FFFFFFF.toString()));
|
|
642
|
+
startPos = [
|
|
643
|
+
rect.x + (startX ?? rect.width / 2),
|
|
644
|
+
rect.y + (startY ?? rect.height / 2)
|
|
645
|
+
];
|
|
646
|
+
}
|
|
647
|
+
else {
|
|
648
|
+
if (startX == null || startY == null) {
|
|
649
|
+
throw new base_driver_1.errors.InvalidArgumentError('Either startElementId or startX and startY must be provided.');
|
|
650
|
+
}
|
|
651
|
+
startPos = [startX, startY];
|
|
652
|
+
}
|
|
653
|
+
let endPos;
|
|
654
|
+
if (endElementId) {
|
|
655
|
+
if (await this.sendPowerShellCommand(/* ps1 */ `$null -eq ${new powershell_1.FoundAutomationElement(endElementId).toString()}`)) {
|
|
656
|
+
const condition = new powershell_1.PropertyCondition(powershell_1.Property.RUNTIME_ID, new powershell_1.PSInt32Array(endElementId.split('.').map(Number)));
|
|
657
|
+
const elId = await this.sendPowerShellCommand(powershell_1.AutomationElement.automationRoot.findFirst(powershell_1.TreeScope.SUBTREE, condition).buildCommand());
|
|
658
|
+
if (elId.trim() === '') {
|
|
659
|
+
throw new base_driver_1.errors.NoSuchElementError();
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
const rectJson = await this.sendPowerShellCommand(new powershell_1.FoundAutomationElement(endElementId).buildGetElementRectCommand());
|
|
663
|
+
const rect = JSON.parse(rectJson.replaceAll(/(?:infinity)/gi, 0x7FFFFFFF.toString()));
|
|
664
|
+
endPos = [
|
|
665
|
+
rect.x + (endX ?? rect.width / 2),
|
|
666
|
+
rect.y + (endY ?? rect.height / 2)
|
|
667
|
+
];
|
|
668
|
+
}
|
|
669
|
+
else {
|
|
670
|
+
if (endX == null || endY == null) {
|
|
671
|
+
throw new base_driver_1.errors.InvalidArgumentError('Either endElementId or endX and endY must be provided.');
|
|
672
|
+
}
|
|
673
|
+
endPos = [endX, endY];
|
|
674
|
+
}
|
|
675
|
+
await (0, user32_1.mouseMoveAbsolute)(startPos[0], startPos[1], 0);
|
|
676
|
+
if (processesModifierKeys.some((key) => key.toLowerCase() === 'ctrl')) {
|
|
677
|
+
(0, user32_1.keyDown)(enums_1.Key.CONTROL);
|
|
678
|
+
}
|
|
679
|
+
if (processesModifierKeys.some((key) => key.toLowerCase() === 'alt')) {
|
|
680
|
+
(0, user32_1.keyDown)(enums_1.Key.ALT);
|
|
681
|
+
}
|
|
682
|
+
if (processesModifierKeys.some((key) => key.toLowerCase() === 'shift')) {
|
|
683
|
+
(0, user32_1.keyDown)(enums_1.Key.SHIFT);
|
|
684
|
+
}
|
|
685
|
+
if (processesModifierKeys.some((key) => key.toLowerCase() === 'win')) {
|
|
686
|
+
(0, user32_1.keyDown)(enums_1.Key.META);
|
|
687
|
+
}
|
|
688
|
+
(0, user32_1.mouseDown)(mouseButton);
|
|
689
|
+
await (0, user32_1.mouseMoveAbsolute)(endPos[0], endPos[1], durationMs, this.caps.smoothPointerMove);
|
|
690
|
+
(0, user32_1.mouseUp)(mouseButton);
|
|
691
|
+
if (processesModifierKeys.some((key) => key.toLowerCase() === 'ctrl')) {
|
|
692
|
+
(0, user32_1.keyUp)(enums_1.Key.CONTROL);
|
|
693
|
+
}
|
|
694
|
+
if (processesModifierKeys.some((key) => key.toLowerCase() === 'alt')) {
|
|
695
|
+
(0, user32_1.keyUp)(enums_1.Key.ALT);
|
|
696
|
+
}
|
|
697
|
+
if (processesModifierKeys.some((key) => key.toLowerCase() === 'shift')) {
|
|
698
|
+
(0, user32_1.keyUp)(enums_1.Key.SHIFT);
|
|
699
|
+
}
|
|
700
|
+
if (processesModifierKeys.some((key) => key.toLowerCase() === 'win')) {
|
|
701
|
+
(0, user32_1.keyUp)(enums_1.Key.META);
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
async function windowsGetDeviceTime(args) {
|
|
705
|
+
return this.getDeviceTime(undefined, args?.format);
|
|
706
|
+
}
|
|
707
|
+
async function getWindowElement() {
|
|
708
|
+
const result = await this.sendPowerShellCommand(powershell_1.AutomationElement.automationRoot.buildCommand());
|
|
709
|
+
const elementId = result.split('\n').map((id) => id.trim()).filter(Boolean)[0];
|
|
710
|
+
if (!elementId) {
|
|
711
|
+
throw new base_driver_1.errors.NoSuchWindowError('No active app window is found for this session.');
|
|
712
|
+
}
|
|
713
|
+
return { [base_driver_1.W3C_ELEMENT_KEY]: elementId };
|
|
714
|
+
}
|
|
715
|
+
//# sourceMappingURL=extension.js.map
|