@panicgit/android-test-pilot 0.1.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/.claude/skills/atp/analyze-app/SKILL.md +86 -0
- package/.claude/skills/atp/app-map/SKILL.md +36 -0
- package/.claude/skills/atp/check-logs/SKILL.md +77 -0
- package/.claude/skills/atp/run-test/SKILL.md +92 -0
- package/README.ko.md +241 -0
- package/README.md +241 -0
- package/lib/android.d.ts +96 -0
- package/lib/android.js +740 -0
- package/lib/android.js.map +1 -0
- package/lib/image-utils.d.ts +28 -0
- package/lib/image-utils.js +156 -0
- package/lib/image-utils.js.map +1 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +90 -0
- package/lib/index.js.map +1 -0
- package/lib/ios.d.ts +54 -0
- package/lib/ios.js +241 -0
- package/lib/ios.js.map +1 -0
- package/lib/iphone-simulator.d.ts +34 -0
- package/lib/iphone-simulator.js +227 -0
- package/lib/iphone-simulator.js.map +1 -0
- package/lib/logger.d.ts +2 -0
- package/lib/logger.js +23 -0
- package/lib/logger.js.map +1 -0
- package/lib/mobile-device.d.ts +25 -0
- package/lib/mobile-device.js +141 -0
- package/lib/mobile-device.js.map +1 -0
- package/lib/mobilecli.d.ts +32 -0
- package/lib/mobilecli.js +113 -0
- package/lib/mobilecli.js.map +1 -0
- package/lib/png.d.ts +9 -0
- package/lib/png.js +20 -0
- package/lib/png.js.map +1 -0
- package/lib/robot.d.ts +116 -0
- package/lib/robot.js +10 -0
- package/lib/robot.js.map +1 -0
- package/lib/server.d.ts +3 -0
- package/lib/server.js +692 -0
- package/lib/server.js.map +1 -0
- package/lib/tiers/abstract-tier.d.ts +48 -0
- package/lib/tiers/abstract-tier.js +35 -0
- package/lib/tiers/abstract-tier.js.map +1 -0
- package/lib/tiers/screenshot-tier.d.ts +19 -0
- package/lib/tiers/screenshot-tier.js +53 -0
- package/lib/tiers/screenshot-tier.js.map +1 -0
- package/lib/tiers/text-tier.d.ts +20 -0
- package/lib/tiers/text-tier.js +138 -0
- package/lib/tiers/text-tier.js.map +1 -0
- package/lib/tiers/tier-runner.d.ts +27 -0
- package/lib/tiers/tier-runner.js +91 -0
- package/lib/tiers/tier-runner.js.map +1 -0
- package/lib/tiers/types.d.ts +100 -0
- package/lib/tiers/types.js +12 -0
- package/lib/tiers/types.js.map +1 -0
- package/lib/tiers/uiautomator-tier.d.ts +16 -0
- package/lib/tiers/uiautomator-tier.js +91 -0
- package/lib/tiers/uiautomator-tier.js.map +1 -0
- package/lib/utils.d.ts +4 -0
- package/lib/utils.js +81 -0
- package/lib/utils.js.map +1 -0
- package/lib/webdriver-agent.d.ts +45 -0
- package/lib/webdriver-agent.js +400 -0
- package/lib/webdriver-agent.js.map +1 -0
- package/package.json +50 -0
- package/templates/scenario.md +49 -0
package/lib/ios.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ios.js","sourceRoot":"","sources":["../src/ios.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Button, InstalledApp, Robot, ScreenElement, ScreenSize, SwipeDirection, Orientation } from "./robot";
|
|
2
|
+
export interface Simulator {
|
|
3
|
+
name: string;
|
|
4
|
+
uuid: string;
|
|
5
|
+
state: string;
|
|
6
|
+
}
|
|
7
|
+
export declare class Simctl implements Robot {
|
|
8
|
+
private readonly simulatorUuid;
|
|
9
|
+
constructor(simulatorUuid: string);
|
|
10
|
+
private isWdaInstalled;
|
|
11
|
+
private startWda;
|
|
12
|
+
private wda;
|
|
13
|
+
private simctl;
|
|
14
|
+
getScreenshot(): Promise<Buffer>;
|
|
15
|
+
openUrl(url: string): Promise<void>;
|
|
16
|
+
launchApp(packageName: string, locale?: string): Promise<void>;
|
|
17
|
+
terminateApp(packageName: string): Promise<void>;
|
|
18
|
+
private findAppBundle;
|
|
19
|
+
private validateZipPaths;
|
|
20
|
+
installApp(path: string): Promise<void>;
|
|
21
|
+
uninstallApp(bundleId: string): Promise<void>;
|
|
22
|
+
listApps(): Promise<InstalledApp[]>;
|
|
23
|
+
getScreenSize(): Promise<ScreenSize>;
|
|
24
|
+
sendKeys(keys: string): Promise<void>;
|
|
25
|
+
swipe(direction: SwipeDirection): Promise<void>;
|
|
26
|
+
swipeFromCoordinate(x: number, y: number, direction: SwipeDirection, distance?: number): Promise<void>;
|
|
27
|
+
tap(x: number, y: number): Promise<void>;
|
|
28
|
+
doubleTap(x: number, y: number): Promise<void>;
|
|
29
|
+
longPress(x: number, y: number, duration: number): Promise<void>;
|
|
30
|
+
pressButton(button: Button): Promise<void>;
|
|
31
|
+
getElementsOnScreen(): Promise<ScreenElement[]>;
|
|
32
|
+
setOrientation(orientation: Orientation): Promise<void>;
|
|
33
|
+
getOrientation(): Promise<Orientation>;
|
|
34
|
+
}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Simctl = void 0;
|
|
4
|
+
const node_child_process_1 = require("node:child_process");
|
|
5
|
+
const node_fs_1 = require("node:fs");
|
|
6
|
+
const node_os_1 = require("node:os");
|
|
7
|
+
const node_path_1 = require("node:path");
|
|
8
|
+
const logger_1 = require("./logger");
|
|
9
|
+
const webdriver_agent_1 = require("./webdriver-agent");
|
|
10
|
+
const robot_1 = require("./robot");
|
|
11
|
+
const utils_1 = require("./utils");
|
|
12
|
+
const TIMEOUT = 30000;
|
|
13
|
+
const WDA_PORT = 8100;
|
|
14
|
+
const MAX_BUFFER_SIZE = 1024 * 1024 * 8;
|
|
15
|
+
class Simctl {
|
|
16
|
+
simulatorUuid;
|
|
17
|
+
constructor(simulatorUuid) {
|
|
18
|
+
this.simulatorUuid = simulatorUuid;
|
|
19
|
+
}
|
|
20
|
+
async isWdaInstalled() {
|
|
21
|
+
const apps = await this.listApps();
|
|
22
|
+
return apps.map(app => app.packageName).includes("com.facebook.WebDriverAgentRunner.xctrunner");
|
|
23
|
+
}
|
|
24
|
+
async startWda() {
|
|
25
|
+
if (!(await this.isWdaInstalled())) {
|
|
26
|
+
// wda is not even installed, won't attempt to start it
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
(0, logger_1.trace)("Starting WebDriverAgent");
|
|
30
|
+
const webdriverPackageName = "com.facebook.WebDriverAgentRunner.xctrunner";
|
|
31
|
+
this.simctl("launch", this.simulatorUuid, webdriverPackageName);
|
|
32
|
+
// now we wait for wda to have a successful status
|
|
33
|
+
const wda = new webdriver_agent_1.WebDriverAgent("localhost", WDA_PORT);
|
|
34
|
+
// wait up to 10 seconds for wda to start
|
|
35
|
+
const timeout = +new Date() + 10 * 1000;
|
|
36
|
+
while (+new Date() < timeout) {
|
|
37
|
+
// cross fingers and see if wda is already running
|
|
38
|
+
if (await wda.isRunning()) {
|
|
39
|
+
(0, logger_1.trace)("WebDriverAgent is now running");
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
// wait 100ms before trying again
|
|
43
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
44
|
+
}
|
|
45
|
+
(0, logger_1.trace)("Could not start WebDriverAgent in time, giving up");
|
|
46
|
+
}
|
|
47
|
+
async wda() {
|
|
48
|
+
const wda = new webdriver_agent_1.WebDriverAgent("localhost", WDA_PORT);
|
|
49
|
+
if (!(await wda.isRunning())) {
|
|
50
|
+
await this.startWda();
|
|
51
|
+
if (!(await wda.isRunning())) {
|
|
52
|
+
throw new robot_1.ActionableError("WebDriverAgent is not running on simulator, please see https://github.com/mobile-next/mobile-mcp/wiki/");
|
|
53
|
+
}
|
|
54
|
+
// was successfully started
|
|
55
|
+
}
|
|
56
|
+
return wda;
|
|
57
|
+
}
|
|
58
|
+
simctl(...args) {
|
|
59
|
+
return (0, node_child_process_1.execFileSync)("xcrun", ["simctl", ...args], {
|
|
60
|
+
timeout: TIMEOUT,
|
|
61
|
+
maxBuffer: MAX_BUFFER_SIZE,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
async getScreenshot() {
|
|
65
|
+
const wda = await this.wda();
|
|
66
|
+
return await wda.getScreenshot();
|
|
67
|
+
// alternative: return this.simctl("io", this.simulatorUuid, "screenshot", "-");
|
|
68
|
+
}
|
|
69
|
+
async openUrl(url) {
|
|
70
|
+
const wda = await this.wda();
|
|
71
|
+
await wda.openUrl(url);
|
|
72
|
+
// alternative: this.simctl("openurl", this.simulatorUuid, url);
|
|
73
|
+
}
|
|
74
|
+
async launchApp(packageName, locale) {
|
|
75
|
+
(0, utils_1.validatePackageName)(packageName);
|
|
76
|
+
const args = ["launch", this.simulatorUuid, packageName];
|
|
77
|
+
if (locale) {
|
|
78
|
+
(0, utils_1.validateLocale)(locale);
|
|
79
|
+
const locales = locale.split(",").map(l => l.trim());
|
|
80
|
+
args.push("-AppleLanguages", `(${locales.join(", ")})`);
|
|
81
|
+
args.push("-AppleLocale", locales[0]);
|
|
82
|
+
}
|
|
83
|
+
this.simctl(...args);
|
|
84
|
+
}
|
|
85
|
+
async terminateApp(packageName) {
|
|
86
|
+
(0, utils_1.validatePackageName)(packageName);
|
|
87
|
+
this.simctl("terminate", this.simulatorUuid, packageName);
|
|
88
|
+
}
|
|
89
|
+
findAppBundle(dir) {
|
|
90
|
+
const entries = (0, node_fs_1.readdirSync)(dir, { withFileTypes: true });
|
|
91
|
+
for (const entry of entries) {
|
|
92
|
+
if (entry.isDirectory() && entry.name.endsWith(".app")) {
|
|
93
|
+
return (0, node_path_1.join)(dir, entry.name);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
validateZipPaths(zipPath) {
|
|
99
|
+
const output = (0, node_child_process_1.execFileSync)("/usr/bin/zipinfo", ["-1", zipPath], {
|
|
100
|
+
timeout: TIMEOUT,
|
|
101
|
+
maxBuffer: MAX_BUFFER_SIZE,
|
|
102
|
+
}).toString();
|
|
103
|
+
const invalidPath = output
|
|
104
|
+
.split("\n")
|
|
105
|
+
.map(s => s.trim())
|
|
106
|
+
.filter(s => s)
|
|
107
|
+
.find(s => s.startsWith("/") || s.includes(".."));
|
|
108
|
+
if (invalidPath) {
|
|
109
|
+
throw new robot_1.ActionableError(`Security violation: File path '${invalidPath}' contains invalid characters`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
async installApp(path) {
|
|
113
|
+
let tempDir = null;
|
|
114
|
+
let installPath = path;
|
|
115
|
+
try {
|
|
116
|
+
// zip files need to be extracted prior to installation
|
|
117
|
+
if ((0, node_path_1.extname)(path).toLowerCase() === ".zip") {
|
|
118
|
+
(0, logger_1.trace)(`Detected .zip file, validating contents`);
|
|
119
|
+
// before extracting, let's make sure there's no zip-slip bombs here
|
|
120
|
+
this.validateZipPaths(path);
|
|
121
|
+
tempDir = (0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), "ios-app-"));
|
|
122
|
+
try {
|
|
123
|
+
(0, node_child_process_1.execFileSync)("unzip", ["-q", path, "-d", tempDir], {
|
|
124
|
+
timeout: TIMEOUT,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
throw new robot_1.ActionableError(`Failed to unzip file: ${error.message}`);
|
|
129
|
+
}
|
|
130
|
+
const appBundle = this.findAppBundle(tempDir);
|
|
131
|
+
if (!appBundle) {
|
|
132
|
+
throw new robot_1.ActionableError("No .app bundle found in the .zip file, please visit wiki at https://github.com/mobile-next/mobile-mcp/wiki for assistance.");
|
|
133
|
+
}
|
|
134
|
+
installPath = appBundle;
|
|
135
|
+
(0, logger_1.trace)(`Found .app bundle at: ${(0, node_path_1.basename)(appBundle)}`);
|
|
136
|
+
}
|
|
137
|
+
// continue with installation
|
|
138
|
+
this.simctl("install", this.simulatorUuid, installPath);
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
const stdout = error.stdout ? error.stdout.toString() : "";
|
|
142
|
+
const stderr = error.stderr ? error.stderr.toString() : "";
|
|
143
|
+
const output = (stdout + stderr).trim();
|
|
144
|
+
throw new robot_1.ActionableError(output || error.message);
|
|
145
|
+
}
|
|
146
|
+
finally {
|
|
147
|
+
// Clean up temporary directory if it was created
|
|
148
|
+
if (tempDir) {
|
|
149
|
+
try {
|
|
150
|
+
(0, logger_1.trace)(`Cleaning up temporary directory`);
|
|
151
|
+
(0, node_fs_1.rmSync)(tempDir, { recursive: true, force: true });
|
|
152
|
+
}
|
|
153
|
+
catch (cleanupError) {
|
|
154
|
+
(0, logger_1.trace)(`Warning: Failed to cleanup temporary directory: ${cleanupError}`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
async uninstallApp(bundleId) {
|
|
160
|
+
try {
|
|
161
|
+
this.simctl("uninstall", this.simulatorUuid, bundleId);
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
const stdout = error.stdout ? error.stdout.toString() : "";
|
|
165
|
+
const stderr = error.stderr ? error.stderr.toString() : "";
|
|
166
|
+
const output = (stdout + stderr).trim();
|
|
167
|
+
throw new robot_1.ActionableError(output || error.message);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
async listApps() {
|
|
171
|
+
const text = this.simctl("listapps", this.simulatorUuid).toString();
|
|
172
|
+
const result = (0, node_child_process_1.execFileSync)("plutil", ["-convert", "json", "-o", "-", "-r", "-"], {
|
|
173
|
+
input: text,
|
|
174
|
+
});
|
|
175
|
+
const output = JSON.parse(result.toString());
|
|
176
|
+
return Object.values(output).map(app => ({
|
|
177
|
+
packageName: app.CFBundleIdentifier,
|
|
178
|
+
appName: app.CFBundleDisplayName,
|
|
179
|
+
}));
|
|
180
|
+
}
|
|
181
|
+
async getScreenSize() {
|
|
182
|
+
const wda = await this.wda();
|
|
183
|
+
return wda.getScreenSize();
|
|
184
|
+
}
|
|
185
|
+
async sendKeys(keys) {
|
|
186
|
+
const wda = await this.wda();
|
|
187
|
+
return wda.sendKeys(keys);
|
|
188
|
+
}
|
|
189
|
+
async swipe(direction) {
|
|
190
|
+
const wda = await this.wda();
|
|
191
|
+
return wda.swipe(direction);
|
|
192
|
+
}
|
|
193
|
+
async swipeFromCoordinate(x, y, direction, distance) {
|
|
194
|
+
const wda = await this.wda();
|
|
195
|
+
return wda.swipeFromCoordinate(x, y, direction, distance);
|
|
196
|
+
}
|
|
197
|
+
async tap(x, y) {
|
|
198
|
+
const wda = await this.wda();
|
|
199
|
+
return wda.tap(x, y);
|
|
200
|
+
}
|
|
201
|
+
async doubleTap(x, y) {
|
|
202
|
+
const wda = await this.wda();
|
|
203
|
+
await wda.doubleTap(x, y);
|
|
204
|
+
}
|
|
205
|
+
async longPress(x, y, duration) {
|
|
206
|
+
const wda = await this.wda();
|
|
207
|
+
return wda.longPress(x, y, duration);
|
|
208
|
+
}
|
|
209
|
+
async pressButton(button) {
|
|
210
|
+
const wda = await this.wda();
|
|
211
|
+
return wda.pressButton(button);
|
|
212
|
+
}
|
|
213
|
+
async getElementsOnScreen() {
|
|
214
|
+
const wda = await this.wda();
|
|
215
|
+
return wda.getElementsOnScreen();
|
|
216
|
+
}
|
|
217
|
+
async setOrientation(orientation) {
|
|
218
|
+
const wda = await this.wda();
|
|
219
|
+
return wda.setOrientation(orientation);
|
|
220
|
+
}
|
|
221
|
+
async getOrientation() {
|
|
222
|
+
const wda = await this.wda();
|
|
223
|
+
return wda.getOrientation();
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
exports.Simctl = Simctl;
|
|
227
|
+
//# sourceMappingURL=iphone-simulator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iphone-simulator.js","sourceRoot":"","sources":["../src/iphone-simulator.ts"],"names":[],"mappings":"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"}
|
package/lib/logger.d.ts
ADDED
package/lib/logger.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.error = exports.trace = void 0;
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
|
+
const writeLog = (message) => {
|
|
6
|
+
if (process.env.LOG_FILE) {
|
|
7
|
+
const logfile = process.env.LOG_FILE;
|
|
8
|
+
const timestamp = new Date().toISOString();
|
|
9
|
+
const levelStr = "INFO";
|
|
10
|
+
const logMessage = `[${timestamp}] ${levelStr} ${message}`;
|
|
11
|
+
(0, node_fs_1.appendFileSync)(logfile, logMessage + "\n");
|
|
12
|
+
}
|
|
13
|
+
console.error(message);
|
|
14
|
+
};
|
|
15
|
+
const trace = (message) => {
|
|
16
|
+
writeLog(message);
|
|
17
|
+
};
|
|
18
|
+
exports.trace = trace;
|
|
19
|
+
const error = (message) => {
|
|
20
|
+
writeLog(message);
|
|
21
|
+
};
|
|
22
|
+
exports.error = error;
|
|
23
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":";;;AAAA,qCAAyC;AAEzC,MAAM,QAAQ,GAAG,CAAC,OAAe,EAAE,EAAE;IACpC,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC1B,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;QACrC,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,MAAM,QAAQ,GAAG,MAAM,CAAC;QACxB,MAAM,UAAU,GAAG,IAAI,SAAS,KAAK,QAAQ,IAAI,OAAO,EAAE,CAAC;QAC3D,IAAA,wBAAc,EAAC,OAAO,EAAE,UAAU,GAAG,IAAI,CAAC,CAAC;IAC5C,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AACxB,CAAC,CAAC;AAEK,MAAM,KAAK,GAAG,CAAC,OAAe,EAAE,EAAE;IACxC,QAAQ,CAAC,OAAO,CAAC,CAAC;AACnB,CAAC,CAAC;AAFW,QAAA,KAAK,SAEhB;AAEK,MAAM,KAAK,GAAG,CAAC,OAAe,EAAE,EAAE;IACxC,QAAQ,CAAC,OAAO,CAAC,CAAC;AACnB,CAAC,CAAC;AAFW,QAAA,KAAK,SAEhB"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Button, InstalledApp, Orientation, Robot, ScreenElement, ScreenSize, SwipeDirection } from "./robot";
|
|
2
|
+
export declare class MobileDevice implements Robot {
|
|
3
|
+
private deviceId;
|
|
4
|
+
private mobilecli;
|
|
5
|
+
constructor(deviceId: string);
|
|
6
|
+
private runCommand;
|
|
7
|
+
getScreenSize(): Promise<ScreenSize>;
|
|
8
|
+
swipe(direction: SwipeDirection): Promise<void>;
|
|
9
|
+
swipeFromCoordinate(x: number, y: number, direction: SwipeDirection, distance?: number): Promise<void>;
|
|
10
|
+
getScreenshot(): Promise<Buffer>;
|
|
11
|
+
listApps(): Promise<InstalledApp[]>;
|
|
12
|
+
launchApp(packageName: string, locale?: string): Promise<void>;
|
|
13
|
+
terminateApp(packageName: string): Promise<void>;
|
|
14
|
+
installApp(path: string): Promise<void>;
|
|
15
|
+
uninstallApp(bundleId: string): Promise<void>;
|
|
16
|
+
openUrl(url: string): Promise<void>;
|
|
17
|
+
sendKeys(text: string): Promise<void>;
|
|
18
|
+
pressButton(button: Button): Promise<void>;
|
|
19
|
+
tap(x: number, y: number): Promise<void>;
|
|
20
|
+
doubleTap(x: number, y: number): Promise<void>;
|
|
21
|
+
longPress(x: number, y: number, duration: number): Promise<void>;
|
|
22
|
+
getElementsOnScreen(): Promise<ScreenElement[]>;
|
|
23
|
+
setOrientation(orientation: Orientation): Promise<void>;
|
|
24
|
+
getOrientation(): Promise<Orientation>;
|
|
25
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MobileDevice = void 0;
|
|
4
|
+
const mobilecli_1 = require("./mobilecli");
|
|
5
|
+
class MobileDevice {
|
|
6
|
+
deviceId;
|
|
7
|
+
mobilecli;
|
|
8
|
+
constructor(deviceId) {
|
|
9
|
+
this.deviceId = deviceId;
|
|
10
|
+
this.mobilecli = new mobilecli_1.Mobilecli();
|
|
11
|
+
}
|
|
12
|
+
runCommand(args) {
|
|
13
|
+
const fullArgs = [...args, "--device", this.deviceId];
|
|
14
|
+
return this.mobilecli.executeCommand(fullArgs);
|
|
15
|
+
}
|
|
16
|
+
async getScreenSize() {
|
|
17
|
+
const response = JSON.parse(this.runCommand(["device", "info"]));
|
|
18
|
+
if (response.data.device.screenSize) {
|
|
19
|
+
return response.data.device.screenSize;
|
|
20
|
+
}
|
|
21
|
+
return { width: 0, height: 0, scale: 1.0 };
|
|
22
|
+
}
|
|
23
|
+
async swipe(direction) {
|
|
24
|
+
const screenSize = await this.getScreenSize();
|
|
25
|
+
const centerX = Math.floor(screenSize.width / 2);
|
|
26
|
+
const centerY = Math.floor(screenSize.height / 2);
|
|
27
|
+
const distance = 400; // Default distance in pixels
|
|
28
|
+
let startX = centerX;
|
|
29
|
+
let startY = centerY;
|
|
30
|
+
let endX = centerX;
|
|
31
|
+
let endY = centerY;
|
|
32
|
+
switch (direction) {
|
|
33
|
+
case "up":
|
|
34
|
+
startY = centerY + distance / 2;
|
|
35
|
+
endY = centerY - distance / 2;
|
|
36
|
+
break;
|
|
37
|
+
case "down":
|
|
38
|
+
startY = centerY - distance / 2;
|
|
39
|
+
endY = centerY + distance / 2;
|
|
40
|
+
break;
|
|
41
|
+
case "left":
|
|
42
|
+
startX = centerX + distance / 2;
|
|
43
|
+
endX = centerX - distance / 2;
|
|
44
|
+
break;
|
|
45
|
+
case "right":
|
|
46
|
+
startX = centerX - distance / 2;
|
|
47
|
+
endX = centerX + distance / 2;
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
this.runCommand(["io", "swipe", `${startX},${startY},${endX},${endY}`]);
|
|
51
|
+
}
|
|
52
|
+
async swipeFromCoordinate(x, y, direction, distance) {
|
|
53
|
+
const swipeDistance = distance || 400;
|
|
54
|
+
let endX = x;
|
|
55
|
+
let endY = y;
|
|
56
|
+
switch (direction) {
|
|
57
|
+
case "up":
|
|
58
|
+
endY = y - swipeDistance;
|
|
59
|
+
break;
|
|
60
|
+
case "down":
|
|
61
|
+
endY = y + swipeDistance;
|
|
62
|
+
break;
|
|
63
|
+
case "left":
|
|
64
|
+
endX = x - swipeDistance;
|
|
65
|
+
break;
|
|
66
|
+
case "right":
|
|
67
|
+
endX = x + swipeDistance;
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
this.runCommand(["io", "swipe", `${x},${y},${endX},${endY}`]);
|
|
71
|
+
}
|
|
72
|
+
async getScreenshot() {
|
|
73
|
+
const fullArgs = ["screenshot", "--device", this.deviceId, "--format", "png", "--output", "-"];
|
|
74
|
+
return this.mobilecli.executeCommandBuffer(fullArgs);
|
|
75
|
+
}
|
|
76
|
+
async listApps() {
|
|
77
|
+
const response = JSON.parse(this.runCommand(["apps", "list"]));
|
|
78
|
+
return response.data.map(app => ({
|
|
79
|
+
appName: app.appName || app.packageName,
|
|
80
|
+
packageName: app.packageName,
|
|
81
|
+
}));
|
|
82
|
+
}
|
|
83
|
+
async launchApp(packageName, locale) {
|
|
84
|
+
const args = ["apps", "launch", packageName];
|
|
85
|
+
if (locale) {
|
|
86
|
+
args.push("--locale", locale);
|
|
87
|
+
}
|
|
88
|
+
this.runCommand(args);
|
|
89
|
+
}
|
|
90
|
+
async terminateApp(packageName) {
|
|
91
|
+
this.runCommand(["apps", "terminate", packageName]);
|
|
92
|
+
}
|
|
93
|
+
async installApp(path) {
|
|
94
|
+
this.runCommand(["apps", "install", path]);
|
|
95
|
+
}
|
|
96
|
+
async uninstallApp(bundleId) {
|
|
97
|
+
this.runCommand(["apps", "uninstall", bundleId]);
|
|
98
|
+
}
|
|
99
|
+
async openUrl(url) {
|
|
100
|
+
this.runCommand(["url", url]);
|
|
101
|
+
}
|
|
102
|
+
async sendKeys(text) {
|
|
103
|
+
this.runCommand(["io", "text", text]);
|
|
104
|
+
}
|
|
105
|
+
async pressButton(button) {
|
|
106
|
+
this.runCommand(["io", "button", button]);
|
|
107
|
+
}
|
|
108
|
+
async tap(x, y) {
|
|
109
|
+
this.runCommand(["io", "tap", `${x},${y}`]);
|
|
110
|
+
}
|
|
111
|
+
async doubleTap(x, y) {
|
|
112
|
+
// TODO: should move into mobilecli itself as "io doubletap"
|
|
113
|
+
await this.tap(x, y);
|
|
114
|
+
await this.tap(x, y);
|
|
115
|
+
}
|
|
116
|
+
async longPress(x, y, duration) {
|
|
117
|
+
this.runCommand(["io", "longpress", `${x},${y}`, "--duration", `${duration}`]);
|
|
118
|
+
}
|
|
119
|
+
async getElementsOnScreen() {
|
|
120
|
+
const response = JSON.parse(this.runCommand(["dump", "ui"]));
|
|
121
|
+
return response.data.elements.map(element => ({
|
|
122
|
+
type: element.type,
|
|
123
|
+
label: element.label,
|
|
124
|
+
text: element.text,
|
|
125
|
+
name: element.name,
|
|
126
|
+
value: element.value,
|
|
127
|
+
identifier: element.identifier,
|
|
128
|
+
rect: element.rect,
|
|
129
|
+
focused: element.focused,
|
|
130
|
+
}));
|
|
131
|
+
}
|
|
132
|
+
async setOrientation(orientation) {
|
|
133
|
+
this.runCommand(["device", "orientation", "set", orientation]);
|
|
134
|
+
}
|
|
135
|
+
async getOrientation() {
|
|
136
|
+
const response = JSON.parse(this.runCommand(["device", "orientation", "get"]));
|
|
137
|
+
return response.data.orientation;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
exports.MobileDevice = MobileDevice;
|
|
141
|
+
//# sourceMappingURL=mobile-device.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mobile-device.js","sourceRoot":"","sources":["../src/mobile-device.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ChildProcess } from "node:child_process";
|
|
2
|
+
export interface MobilecliDevicesOptions {
|
|
3
|
+
includeOffline?: boolean;
|
|
4
|
+
platform?: "ios" | "android";
|
|
5
|
+
type?: "real" | "emulator" | "simulator";
|
|
6
|
+
}
|
|
7
|
+
export interface MobilecliDevicesResponse {
|
|
8
|
+
status: "ok";
|
|
9
|
+
data: {
|
|
10
|
+
devices: Array<{
|
|
11
|
+
id: string;
|
|
12
|
+
name: string;
|
|
13
|
+
platform: "android" | "ios";
|
|
14
|
+
type: "real" | "emulator" | "simulator";
|
|
15
|
+
version: string;
|
|
16
|
+
}>;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export declare class Mobilecli {
|
|
20
|
+
private path;
|
|
21
|
+
constructor();
|
|
22
|
+
private getPath;
|
|
23
|
+
executeCommand(args: string[]): string;
|
|
24
|
+
spawnCommand(args: string[]): ChildProcess;
|
|
25
|
+
executeCommandBuffer(args: string[]): Buffer;
|
|
26
|
+
private static getMobilecliPath;
|
|
27
|
+
getVersion(): string;
|
|
28
|
+
fleetListDevices(): string;
|
|
29
|
+
fleetAllocate(platform: "ios" | "android"): string;
|
|
30
|
+
fleetRelease(deviceId: string): string;
|
|
31
|
+
getDevices(options?: MobilecliDevicesOptions): MobilecliDevicesResponse;
|
|
32
|
+
}
|
package/lib/mobilecli.js
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Mobilecli = void 0;
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
const node_child_process_1 = require("node:child_process");
|
|
7
|
+
const TIMEOUT = 30000;
|
|
8
|
+
const MAX_BUFFER_SIZE = 1024 * 1024 * 8;
|
|
9
|
+
class Mobilecli {
|
|
10
|
+
path = null;
|
|
11
|
+
constructor() { }
|
|
12
|
+
getPath() {
|
|
13
|
+
if (!this.path) {
|
|
14
|
+
this.path = Mobilecli.getMobilecliPath();
|
|
15
|
+
}
|
|
16
|
+
return this.path;
|
|
17
|
+
}
|
|
18
|
+
executeCommand(args) {
|
|
19
|
+
const path = this.getPath();
|
|
20
|
+
return (0, node_child_process_1.execFileSync)(path, args, { encoding: "utf8" }).toString().trim();
|
|
21
|
+
}
|
|
22
|
+
spawnCommand(args) {
|
|
23
|
+
const binaryPath = this.getPath();
|
|
24
|
+
return (0, node_child_process_1.spawn)(binaryPath, args, {
|
|
25
|
+
stdio: ["ignore", "ignore", "ignore"],
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
executeCommandBuffer(args) {
|
|
29
|
+
const path = this.getPath();
|
|
30
|
+
return (0, node_child_process_1.execFileSync)(path, args, {
|
|
31
|
+
encoding: "buffer",
|
|
32
|
+
maxBuffer: MAX_BUFFER_SIZE,
|
|
33
|
+
timeout: TIMEOUT,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
static getMobilecliPath() {
|
|
37
|
+
if (process.env.MOBILECLI_PATH) {
|
|
38
|
+
return process.env.MOBILECLI_PATH;
|
|
39
|
+
}
|
|
40
|
+
const platform = process.platform;
|
|
41
|
+
const arch = process.arch;
|
|
42
|
+
const normalizedPlatform = platform === "win32" ? "windows" : platform;
|
|
43
|
+
const normalizedArch = arch === "arm64" ? "arm64" : "amd64";
|
|
44
|
+
const ext = platform === "win32" ? ".exe" : "";
|
|
45
|
+
const binaryName = `mobilecli-${normalizedPlatform}-${normalizedArch}${ext}`;
|
|
46
|
+
// Check if mobile-mcp is installed as a package
|
|
47
|
+
const currentPath = __filename;
|
|
48
|
+
const pathParts = currentPath.split(node_path_1.sep);
|
|
49
|
+
const lastNodeModulesIndex = pathParts.lastIndexOf("node_modules");
|
|
50
|
+
if (lastNodeModulesIndex !== -1) {
|
|
51
|
+
// We're inside node_modules, go to the last node_modules in the path
|
|
52
|
+
const nodeModulesParts = pathParts.slice(0, lastNodeModulesIndex + 1);
|
|
53
|
+
const lastNodeModulesPath = nodeModulesParts.join(node_path_1.sep);
|
|
54
|
+
const mobilecliPath = (0, node_path_1.join)(lastNodeModulesPath, "@mobilenext", "mobilecli", "bin", binaryName);
|
|
55
|
+
if ((0, node_fs_1.existsSync)(mobilecliPath)) {
|
|
56
|
+
return mobilecliPath;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// Not in node_modules, look one directory up from current script
|
|
60
|
+
const scriptDir = (0, node_path_1.dirname)(__filename);
|
|
61
|
+
const parentDir = (0, node_path_1.dirname)(scriptDir);
|
|
62
|
+
const mobilecliPath = (0, node_path_1.join)(parentDir, "node_modules", "@mobilenext", "mobilecli", "bin", binaryName);
|
|
63
|
+
if ((0, node_fs_1.existsSync)(mobilecliPath)) {
|
|
64
|
+
return mobilecliPath;
|
|
65
|
+
}
|
|
66
|
+
throw new Error(`Could not find mobilecli binary for platform: ${platform}`);
|
|
67
|
+
}
|
|
68
|
+
getVersion() {
|
|
69
|
+
try {
|
|
70
|
+
const output = this.executeCommand(["--version"]);
|
|
71
|
+
if (output.startsWith("mobilecli version ")) {
|
|
72
|
+
return output.substring("mobilecli version ".length);
|
|
73
|
+
}
|
|
74
|
+
return "failed";
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
return "failed " + error.message;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
fleetListDevices() {
|
|
81
|
+
return this.executeCommand(["fleet", "list-devices"]);
|
|
82
|
+
}
|
|
83
|
+
fleetAllocate(platform) {
|
|
84
|
+
return this.executeCommand(["fleet", "allocate", "--platform", platform]);
|
|
85
|
+
}
|
|
86
|
+
fleetRelease(deviceId) {
|
|
87
|
+
return this.executeCommand(["fleet", "release", "--device", deviceId]);
|
|
88
|
+
}
|
|
89
|
+
getDevices(options) {
|
|
90
|
+
const args = ["devices"];
|
|
91
|
+
if (options) {
|
|
92
|
+
if (options.includeOffline) {
|
|
93
|
+
args.push("--include-offline");
|
|
94
|
+
}
|
|
95
|
+
if (options.platform) {
|
|
96
|
+
if (options.platform !== "ios" && options.platform !== "android") {
|
|
97
|
+
throw new Error(`Invalid platform: ${options.platform}. Must be "ios" or "android"`);
|
|
98
|
+
}
|
|
99
|
+
args.push("--platform", options.platform);
|
|
100
|
+
}
|
|
101
|
+
if (options.type) {
|
|
102
|
+
if (options.type !== "real" && options.type !== "emulator" && options.type !== "simulator") {
|
|
103
|
+
throw new Error(`Invalid type: ${options.type}. Must be "real", "emulator", or "simulator"`);
|
|
104
|
+
}
|
|
105
|
+
args.push("--type", options.type);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const mobilecliOutput = this.executeCommand(args);
|
|
109
|
+
return JSON.parse(mobilecliOutput);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
exports.Mobilecli = Mobilecli;
|
|
113
|
+
//# sourceMappingURL=mobilecli.js.map
|