appium-xcuitest-driver 7.22.1 → 7.23.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/CHANGELOG.md +6 -0
- package/build/lib/commands/certificate.js +4 -4
- package/build/lib/commands/certificate.js.map +1 -1
- package/build/lib/commands/log.d.ts.map +1 -1
- package/build/lib/commands/log.js +2 -1
- package/build/lib/commands/log.js.map +1 -1
- package/build/lib/commands/memory.js +1 -1
- package/build/lib/commands/memory.js.map +1 -1
- package/build/lib/commands/pcap.d.ts.map +1 -1
- package/build/lib/commands/pcap.js +3 -7
- package/build/lib/commands/pcap.js.map +1 -1
- package/build/lib/device-log/helpers.d.ts +4 -0
- package/build/lib/device-log/helpers.d.ts.map +1 -1
- package/build/lib/device-log/helpers.js +22 -0
- package/build/lib/device-log/helpers.js.map +1 -1
- package/build/lib/device-log/ios-crash-log.d.ts +30 -38
- package/build/lib/device-log/ios-crash-log.d.ts.map +1 -1
- package/build/lib/device-log/ios-crash-log.js +97 -100
- package/build/lib/device-log/ios-crash-log.js.map +1 -1
- package/build/lib/device-log/ios-log.d.ts +1 -1
- package/build/lib/device-log/ios-log.d.ts.map +1 -1
- package/build/lib/device-log/ios-log.js +2 -1
- package/build/lib/device-log/ios-log.js.map +1 -1
- package/build/lib/driver.d.ts +4 -2
- package/build/lib/driver.d.ts.map +1 -1
- package/build/lib/driver.js +2 -2
- package/build/lib/driver.js.map +1 -1
- package/build/lib/real-device-clients/base-device-client.d.ts +22 -0
- package/build/lib/real-device-clients/base-device-client.d.ts.map +1 -0
- package/build/lib/real-device-clients/base-device-client.js +13 -0
- package/build/lib/real-device-clients/base-device-client.js.map +1 -0
- package/build/lib/real-device-clients/devicectl.d.ts.map +1 -0
- package/build/lib/real-device-clients/devicectl.js.map +1 -0
- package/build/lib/real-device-clients/py-ios-device-client.d.ts +21 -0
- package/build/lib/real-device-clients/py-ios-device-client.d.ts.map +1 -0
- package/build/lib/{py-ios-device-client.js → real-device-clients/py-ios-device-client.js} +53 -84
- package/build/lib/real-device-clients/py-ios-device-client.js.map +1 -0
- package/build/lib/real-device.d.ts +1 -1
- package/build/lib/real-device.d.ts.map +1 -1
- package/build/lib/real-device.js +1 -1
- package/build/lib/real-device.js.map +1 -1
- package/lib/commands/certificate.js +1 -1
- package/lib/commands/log.js +2 -1
- package/lib/commands/memory.js +1 -1
- package/lib/commands/pcap.js +3 -4
- package/lib/device-log/helpers.ts +27 -0
- package/lib/device-log/ios-crash-log.ts +167 -0
- package/lib/device-log/ios-log.ts +2 -1
- package/lib/driver.js +1 -1
- package/lib/real-device-clients/base-device-client.ts +34 -0
- package/lib/real-device-clients/py-ios-device-client.ts +149 -0
- package/lib/real-device.js +1 -1
- package/npm-shrinkwrap.json +9 -9
- package/package.json +1 -1
- package/build/lib/devicectl.d.ts.map +0 -1
- package/build/lib/devicectl.js.map +0 -1
- package/build/lib/py-ios-device-client.d.ts +0 -76
- package/build/lib/py-ios-device-client.d.ts.map +0 -1
- package/build/lib/py-ios-device-client.js.map +0 -1
- package/lib/device-log/ios-crash-log.js +0 -146
- package/lib/py-ios-device-client.js +0 -167
- /package/build/lib/{devicectl.d.ts → real-device-clients/devicectl.d.ts} +0 -0
- /package/build/lib/{devicectl.js → real-device-clients/devicectl.js} +0 -0
- /package/lib/{devicectl.js → real-device-clients/devicectl.js} +0 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import {exec, SubProcess} from 'teen_process';
|
|
2
|
+
import {fs, util, tempDir} from 'appium/support';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { BaseDeviceClient } from './base-device-client';
|
|
5
|
+
import type { BaseDeviceClientOptions, InstallProfileArgs } from './base-device-client';
|
|
6
|
+
import type { TeenProcessExecResult } from 'teen_process';
|
|
7
|
+
import type { CertificateList } from '../commands/types';
|
|
8
|
+
|
|
9
|
+
// https://github.com/YueChen-C/py-ios-device
|
|
10
|
+
|
|
11
|
+
const BINARY_NAME = 'pyidevice';
|
|
12
|
+
const CRASH_REPORT_EXT = '.ips';
|
|
13
|
+
|
|
14
|
+
export interface PyideviceOptions extends BaseDeviceClientOptions {
|
|
15
|
+
udid: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface ExecuteOptions {
|
|
19
|
+
cwd?: string;
|
|
20
|
+
format?: string | null;
|
|
21
|
+
logStdout?: boolean;
|
|
22
|
+
asynchronous?: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export class Pyidevice extends BaseDeviceClient {
|
|
26
|
+
private readonly _udid: string;
|
|
27
|
+
private _binaryPath: string | null;
|
|
28
|
+
|
|
29
|
+
constructor(opts: PyideviceOptions) {
|
|
30
|
+
super({log: opts.log});
|
|
31
|
+
this._udid = opts.udid;
|
|
32
|
+
this._binaryPath = null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
override async assertExists(isStrict = true): Promise<boolean> {
|
|
36
|
+
if (this._binaryPath) {
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
this._binaryPath = await fs.which(BINARY_NAME);
|
|
42
|
+
return true;
|
|
43
|
+
} catch (e) {
|
|
44
|
+
if (isStrict) {
|
|
45
|
+
throw new Error(
|
|
46
|
+
`${BINARY_NAME} binary cannot be found in PATH. ` +
|
|
47
|
+
`Please make sure it is installed. Visit https://github.com/YueChen-C/py-ios-device for ` +
|
|
48
|
+
`more details.`,
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
override async listProfiles(): Promise<CertificateList> {
|
|
56
|
+
const {stdout} = await this.execute(['profiles', 'list']) as TeenProcessExecResult<string>;
|
|
57
|
+
return JSON.parse(stdout);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
override async installProfile(args: InstallProfileArgs): Promise<void> {
|
|
61
|
+
const {profilePath, payload} = args;
|
|
62
|
+
if (!profilePath && !payload) {
|
|
63
|
+
throw new Error('Either the full path to the profile or its payload must be provided');
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
let tmpRoot: string | undefined;
|
|
67
|
+
let srcPath = profilePath;
|
|
68
|
+
try {
|
|
69
|
+
if (!srcPath) {
|
|
70
|
+
tmpRoot = await tempDir.openDir();
|
|
71
|
+
srcPath = path.join(tmpRoot, 'cert.pem');
|
|
72
|
+
if (Buffer.isBuffer(payload)) {
|
|
73
|
+
await fs.writeFile(srcPath, payload);
|
|
74
|
+
} else {
|
|
75
|
+
await fs.writeFile(srcPath, payload as string, 'utf8');
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
await this.execute(['profiles', 'install', '--path', srcPath], {
|
|
79
|
+
logStdout: true,
|
|
80
|
+
});
|
|
81
|
+
} finally {
|
|
82
|
+
if (tmpRoot) {
|
|
83
|
+
await fs.rimraf(tmpRoot);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
override async removeProfile(name: string): Promise<string> {
|
|
89
|
+
return (
|
|
90
|
+
await this.execute(['profiles', 'remove', '--name', name], {logStdout: true}) as TeenProcessExecResult<string>
|
|
91
|
+
).stdout;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
override async listCrashes(): Promise<string[]> {
|
|
95
|
+
const {stdout} = await this.execute(['crash', 'list']) as TeenProcessExecResult<string>;
|
|
96
|
+
// Example output:
|
|
97
|
+
// ['.', '..', 'SiriSearchFeedback-2023-12-06-144043.ips', '
|
|
98
|
+
// SiriSearchFeedback-2024-05-22-194219.ips', 'JetsamEvent-2024-05-23-225056.ips',
|
|
99
|
+
// 'JetsamEvent-2023-09-18-090920.ips', 'JetsamEvent-2024-05-16-054529.ips',
|
|
100
|
+
// 'Assistant']
|
|
101
|
+
return JSON.parse(stdout.replace(/'/g, '"'))
|
|
102
|
+
.filter((x: string) => x.endsWith(CRASH_REPORT_EXT));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
override async exportCrash(name: string, dstFolder: string): Promise<void> {
|
|
106
|
+
await this.execute(['crash', 'export', '--name', name], {
|
|
107
|
+
logStdout: true,
|
|
108
|
+
// The tool exports crash reports to the current working dir
|
|
109
|
+
cwd: dstFolder,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
override async collectPcap(dstFile: string): Promise<SubProcess> {
|
|
114
|
+
return await this.execute(['pcapd', dstFile], {
|
|
115
|
+
format: null,
|
|
116
|
+
asynchronous: true,
|
|
117
|
+
}) as SubProcess;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
private async execute(
|
|
121
|
+
args: string[],
|
|
122
|
+
opts: ExecuteOptions = {}
|
|
123
|
+
): Promise<TeenProcessExecResult<string> | SubProcess> {
|
|
124
|
+
await this.assertExists();
|
|
125
|
+
const {cwd, format = 'json', logStdout = false, asynchronous = false} = opts;
|
|
126
|
+
|
|
127
|
+
const finalArgs = [...args, '--udid', this._udid, '--network'];
|
|
128
|
+
if (format) {
|
|
129
|
+
finalArgs.push('--format', format);
|
|
130
|
+
}
|
|
131
|
+
const binaryPath = this._binaryPath as string;
|
|
132
|
+
const cmdStr = util.quote([binaryPath, ...finalArgs]);
|
|
133
|
+
this.log.debug(`Executing ${cmdStr}`);
|
|
134
|
+
try {
|
|
135
|
+
if (asynchronous) {
|
|
136
|
+
const result = new SubProcess(binaryPath, finalArgs, {cwd});
|
|
137
|
+
await result.start(0);
|
|
138
|
+
return result;
|
|
139
|
+
}
|
|
140
|
+
const result = await exec(binaryPath, finalArgs, {cwd});
|
|
141
|
+
if (logStdout) {
|
|
142
|
+
this.log.debug(`Command output: ${result.stdout}`);
|
|
143
|
+
}
|
|
144
|
+
return result;
|
|
145
|
+
} catch (e) {
|
|
146
|
+
throw new Error(`'${cmdStr}' failed. Original error: ${e.stderr || e.stdout || e.message}`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
package/lib/real-device.js
CHANGED
|
@@ -6,7 +6,7 @@ import defaultLogger from './logger';
|
|
|
6
6
|
import _ from 'lodash';
|
|
7
7
|
import {SAFARI_BUNDLE_ID} from './app-utils';
|
|
8
8
|
import {pushFile, pushFolder, IO_TIMEOUT_MS} from './ios-fs-helpers';
|
|
9
|
-
import { Devicectl } from './devicectl';
|
|
9
|
+
import { Devicectl } from './real-device-clients/devicectl';
|
|
10
10
|
|
|
11
11
|
const APPLICATION_INSTALLED_NOTIFICATION = 'com.apple.mobile.application_installed';
|
|
12
12
|
const APPLICATION_NOTIFICATION_TIMEOUT_MS = 30 * 1000;
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "appium-xcuitest-driver",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.23.0",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "appium-xcuitest-driver",
|
|
9
|
-
"version": "7.
|
|
9
|
+
"version": "7.23.0",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@colors/colors": "^1.6.0",
|
|
@@ -2777,9 +2777,9 @@
|
|
|
2777
2777
|
}
|
|
2778
2778
|
},
|
|
2779
2779
|
"node_modules/node-simctl": {
|
|
2780
|
-
"version": "7.5.
|
|
2781
|
-
"resolved": "https://registry.npmjs.org/node-simctl/-/node-simctl-7.5.
|
|
2782
|
-
"integrity": "sha512-
|
|
2780
|
+
"version": "7.5.3",
|
|
2781
|
+
"resolved": "https://registry.npmjs.org/node-simctl/-/node-simctl-7.5.3.tgz",
|
|
2782
|
+
"integrity": "sha512-afI01Azk7IZdL/sI+qUDpvhAv+G5jQLq8SirqdzP6+GciiP15yWELAKhfhMYwJAB+qI37/J2uZzgHo/4a2FQXQ==",
|
|
2783
2783
|
"dependencies": {
|
|
2784
2784
|
"@appium/logger": "^1.3.0",
|
|
2785
2785
|
"asyncbox": "^3.0.0",
|
|
@@ -2788,7 +2788,7 @@
|
|
|
2788
2788
|
"rimraf": "^5.0.0",
|
|
2789
2789
|
"semver": "^7.0.0",
|
|
2790
2790
|
"source-map-support": "^0.x",
|
|
2791
|
-
"teen_process": "^2.
|
|
2791
|
+
"teen_process": "^2.2.0",
|
|
2792
2792
|
"uuid": "^10.0.0",
|
|
2793
2793
|
"which": "^4.0.0"
|
|
2794
2794
|
},
|
|
@@ -4041,9 +4041,9 @@
|
|
|
4041
4041
|
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
|
4042
4042
|
},
|
|
4043
4043
|
"node_modules/ws": {
|
|
4044
|
-
"version": "8.
|
|
4045
|
-
"resolved": "https://registry.npmjs.org/ws/-/ws-8.
|
|
4046
|
-
"integrity": "sha512-
|
|
4044
|
+
"version": "8.18.0",
|
|
4045
|
+
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
|
|
4046
|
+
"integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
|
|
4047
4047
|
"engines": {
|
|
4048
4048
|
"node": ">=10.0.0"
|
|
4049
4049
|
},
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"devicectl.d.ts","sourceRoot":"","sources":["../../lib/devicectl.js"],"names":[],"mappings":"AAMA;;;;GAIG;AAUH;;;;;;;;;;;;;GAaG;AAmBH;;;;;;;GAOG;AAEH;;GAEG;AAEH;;;;GAIG;AAEH;;;;;;;;;;GAUG;AAGH;;;;;GAKG;AAEH;IACE;;;;OAIG;IACH,kBAHW,MAAM,OACN,OAAO,eAAe,EAAE,YAAY,EAK9C;IAFC,aAAgB;IAChB,0CAAc;IAGhB;;;;;OAKG;IACH,QAL8B,SAAS,SAAzB,cAAe,cAClB,MAAM,EAAE,iCAEP,OAAO,CAAC,SAAS,SAAS,UAAU,GAAG,OAAO,cAAc,EAAE,UAAU,GAAG,iDAA4C,CAAC,CA6CnI;IAED;;;;;OAKG;IACH,uBAHW,MAAM,GAAC,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC,CAMxB;IAED;;;;OAIG;IACH,iBAFa,OAAO,CAAC,WAAW,EAAE,CAAC,CAKlC;IAED;;;;;;;;;;;OAWG;IACH,sBATW,MAAM,oBAKN,MAAM,wCAEJ,OAAO,CAAC,MAAM,EAAE,CAAC,CAiB7B;IAED;;;;;;;OAOG;IACH,eALW,MAAM,MACN,MAAM,QACN,eAAe,GACb,OAAO,CAAC,MAAM,CAAC,CAkB3B;IAED;;;;;;OAMG;IACH,yBAJW,MAAM,GAAC,MAAM,UACb,MAAM,GAAC,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAMzB;IAED;;;;;;OAMG;IACH,gDAFa,OAAO,CAAC,OAAO,EAAE,CAAC,CAW9B;IAED;;;;;;;;;OASG;IACH,oBALW,MAAM,QACN,gBAAgB,GACd,OAAO,CAAC,IAAI,CAAC,CAqBzB;CACF;;uBA1Ra,MAAM;gBACN,MAAM;;;aAaN,OAAO;sBACP,OAAO;sBACP,MAAM;mBACN,MAAM;gBACN,OAAO;YACP,OAAO;iBACP,OAAO;UACP,MAAM;eACN,OAAO;SACP,MAAM;aACN,MAAM;;;;;;;;;yBA8BP;IAAC,YAAY,EAAE,IAAI,CAAA;CAAC;;;;;;;;;;;;;;;;;;;;;;;gBAYnB,MAAM;;;;sBAKN,MAAM"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"devicectl.js","sourceRoot":"","sources":["../../lib/devicectl.js"],"names":[],"mappings":";;;;;;AAAA,+CAA8C;AAC9C,4CAAoC;AACpC,oDAAuB;AAEvB,MAAM,KAAK,GAAG,OAAO,CAAC;AAEtB;;;;GAIG;AAEH;;;;;;EAME;AAEF;;;;;;;;;;;;;GAaG;AAEH;;;;;;;;;;;;;;;EAeE;AAEF;;;;;;;GAOG;AAEH;;GAEG;AAEH;;;;GAIG;AAEH;;;;;;;;;;GAUG;AAGH;;;;;GAKG;AAEH,MAAa,SAAS;IACpB;;;;OAIG;IACH,YAAY,IAAI,EAAE,GAAG;QACnB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI;QAC5B,MAAM,EACJ,SAAS,GAAG,KAAK,EACjB,YAAY,GAAG,KAAK,EACpB,MAAM,GAAG,IAAI,EACb,iBAAiB,EACjB,OAAO,GACR,GAAG,IAAI,IAAI,EAAE,CAAC;QAEf,MAAM,SAAS,GAAG;YAChB,WAAW,EAAE,GAAG,UAAU;YAC1B,UAAU,EAAE,IAAI,CAAC,IAAI;SACtB,CAAC;QACF,IAAI,iBAAiB,IAAI,CAAC,gBAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,CAAC;YACvD,SAAS,CAAC,IAAI,CACZ,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAChF,CAAC;QACJ,CAAC;QACD,IAAI,MAAM,EAAE,CAAC;YACX,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,eAAe,EAAE,GAAG,CAAC,CAAC;QAClD,CAAC;QACD,MAAM,MAAM,GAAG,cAAI,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC;QACjD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,MAAM,EAAE,CAAC,CAAC;QACtC,IAAI,CAAC;YACH,IAAI,YAAY,EAAE,CAAC;gBACjB,MAAM,MAAM,GAAG,IAAI,yBAAU,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;gBAChD,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBACtB,uCAAuC;gBACvC,OAAO,MAAM,CAAC;YAChB,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,IAAA,mBAAI,EACvB,KAAK,EACL,SAAS,EACT,GAAG,CAAC,gBAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,OAAO,EAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAC5C,CAAC;YACF,IAAI,SAAS,EAAE,CAAC;gBACd,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,mBAAmB,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;YACrD,CAAC;YACD,uCAAuC;YACvC,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,IAAI,MAAM,6BAA6B,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9F,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,iBAAiB,CAAC,GAAG;QACzB,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,mBAAmB,CAAC,EAAE;YAC7D,iBAAiB,EAAE,CAAC,OAAO,EAAE,GAAG,GAAG,EAAE,CAAC;SACvC,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,aAAa;QACjB,MAAM,EAAC,MAAM,EAAC,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;QACrE,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC;IACpD,CAAC;IAED;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,SAAS,CAAC,UAAU,EAAE,gBAAgB,EAAE,IAAI,GAAG,EAAE;QACrD,MAAM,iBAAiB,GAAG;YACxB,eAAe,EAAE,UAAU;YAC3B,qBAAqB,EAAE,gBAAgB;SACxC,CAAC;QACF,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,iBAAiB,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACtD,CAAC;QACD,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,iBAAiB,CAAC,IAAI,CAAC,gBAAgB,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QAC9D,CAAC;QACD,MAAM,EAAC,MAAM,EAAC,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;YAC/D,iBAAiB;SAClB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAC,IAAI,EAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;IAC/D,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI;QAC3B,MAAM,iBAAiB,GAAG;YACxB,eAAe,EAAE,IAAI,CAAC,UAAU;YAChC,qBAAqB,EAAE,IAAI,CAAC,gBAAgB;YAC5C,UAAU,EAAE,IAAI;YAChB,eAAe,EAAE,EAAE;SACpB,CAAC;QACF,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,iBAAiB,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAClD,CAAC;QACD,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE;YAC7C,iBAAiB;YACjB,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,MAAM;YAC/B,MAAM,EAAE,KAAK;SACd,CAAC,CAAC;QACH,OAAO,EAAE,CAAC;IACZ,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,mBAAmB,CAAC,GAAG,EAAE,MAAM;QACnC,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE;YAClD,iBAAiB,EAAE,CAAC,UAAU,EAAE,GAAG,MAAM,EAAE,EAAE,OAAO,EAAE,GAAG,GAAG,EAAE,CAAC;SAChE,CAAC,CAAC;IACL,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,QAAQ,CAAC,QAAQ,GAAG,IAAI;QAC5B,MAAM,iBAAiB,GAAG,CAAC,oBAAoB,CAAC,CAAC;QACjD,IAAI,QAAQ,EAAE,CAAC;YACb,iBAAiB,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;QAClD,CAAC;QACD,MAAM,EAAC,MAAM,EAAC,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE;YAC9D,iBAAiB;SAClB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;IACxC,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI;QAC5B,MAAM,EACJ,GAAG,EACH,iBAAiB,GAAG,KAAK,EAC1B,GAAG,IAAI,CAAC;QAET,MAAM,iBAAiB,GAAG,EAAE,CAAC;QAC7B,IAAI,iBAAiB,EAAE,CAAC;YACtB,iBAAiB,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QACjD,CAAC;QAAA,CAAC;QACF,IAAI,CAAC,gBAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YACpB,iBAAiB,CAAC,IAAI,CAAC,yBAAyB,EAAE,IAAI,CAAC,SAAS,CAAC,gBAAC,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5G,CAAC;QAAA,CAAC;QACF,gEAAgE;QAChE,wEAAwE;QACxE,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEjC,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,EAAE,iBAAiB,EAAE,MAAM,EAAE,KAAK,EAAC,CAAC,CAAC;IAC3F,CAAC;CACF;AAvMD,8BAuMC"}
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
export default Pyidevice;
|
|
2
|
-
export class Pyidevice {
|
|
3
|
-
/**
|
|
4
|
-
* @param {string} udid
|
|
5
|
-
*/
|
|
6
|
-
constructor(udid: string);
|
|
7
|
-
udid: string;
|
|
8
|
-
binaryPath: string | null;
|
|
9
|
-
/**
|
|
10
|
-
* @param {boolean} isStrict
|
|
11
|
-
* @return {Promise<boolean>}
|
|
12
|
-
*/
|
|
13
|
-
assertExists(isStrict?: boolean): Promise<boolean>;
|
|
14
|
-
/**
|
|
15
|
-
* @typedef {Object} ExecuteOptions
|
|
16
|
-
* @property {string} cwd
|
|
17
|
-
* @property {string?} format [json]
|
|
18
|
-
* @property {boolean} logStdout [false]
|
|
19
|
-
* @property {boolean} asynchronous [false]
|
|
20
|
-
*/
|
|
21
|
-
/**
|
|
22
|
-
* @param {string[]} args
|
|
23
|
-
* @param {Partial<ExecuteOptions>} opts
|
|
24
|
-
* @return {Promise<import('teen_process').TeenProcessExecResult|import('teen_process').SubProcess>}
|
|
25
|
-
*/
|
|
26
|
-
execute(args: string[], opts?: Partial<{
|
|
27
|
-
cwd: string;
|
|
28
|
-
/**
|
|
29
|
-
* [json]
|
|
30
|
-
*/
|
|
31
|
-
format: string | null;
|
|
32
|
-
/**
|
|
33
|
-
* [false]
|
|
34
|
-
*/
|
|
35
|
-
logStdout: boolean;
|
|
36
|
-
/**
|
|
37
|
-
* [false]
|
|
38
|
-
*/
|
|
39
|
-
asynchronous: boolean;
|
|
40
|
-
}>): Promise<import("teen_process").TeenProcessExecResult<any> | import("teen_process").SubProcess>;
|
|
41
|
-
/**
|
|
42
|
-
* @return {Promise<object>}
|
|
43
|
-
*/
|
|
44
|
-
listProfiles(): Promise<object>;
|
|
45
|
-
/**
|
|
46
|
-
*
|
|
47
|
-
* @param { {profilePath?: string, payload: string|Buffer} } opts
|
|
48
|
-
* @privateRemarks The error below seems to suggest that `payload` can be undefined, but the code suggests otherwise
|
|
49
|
-
*/
|
|
50
|
-
installProfile(opts: {
|
|
51
|
-
profilePath?: string;
|
|
52
|
-
payload: string | Buffer;
|
|
53
|
-
}): Promise<void>;
|
|
54
|
-
/**
|
|
55
|
-
*
|
|
56
|
-
* @param {string} name
|
|
57
|
-
* @returns {Promise<string>}
|
|
58
|
-
*/
|
|
59
|
-
removeProfile(name: string): Promise<string>;
|
|
60
|
-
/**
|
|
61
|
-
* @returns {Promise<object>}
|
|
62
|
-
*/
|
|
63
|
-
listCrashes(): Promise<object>;
|
|
64
|
-
/**
|
|
65
|
-
* @param {string} name
|
|
66
|
-
* @param {string} dstFolder
|
|
67
|
-
* @returns {Promise<void>}
|
|
68
|
-
*/
|
|
69
|
-
exportCrash(name: string, dstFolder: string): Promise<void>;
|
|
70
|
-
/**
|
|
71
|
-
* @param {string} dstFile
|
|
72
|
-
*/
|
|
73
|
-
collectPcap(dstFile: string): Promise<SubProcess | import("teen_process").TeenProcessExecResult<any>>;
|
|
74
|
-
}
|
|
75
|
-
import { SubProcess } from 'teen_process';
|
|
76
|
-
//# sourceMappingURL=py-ios-device-client.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"py-ios-device-client.d.ts","sourceRoot":"","sources":["../../lib/py-ios-device-client.js"],"names":[],"mappings":";AASA;IACE;;OAEG;IACH,kBAFW,MAAM,EAKhB;IAFC,aAAgB;IAChB,0BAAsB;IAGxB;;;OAGG;IACH,wBAHW,OAAO,GACN,OAAO,CAAC,OAAO,CAAC,CAoB3B;IAED;;;;;;OAMG;IAEH;;;;OAIG;IACH,cAJW,MAAM,EAAE,SACR,OAAO;aARJ,MAAM;;;;gBACN,MAAM,OAAC;;;;mBACP,OAAO;;;;sBACP,OAAO;MAKa,GACtB,OAAO,CAAC,iDAA4C,GAAC,OAAO,cAAc,EAAE,UAAU,CAAC,CA2BlG;IAED;;OAEG;IACH,gBAFY,OAAO,CAAC,MAAM,CAAC,CAO1B;IAED;;;;OAIG;IACH,qBAHY;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,GAAC,MAAM,CAAA;KAAC,iBAyBzD;IAED;;;;OAIG;IACH,oBAHW,MAAM,GACJ,OAAO,CAAC,MAAM,CAAC,CAM3B;IAED;;OAEG;IACH,eAFa,OAAO,CAAC,MAAM,CAAC,CAO3B;IAED;;;;OAIG;IACH,kBAJW,MAAM,aACN,MAAM,GACJ,OAAO,CAAC,IAAI,CAAC,CAQzB;IACD;;OAEG;IACH,qBAFW,MAAM,2EAOhB;CACF;2BAnK8B,cAAc"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"py-ios-device-client.js","sourceRoot":"","sources":["../../lib/py-ios-device-client.js"],"names":[],"mappings":"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"}
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
import {fs, tempDir} from 'appium/support';
|
|
2
|
-
import B from 'bluebird';
|
|
3
|
-
import log from '../logger';
|
|
4
|
-
import {utilities} from 'appium-ios-device';
|
|
5
|
-
import path from 'path';
|
|
6
|
-
import _ from 'lodash';
|
|
7
|
-
import Pyidevice from '../py-ios-device-client';
|
|
8
|
-
|
|
9
|
-
const REAL_DEVICE_MAGIC = '3620bbb0-fb9f-4b62-a668-896f2edc4d88';
|
|
10
|
-
const MAGIC_SEP = '/';
|
|
11
|
-
// The file format has been changed from '.crash' to '.ips' since Monterey.
|
|
12
|
-
const CRASH_REPORTS_GLOB_PATTERN = '**/*.@(crash|ips)';
|
|
13
|
-
|
|
14
|
-
class IOSCrashLog {
|
|
15
|
-
constructor(opts = {}) {
|
|
16
|
-
this.udid = opts.udid;
|
|
17
|
-
this.pyideviceClient = this.udid ? new Pyidevice(this.udid) : null;
|
|
18
|
-
const root = process.env.HOME || '/';
|
|
19
|
-
const logDir = opts.udid
|
|
20
|
-
? path.resolve(root, 'Library', 'Logs', 'CrashReporter', 'MobileDevice')
|
|
21
|
-
: path.resolve(root, 'Library', 'Logs', 'DiagnosticReports');
|
|
22
|
-
this.logDir = logDir || path.resolve(root, 'Library', 'Logs', 'DiagnosticReports');
|
|
23
|
-
this.prevLogs = [];
|
|
24
|
-
this.logsSinceLastRequest = [];
|
|
25
|
-
this.phoneName = null;
|
|
26
|
-
this.sim = opts.sim;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* @returns {Promise<string[]>}
|
|
31
|
-
*/
|
|
32
|
-
async _gatherFromRealDevice() {
|
|
33
|
-
if (await this.pyideviceClient?.assertExists(false)) {
|
|
34
|
-
return (await /** @type {Pyidevice} */ (this.pyideviceClient).listCrashes()).map(
|
|
35
|
-
(x) => `${REAL_DEVICE_MAGIC}${MAGIC_SEP}${x}`,
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
let crashLogsRoot = this.logDir;
|
|
40
|
-
if (this.udid) {
|
|
41
|
-
this.phoneName = this.phoneName || (await utilities.getDeviceName(this.udid));
|
|
42
|
-
crashLogsRoot = path.resolve(crashLogsRoot, this.phoneName);
|
|
43
|
-
}
|
|
44
|
-
if (!(await fs.exists(crashLogsRoot))) {
|
|
45
|
-
log.debug(`Crash reports root '${crashLogsRoot}' does not exist. Got nothing to gather.`);
|
|
46
|
-
return [];
|
|
47
|
-
}
|
|
48
|
-
return await fs.glob(CRASH_REPORTS_GLOB_PATTERN, {
|
|
49
|
-
cwd: crashLogsRoot,
|
|
50
|
-
absolute: true,
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* @returns {Promise<string[]>}
|
|
56
|
-
*/
|
|
57
|
-
async _gatherFromSimulator() {
|
|
58
|
-
if (!(await fs.exists(this.logDir))) {
|
|
59
|
-
log.debug(`Crash reports root '${this.logDir}' does not exist. Got nothing to gather.`);
|
|
60
|
-
return [];
|
|
61
|
-
}
|
|
62
|
-
const foundFiles = await fs.glob(CRASH_REPORTS_GLOB_PATTERN, {
|
|
63
|
-
cwd: this.logDir,
|
|
64
|
-
absolute: true,
|
|
65
|
-
});
|
|
66
|
-
// For Simulator only include files, that contain current UDID
|
|
67
|
-
return await B.filter(foundFiles, async (x) => {
|
|
68
|
-
try {
|
|
69
|
-
const content = await fs.readFile(x, 'utf8');
|
|
70
|
-
return content.toUpperCase().includes(this.sim.udid.toUpperCase());
|
|
71
|
-
} catch (err) {
|
|
72
|
-
return false;
|
|
73
|
-
}
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* @returns {Promise<string[]>}
|
|
79
|
-
*/
|
|
80
|
-
async getCrashes() {
|
|
81
|
-
return this.udid ? await this._gatherFromRealDevice() : await this._gatherFromSimulator();
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* @returns {Promise<void>}
|
|
86
|
-
*/
|
|
87
|
-
async startCapture() {
|
|
88
|
-
this.prevLogs = await this.getCrashes();
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* @returns {Promise<void>}
|
|
93
|
-
*/
|
|
94
|
-
async stopCapture() {
|
|
95
|
-
// needed for consistent API with other logs
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* @returns {Promise<import('../commands/types').LogEntry[]>}
|
|
100
|
-
*/
|
|
101
|
-
async getLogs() {
|
|
102
|
-
let crashFiles = await this.getCrashes();
|
|
103
|
-
let diff = _.difference(crashFiles, this.prevLogs, this.logsSinceLastRequest);
|
|
104
|
-
this.logsSinceLastRequest = _.union(this.logsSinceLastRequest, diff);
|
|
105
|
-
return await this.filesToJSON(diff);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* @param {string[]} paths
|
|
110
|
-
* @returns {Promise<import('../commands/types').LogEntry[]>}
|
|
111
|
-
*/
|
|
112
|
-
async filesToJSON(paths) {
|
|
113
|
-
const tmpRoot = await tempDir.openDir();
|
|
114
|
-
try {
|
|
115
|
-
return /** @type {import('../commands/types').LogEntry[]} */ ((
|
|
116
|
-
await B.map(paths, async (fullPath) => {
|
|
117
|
-
if (_.includes(fullPath, REAL_DEVICE_MAGIC)) {
|
|
118
|
-
const fileName = /** @type {string} */ (_.last(fullPath.split(MAGIC_SEP)));
|
|
119
|
-
try {
|
|
120
|
-
// @ts-expect-error If pyideviceClient is not defined, then the exception will be caught below
|
|
121
|
-
await this.pyideviceClient.exportCrash(fileName, tmpRoot);
|
|
122
|
-
} catch (e) {
|
|
123
|
-
log.warn(
|
|
124
|
-
`Cannot export the crash report '${fileName}'. Skipping it. ` +
|
|
125
|
-
`Original error: ${e.message}`,
|
|
126
|
-
);
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
fullPath = path.join(tmpRoot, fileName);
|
|
130
|
-
}
|
|
131
|
-
const stat = await fs.stat(fullPath);
|
|
132
|
-
return {
|
|
133
|
-
timestamp: stat.ctime.getTime(),
|
|
134
|
-
level: 'ALL',
|
|
135
|
-
message: await fs.readFile(fullPath, 'utf8'),
|
|
136
|
-
};
|
|
137
|
-
})
|
|
138
|
-
).filter(Boolean));
|
|
139
|
-
} finally {
|
|
140
|
-
await fs.rimraf(tmpRoot);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
export {IOSCrashLog};
|
|
146
|
-
export default IOSCrashLog;
|
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
import {exec, SubProcess} from 'teen_process';
|
|
2
|
-
import {fs, util, tempDir} from 'appium/support';
|
|
3
|
-
import log from './logger';
|
|
4
|
-
import path from 'path';
|
|
5
|
-
|
|
6
|
-
// https://github.com/YueChen-C/py-ios-device
|
|
7
|
-
|
|
8
|
-
const BINARY_NAME = 'pyidevice';
|
|
9
|
-
|
|
10
|
-
class Pyidevice {
|
|
11
|
-
/**
|
|
12
|
-
* @param {string} udid
|
|
13
|
-
*/
|
|
14
|
-
constructor(udid) {
|
|
15
|
-
this.udid = udid;
|
|
16
|
-
this.binaryPath = null;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* @param {boolean} isStrict
|
|
21
|
-
* @return {Promise<boolean>}
|
|
22
|
-
*/
|
|
23
|
-
async assertExists(isStrict = true) {
|
|
24
|
-
if (this.binaryPath) {
|
|
25
|
-
return true;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
try {
|
|
29
|
-
this.binaryPath = await fs.which(BINARY_NAME);
|
|
30
|
-
return true;
|
|
31
|
-
} catch (e) {
|
|
32
|
-
if (isStrict) {
|
|
33
|
-
throw new Error(
|
|
34
|
-
`${BINARY_NAME} binary cannot be found in PATH. ` +
|
|
35
|
-
`Please make sure it is installed. Visit https://github.com/YueChen-C/py-ios-device for ` +
|
|
36
|
-
`more details.`,
|
|
37
|
-
);
|
|
38
|
-
}
|
|
39
|
-
return false;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* @typedef {Object} ExecuteOptions
|
|
45
|
-
* @property {string} cwd
|
|
46
|
-
* @property {string?} format [json]
|
|
47
|
-
* @property {boolean} logStdout [false]
|
|
48
|
-
* @property {boolean} asynchronous [false]
|
|
49
|
-
*/
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* @param {string[]} args
|
|
53
|
-
* @param {Partial<ExecuteOptions>} opts
|
|
54
|
-
* @return {Promise<import('teen_process').TeenProcessExecResult|import('teen_process').SubProcess>}
|
|
55
|
-
*/
|
|
56
|
-
async execute(args, opts = {}) {
|
|
57
|
-
await this.assertExists();
|
|
58
|
-
const {cwd, format = 'json', logStdout = false, asynchronous = false} = opts;
|
|
59
|
-
|
|
60
|
-
const finalArgs = [...args, '--udid', this.udid, '--network'];
|
|
61
|
-
if (format) {
|
|
62
|
-
finalArgs.push('--format', format);
|
|
63
|
-
}
|
|
64
|
-
const binaryPath = /** @type {string} */ (this.binaryPath);
|
|
65
|
-
const cmdStr = util.quote([binaryPath, ...finalArgs]);
|
|
66
|
-
log.debug(`Executing ${cmdStr}`);
|
|
67
|
-
try {
|
|
68
|
-
if (asynchronous) {
|
|
69
|
-
const result = new SubProcess(binaryPath, finalArgs, {cwd});
|
|
70
|
-
await result.start(0);
|
|
71
|
-
return result;
|
|
72
|
-
}
|
|
73
|
-
const result = await exec(binaryPath, finalArgs, {cwd});
|
|
74
|
-
if (logStdout) {
|
|
75
|
-
log.debug(`Command output: ${result.stdout}`);
|
|
76
|
-
}
|
|
77
|
-
return result;
|
|
78
|
-
} catch (e) {
|
|
79
|
-
throw new Error(`'${cmdStr}' failed. Original error: ${e.stderr || e.stdout || e.message}`);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* @return {Promise<object>}
|
|
85
|
-
*/
|
|
86
|
-
async listProfiles() {
|
|
87
|
-
const {stdout} = /** @type {import('teen_process').TeenProcessExecResult} */ (
|
|
88
|
-
await this.execute(['profiles', 'list'])
|
|
89
|
-
);
|
|
90
|
-
return JSON.parse(stdout);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
*
|
|
95
|
-
* @param { {profilePath?: string, payload: string|Buffer} } opts
|
|
96
|
-
* @privateRemarks The error below seems to suggest that `payload` can be undefined, but the code suggests otherwise
|
|
97
|
-
*/
|
|
98
|
-
async installProfile(opts) {
|
|
99
|
-
const {profilePath, payload} = opts ?? {};
|
|
100
|
-
if (!profilePath && !payload) {
|
|
101
|
-
throw new Error('Either the full path to the profile or its payload must be provided');
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
let tmpRoot;
|
|
105
|
-
let srcPath = profilePath;
|
|
106
|
-
try {
|
|
107
|
-
if (!srcPath) {
|
|
108
|
-
tmpRoot = await tempDir.openDir();
|
|
109
|
-
srcPath = path.join(tmpRoot, 'cert.pem');
|
|
110
|
-
await fs.writeFile(srcPath, payload, 'utf8');
|
|
111
|
-
}
|
|
112
|
-
await this.execute(['profiles', 'install', '--path', srcPath], {
|
|
113
|
-
logStdout: true,
|
|
114
|
-
});
|
|
115
|
-
} finally {
|
|
116
|
-
if (tmpRoot) {
|
|
117
|
-
await fs.rimraf(tmpRoot);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
*
|
|
124
|
-
* @param {string} name
|
|
125
|
-
* @returns {Promise<string>}
|
|
126
|
-
*/
|
|
127
|
-
async removeProfile(name) {
|
|
128
|
-
return /** @type {import('teen_process').TeenProcessExecResult} */ (
|
|
129
|
-
await this.execute(['profiles', 'remove', '--name', name], {logStdout: true})
|
|
130
|
-
).stdout;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* @returns {Promise<object>}
|
|
135
|
-
*/
|
|
136
|
-
async listCrashes() {
|
|
137
|
-
const {stdout} = /** @type {import('teen_process').TeenProcessExecResult} */ (
|
|
138
|
-
await this.execute(['crash', 'list'])
|
|
139
|
-
);
|
|
140
|
-
return JSON.parse(stdout.replace(/'/g, '"')).filter((x) => !['.', '..'].includes(x));
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* @param {string} name
|
|
145
|
-
* @param {string} dstFolder
|
|
146
|
-
* @returns {Promise<void>}
|
|
147
|
-
*/
|
|
148
|
-
async exportCrash(name, dstFolder) {
|
|
149
|
-
await this.execute(['crash', 'export', '--name', name], {
|
|
150
|
-
logStdout: true,
|
|
151
|
-
// The tool exports crash reports to the current working dir
|
|
152
|
-
cwd: dstFolder,
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
/**
|
|
156
|
-
* @param {string} dstFile
|
|
157
|
-
*/
|
|
158
|
-
async collectPcap(dstFile) {
|
|
159
|
-
return await this.execute(['pcapd', dstFile], {
|
|
160
|
-
format: null,
|
|
161
|
-
asynchronous: true,
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
export {Pyidevice};
|
|
167
|
-
export default Pyidevice;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|