forked from stoneman/appium-windows-driver
-
Notifications
You must be signed in to change notification settings - Fork 37
Expand file tree
/
Copy pathfile-movement.js
More file actions
174 lines (161 loc) · 5.03 KB
/
file-movement.js
File metadata and controls
174 lines (161 loc) · 5.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
import _ from 'lodash';
import path from 'node:path';
import {errors} from 'appium/driver';
import {fs, mkdirp, util, zip} from 'appium/support';
import {MODIFY_FS_FEATURE} from '../constants';
// List of env variables, that can be expanded in path
const KNOWN_ENV_VARS = [
'APPDATA',
'LOCALAPPDATA',
'PROGRAMFILES',
'PROGRAMFILES(X86)',
'PROGRAMDATA',
'ALLUSERSPROFILE',
'TEMP',
'TMP',
'HOMEPATH',
'USERPROFILE',
'PUBLIC',
];
/**
*
* @this {WindowsDriver}
* @param {string} remotePath
* @param {string} base64Data
* @returns {Promise<void>}
*/
export async function pushFile(remotePath, base64Data) {
this.assertFeatureEnabled(MODIFY_FS_FEATURE);
if (remotePath.endsWith(path.sep)) {
throw new errors.InvalidArgumentError(
'It is expected that remote path points to a file rather than a folder. ' +
`'${remotePath}' is given instead`,
);
}
if (_.isArray(base64Data)) {
// some clients (ahem) java, send a byte array encoding utf8 characters
// instead of a string, which would be infinitely better!
base64Data = Buffer.from(base64Data).toString('utf8');
}
const fullPath = resolveToAbsolutePath(remotePath);
await mkdirp(path.dirname(fullPath));
const content = Buffer.from(base64Data, 'base64');
await fs.writeFile(fullPath, content);
}
/**
*
* @this {WindowsDriver}
* @param {string} remotePath
* @returns {Promise<string>}
*/
export async function pullFile(remotePath) {
const fullPath = resolveToAbsolutePath(remotePath);
await checkFileExists(fullPath);
return (await util.toInMemoryBase64(fullPath)).toString();
}
/**
*
* @this {WindowsDriver}
* @param {string} remotePath
* @returns {Promise<string>}
*/
export async function pullFolder(remotePath) {
const fullPath = resolveToAbsolutePath(remotePath);
await checkFolderExists(fullPath);
return (
await zip.toInMemoryZip(fullPath, {
encodeToBase64: true,
})
).toString();
}
/**
* Remove the file from the file system
*
* @this {WindowsDriver}
* @param {string} remotePath - The path to a file.
* The path may contain environment variables that could be expanded on the server side.
* Due to security reasons only variables listed below would be expanded: `APPDATA`,
* `LOCALAPPDATA`, `PROGRAMFILES`, `PROGRAMFILES(X86)`, `PROGRAMDATA`, `ALLUSERSPROFILE`,
* `TEMP`, `TMP`, `HOMEPATH`, `USERPROFILE`, `PUBLIC`.
* @throws {InvalidArgumentError} If the file to be deleted does not exist or
* remote path is not an absolute path.
*/
export async function windowsDeleteFile(remotePath) {
this.assertFeatureEnabled(MODIFY_FS_FEATURE);
const fullPath = resolveToAbsolutePath(remotePath);
await checkFileExists(fullPath);
await fs.unlink(fullPath);
}
/**
* Remove the folder from the file system
*
* @this {WindowsDriver}
* @param {string} remotePath - The path to a folder.
* The path may contain environment variables that could be expanded on the server side.
* Due to security reasons only variables listed below would be expanded: `APPDATA`,
* `LOCALAPPDATA`, `PROGRAMFILES`, `PROGRAMFILES(X86)`, `PROGRAMDATA`, `ALLUSERSPROFILE`,
* `TEMP`, `TMP`, `HOMEPATH`, `USERPROFILE`, `PUBLIC`.
* @throws {InvalidArgumentError} If the folder to be deleted does not exist or
* remote path is not an absolute path.
*/
export async function windowsDeleteFolder(remotePath) {
this.assertFeatureEnabled(MODIFY_FS_FEATURE);
const fullPath = resolveToAbsolutePath(remotePath);
await checkFolderExists(fullPath);
await fs.rimraf(fullPath);
}
/**
*
* @param {string} remotePath
* @returns {string}
*/
function resolveToAbsolutePath(remotePath) {
const resolvedPath = remotePath.replace(/%([^%]+)%/g, (_, key) =>
KNOWN_ENV_VARS.includes(key.toUpperCase())
? /** @type {string} */ (process.env[key.toUpperCase()])
: `%${key}%`,
);
if (!path.isAbsolute(resolvedPath)) {
throw new errors.InvalidArgumentError(
'It is expected that remote path is absolute. ' + `'${resolvedPath}' is given instead`,
);
}
return resolvedPath;
}
/**
*
* @param {string} remotePath
* @returns {Promise<void>}
*/
async function checkFileExists(remotePath) {
if (!(await fs.exists(remotePath))) {
throw new errors.InvalidArgumentError(`The remote file '${remotePath}' does not exist.`);
}
const stat = await fs.stat(remotePath);
if (!stat.isFile()) {
throw new errors.InvalidArgumentError(
'It is expected that remote path points to a file rather than a folder. ' +
`'${remotePath}' is given instead`,
);
}
}
/**
*
* @param {string} remotePath
* @returns {Promise<void>}
*/
async function checkFolderExists(remotePath) {
if (!(await fs.exists(remotePath))) {
throw new errors.InvalidArgumentError(`The remote folder '${remotePath}' does not exist.`);
}
const stat = await fs.stat(remotePath);
if (!stat.isDirectory()) {
throw new errors.InvalidArgumentError(
'It is expected that remote path points to a folder rather than a file. ' +
`'${remotePath}' is given instead`,
);
}
}
/**
* @typedef {import('../driver').WindowsDriver} WindowsDriver
*/