@nbakka/mcp-appium 3.0.25 → 4.0.1
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/lib/android.js +69 -8
- package/lib/ios.js +8 -0
- package/lib/iphone-simulator.js +4 -0
- package/lib/server.js +1359 -1673
- package/lib/webdriver-agent.js +63 -2
- package/package.json +6 -6
package/lib/android.js
CHANGED
|
@@ -124,17 +124,19 @@ class AndroidRobot {
|
|
|
124
124
|
let x0, y0, x1, y1;
|
|
125
125
|
switch (direction) {
|
|
126
126
|
case "up":
|
|
127
|
+
// Scroll up to reveal content above (swipe down gesture: top to bottom)
|
|
127
128
|
x0 = x1 = centerX;
|
|
128
|
-
y0 = Math.floor(screenSize.height * 0.
|
|
129
|
-
y1 = Math.floor(screenSize.height * 0.
|
|
129
|
+
y0 = Math.floor(screenSize.height * 0.20);
|
|
130
|
+
y1 = Math.floor(screenSize.height * 0.80);
|
|
130
131
|
break;
|
|
131
132
|
case "down":
|
|
133
|
+
// Scroll down to reveal content below (swipe up gesture: bottom to top)
|
|
132
134
|
x0 = x1 = centerX;
|
|
133
|
-
y0 = Math.floor(screenSize.height * 0.
|
|
134
|
-
y1 = Math.floor(screenSize.height * 0.
|
|
135
|
+
y0 = Math.floor(screenSize.height * 0.80);
|
|
136
|
+
y1 = Math.floor(screenSize.height * 0.20);
|
|
135
137
|
break;
|
|
136
138
|
default:
|
|
137
|
-
throw new robot_1.ActionableError(`
|
|
139
|
+
throw new robot_1.ActionableError(`Scroll direction "${direction}" is not supported`);
|
|
138
140
|
}
|
|
139
141
|
this.adb("shell", "input", "swipe", `${x0}`, `${y0}`, `${x1}`, `${y1}`, "1000");
|
|
140
142
|
}
|
|
@@ -170,12 +172,71 @@ class AndroidRobot {
|
|
|
170
172
|
}
|
|
171
173
|
return elements;
|
|
172
174
|
}
|
|
173
|
-
|
|
175
|
+
collectSimplifiedElements(node) {
|
|
176
|
+
const elements = [];
|
|
177
|
+
|
|
178
|
+
// Recursively traverse children first
|
|
179
|
+
if (node.node) {
|
|
180
|
+
if (Array.isArray(node.node)) {
|
|
181
|
+
for (const childNode of node.node) {
|
|
182
|
+
elements.push(...this.collectSimplifiedElements(childNode));
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
elements.push(...this.collectSimplifiedElements(node.node));
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Only include element if it has at least one useful attribute
|
|
191
|
+
const hasText = node.text && node.text.trim().length > 0;
|
|
192
|
+
const hasContentDesc = node["content-desc"] && node["content-desc"].trim().length > 0;
|
|
193
|
+
const hasResourceId = node["resource-id"] && node["resource-id"].trim().length > 0;
|
|
194
|
+
|
|
195
|
+
if (hasText || hasContentDesc || hasResourceId) {
|
|
196
|
+
const element = {};
|
|
197
|
+
|
|
198
|
+
// Only include fields that have values
|
|
199
|
+
if (hasText) {
|
|
200
|
+
element.text = node.text;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (node.class) {
|
|
204
|
+
element.class = node.class;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (hasResourceId) {
|
|
208
|
+
element.id = node["resource-id"];
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (hasContentDesc) {
|
|
212
|
+
element.accessibilityId = node["content-desc"];
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (node.bounds) {
|
|
216
|
+
element.bounds = node.bounds;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
elements.push(element);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return elements;
|
|
223
|
+
}
|
|
224
|
+
async getXmlStructure() {
|
|
174
225
|
const parsedXml = await this.getUiAutomatorXml();
|
|
175
|
-
// const hierarchy = parsedXml.hierarchy;
|
|
176
|
-
// const elements = this.collectElements(hierarchy.node);
|
|
177
226
|
return parsedXml;
|
|
178
227
|
}
|
|
228
|
+
async getElementsOnScreen() {
|
|
229
|
+
const parsedXml = await this.getUiAutomatorXml();
|
|
230
|
+
const hierarchy = parsedXml.hierarchy;
|
|
231
|
+
const elements = this.collectElements(hierarchy.node);
|
|
232
|
+
return elements;
|
|
233
|
+
}
|
|
234
|
+
async getSimplifiedElements() {
|
|
235
|
+
const parsedXml = await this.getUiAutomatorXml();
|
|
236
|
+
const hierarchy = parsedXml.hierarchy;
|
|
237
|
+
const elements = this.collectSimplifiedElements(hierarchy.node);
|
|
238
|
+
return elements;
|
|
239
|
+
}
|
|
179
240
|
async terminateApp(packageName) {
|
|
180
241
|
this.adb("shell", "am", "force-stop", packageName);
|
|
181
242
|
}
|
package/lib/ios.js
CHANGED
|
@@ -124,6 +124,14 @@ class IosRobot {
|
|
|
124
124
|
const wda = await this.wda();
|
|
125
125
|
return await wda.getElementsOnScreen();
|
|
126
126
|
}
|
|
127
|
+
async getXmlStructure() {
|
|
128
|
+
const wda = await this.wda();
|
|
129
|
+
return await wda.getXmlStructure();
|
|
130
|
+
}
|
|
131
|
+
async getSimplifiedElements() {
|
|
132
|
+
const wda = await this.wda();
|
|
133
|
+
return await wda.getSimplifiedElements();
|
|
134
|
+
}
|
|
127
135
|
async getScreenshot() {
|
|
128
136
|
await this.assertTunnelRunning();
|
|
129
137
|
const tmpFilename = path_1.default.join((0, os_1.tmpdir)(), `screenshot-${(0, crypto_1.randomBytes)(8).toString("hex")}.png`);
|
package/lib/iphone-simulator.js
CHANGED
|
@@ -136,6 +136,10 @@ class Simctl {
|
|
|
136
136
|
const wda = await this.wda();
|
|
137
137
|
return wda.getElementsOnScreen();
|
|
138
138
|
}
|
|
139
|
+
async getSimplifiedElements() {
|
|
140
|
+
const wda = await this.wda();
|
|
141
|
+
return wda.getSimplifiedElements();
|
|
142
|
+
}
|
|
139
143
|
async setOrientation(orientation) {
|
|
140
144
|
const wda = await this.wda();
|
|
141
145
|
return wda.setOrientation(orientation);
|