@midscene/web 0.12.9-beta-20250324113701.0 → 0.13.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/README.md +16 -4
- package/dist/es/{android.js → appium.js} +177 -279
- package/dist/es/appium.js.map +1 -0
- package/dist/es/bridge-mode-browser.js +3 -3
- package/dist/es/bridge-mode-browser.js.map +1 -1
- package/dist/es/bridge-mode.js +5 -5
- package/dist/es/bridge-mode.js.map +1 -1
- package/dist/es/chrome-extension.js +4 -4
- package/dist/es/chrome-extension.js.map +1 -1
- package/dist/es/index.js +272 -352
- package/dist/es/index.js.map +1 -1
- package/dist/es/midscene-playground.js +3 -3
- package/dist/es/midscene-playground.js.map +1 -1
- package/dist/es/playground.js +3 -3
- package/dist/es/playground.js.map +1 -1
- package/dist/es/playwright.js +99 -77
- package/dist/es/playwright.js.map +1 -1
- package/dist/es/puppeteer.js +3 -3
- package/dist/es/puppeteer.js.map +1 -1
- package/dist/lib/{android.js → appium.js} +180 -284
- package/dist/lib/appium.js.map +1 -0
- package/dist/lib/bridge-mode-browser.js +3 -3
- package/dist/lib/bridge-mode-browser.js.map +1 -1
- package/dist/lib/bridge-mode.js +5 -5
- package/dist/lib/bridge-mode.js.map +1 -1
- package/dist/lib/chrome-extension.js +4 -4
- package/dist/lib/chrome-extension.js.map +1 -1
- package/dist/lib/index.js +271 -353
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/midscene-playground.js +3 -3
- package/dist/lib/midscene-playground.js.map +1 -1
- package/dist/lib/playground.js +3 -3
- package/dist/lib/playground.js.map +1 -1
- package/dist/lib/playwright.js +99 -77
- package/dist/lib/playwright.js.map +1 -1
- package/dist/lib/puppeteer.js +3 -3
- package/dist/lib/puppeteer.js.map +1 -1
- package/dist/types/{agent-27118467.d.ts → agent-77ade165.d.ts} +2 -2
- package/dist/types/{android.d.ts → appium.d.ts} +3 -3
- package/dist/types/bridge-mode-browser.d.ts +3 -3
- package/dist/types/bridge-mode.d.ts +4 -4
- package/dist/types/{browser-3d632bea.d.ts → browser-178b6a27.d.ts} +1 -1
- package/dist/types/chrome-extension.d.ts +4 -4
- package/dist/types/index.d.ts +4 -4
- package/dist/types/{page-3e1fa69c.d.ts → page-1f2132ee.d.ts} +4 -28
- package/dist/types/playground.d.ts +4 -4
- package/dist/types/playwright.d.ts +30 -6
- package/dist/types/puppeteer.d.ts +3 -3
- package/dist/types/{utils-838044c6.d.ts → utils-4d9403e6.d.ts} +1 -1
- package/dist/types/utils.d.ts +2 -2
- package/dist/types/yaml.d.ts +4 -4
- package/package.json +22 -17
- package/bin/yadb +0 -0
- package/dist/es/android.js.map +0 -1
- package/dist/lib/android.js.map +0 -1
package/README.md
CHANGED
|
@@ -4,13 +4,25 @@ Automate browser actions, extract data, and perform assertions using AI. It offe
|
|
|
4
4
|
|
|
5
5
|
See https://midscenejs.com/ for details.
|
|
6
6
|
|
|
7
|
-
## Android prerequisites
|
|
7
|
+
## iOS/Android prerequisites
|
|
8
8
|
|
|
9
|
-
Android is driven by
|
|
10
|
-
- [CLI](https://
|
|
9
|
+
iOS/Android is driven by appium, so you need the following Appium tool chain first:
|
|
10
|
+
- [CLI](https://appium.io/docs/en/latest/quickstart/install/)
|
|
11
|
+
- Driver
|
|
12
|
+
- [iOS](https://github.com/appium/appium-xcuitest-driver)
|
|
13
|
+
- [Android](https://github.com/appium/appium-uiautomator2-driver)
|
|
14
|
+
- [Plugin](https://github.com/appium/appium/tree/master/packages/universal-xml-plugin)
|
|
15
|
+
|
|
16
|
+
then execute the command to start appium server:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
appium --use-plugins=universal-xml
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
now you can use run tests for iOS/Android devices:
|
|
11
23
|
|
|
12
24
|
```bash
|
|
13
|
-
npm run test:ai --
|
|
25
|
+
npm run test:ai -- appium
|
|
14
26
|
```
|
|
15
27
|
|
|
16
28
|
## License
|
|
@@ -1169,7 +1169,7 @@ var PageTaskExecutor = class {
|
|
|
1169
1169
|
let planningTask = this.planningTaskFromPrompt(userPrompt, cacheGroup);
|
|
1170
1170
|
let result;
|
|
1171
1171
|
let replanCount = 0;
|
|
1172
|
-
const
|
|
1172
|
+
const logList = [];
|
|
1173
1173
|
while (planningTask) {
|
|
1174
1174
|
if (replanCount > replanningCountLimit) {
|
|
1175
1175
|
const errorMsg = "Replanning too many times, please split the task into multiple steps";
|
|
@@ -1204,7 +1204,7 @@ var PageTaskExecutor = class {
|
|
|
1204
1204
|
};
|
|
1205
1205
|
}
|
|
1206
1206
|
if (planResult?.log) {
|
|
1207
|
-
|
|
1207
|
+
logList.push(planResult.log);
|
|
1208
1208
|
}
|
|
1209
1209
|
if (!planResult.more_actions_needed_by_instruction) {
|
|
1210
1210
|
planningTask = null;
|
|
@@ -1213,7 +1213,7 @@ var PageTaskExecutor = class {
|
|
|
1213
1213
|
planningTask = this.planningTaskFromPrompt(
|
|
1214
1214
|
userPrompt,
|
|
1215
1215
|
cacheGroup,
|
|
1216
|
-
|
|
1216
|
+
logList.length > 0 ? `- ${logList.join("\n- ")}` : void 0
|
|
1217
1217
|
);
|
|
1218
1218
|
replanCount++;
|
|
1219
1219
|
}
|
|
@@ -1832,154 +1832,48 @@ ${errors}`);
|
|
|
1832
1832
|
}
|
|
1833
1833
|
};
|
|
1834
1834
|
|
|
1835
|
-
// src/
|
|
1835
|
+
// src/appium/page.ts
|
|
1836
1836
|
import fs from "fs";
|
|
1837
|
-
import path from "path";
|
|
1838
1837
|
import { getTmpFile } from "@midscene/core/utils";
|
|
1839
|
-
import {
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1838
|
+
import {
|
|
1839
|
+
clientExtractTextWithPosition
|
|
1840
|
+
} from "@midscene/shared/extractor";
|
|
1841
|
+
import { base64Encoded, resizeImg } from "@midscene/shared/img";
|
|
1842
|
+
import { DOMParser } from "@xmldom/xmldom";
|
|
1843
|
+
function buttonToNumber(button) {
|
|
1844
|
+
return button === "left" ? 0 : button === "middle" ? 1 : 2;
|
|
1845
|
+
}
|
|
1843
1846
|
var Page = class {
|
|
1844
|
-
constructor(
|
|
1845
|
-
this.
|
|
1846
|
-
this.
|
|
1847
|
-
this.deviceRatio = 1;
|
|
1848
|
-
this.pageType = "android";
|
|
1849
|
-
this.deviceId = deviceId;
|
|
1850
|
-
this.adbPromise = this.initAdb();
|
|
1851
|
-
}
|
|
1852
|
-
async initAdb() {
|
|
1853
|
-
try {
|
|
1854
|
-
debugPage(`Initializing ADB with device ID: ${this.deviceId}`);
|
|
1855
|
-
const adb = await ADB.createADB({
|
|
1856
|
-
udid: this.deviceId,
|
|
1857
|
-
adbExecTimeout: 6e4
|
|
1858
|
-
});
|
|
1859
|
-
debugPage("ADB initialized successfully");
|
|
1860
|
-
return adb;
|
|
1861
|
-
} catch (error) {
|
|
1862
|
-
console.error(`Failed to initialize ADB: ${error}`);
|
|
1863
|
-
throw error;
|
|
1864
|
-
}
|
|
1865
|
-
}
|
|
1866
|
-
async getAdb() {
|
|
1867
|
-
return this.adbPromise;
|
|
1868
|
-
}
|
|
1869
|
-
async execYadb(keyboardContent) {
|
|
1870
|
-
await this.pushYadb();
|
|
1871
|
-
const adb = await this.getAdb();
|
|
1872
|
-
await adb.shell(
|
|
1873
|
-
`app_process -Djava.class.path=/data/local/tmp/yadb /data/local/tmp com.ysbing.yadb.Main -keyboard "${keyboardContent}"`
|
|
1874
|
-
);
|
|
1847
|
+
constructor(browser) {
|
|
1848
|
+
this.pageType = "appium";
|
|
1849
|
+
this.browser = browser;
|
|
1875
1850
|
}
|
|
1876
1851
|
async getElementsInfo() {
|
|
1877
|
-
|
|
1852
|
+
const pageSource = await this.browser.getPageSource();
|
|
1853
|
+
const { width, height } = await this.browser.getWindowSize();
|
|
1854
|
+
const parser = new DOMParser();
|
|
1855
|
+
const doc = parser.parseFromString(pageSource, "text/xml");
|
|
1856
|
+
const infos = clientExtractTextWithPosition(doc).filter(
|
|
1857
|
+
(element) => element.rect.height !== height && element.rect.width !== width && element.rect.left !== 0 && element.rect.top !== 0 && element.attributes.visible === "true"
|
|
1858
|
+
);
|
|
1859
|
+
return infos;
|
|
1878
1860
|
}
|
|
1879
1861
|
async getElementsNodeTree() {
|
|
1880
|
-
|
|
1881
|
-
node: null,
|
|
1882
|
-
children: []
|
|
1883
|
-
};
|
|
1862
|
+
throw new Error("Not implemented");
|
|
1884
1863
|
}
|
|
1885
1864
|
async size() {
|
|
1886
|
-
|
|
1887
|
-
return this.screenSize;
|
|
1888
|
-
}
|
|
1889
|
-
try {
|
|
1890
|
-
const adb = await this.getAdb();
|
|
1891
|
-
const screenSize = await adb.getScreenSize();
|
|
1892
|
-
let width;
|
|
1893
|
-
let height;
|
|
1894
|
-
if (typeof screenSize === "string") {
|
|
1895
|
-
const match = screenSize.match(/(\d+)x(\d+)/);
|
|
1896
|
-
if (!match || match.length < 3) {
|
|
1897
|
-
throw new Error(`Unable to parse screen size: ${screenSize}`);
|
|
1898
|
-
}
|
|
1899
|
-
width = Number.parseInt(match[1], 10);
|
|
1900
|
-
height = Number.parseInt(match[2], 10);
|
|
1901
|
-
} else if (typeof screenSize === "object" && screenSize !== null) {
|
|
1902
|
-
const sizeObj = screenSize;
|
|
1903
|
-
if ("width" in sizeObj && "height" in sizeObj) {
|
|
1904
|
-
width = Number(sizeObj.width);
|
|
1905
|
-
height = Number(sizeObj.height);
|
|
1906
|
-
} else {
|
|
1907
|
-
throw new Error(
|
|
1908
|
-
`Invalid screen size object: ${JSON.stringify(screenSize)}`
|
|
1909
|
-
);
|
|
1910
|
-
}
|
|
1911
|
-
} else {
|
|
1912
|
-
throw new Error(`Invalid screen size format: ${screenSize}`);
|
|
1913
|
-
}
|
|
1914
|
-
try {
|
|
1915
|
-
const densityNum = await adb.getScreenDensity();
|
|
1916
|
-
this.deviceRatio = Number(densityNum) / 160;
|
|
1917
|
-
debugPage(`Device display ratio: ${this.deviceRatio}`);
|
|
1918
|
-
} catch (error) {
|
|
1919
|
-
console.warn("Error getting device density:", error);
|
|
1920
|
-
}
|
|
1921
|
-
const { x: logicalWidth, y: logicalHeight } = this.reverseAdjustCoordinates(width, height);
|
|
1922
|
-
this.screenSize = {
|
|
1923
|
-
width: logicalWidth,
|
|
1924
|
-
height: logicalHeight
|
|
1925
|
-
};
|
|
1926
|
-
return this.screenSize;
|
|
1927
|
-
} catch (error) {
|
|
1928
|
-
console.error("Error getting screen size:", error);
|
|
1929
|
-
return { width: 720, height: 1280 };
|
|
1930
|
-
}
|
|
1931
|
-
}
|
|
1932
|
-
/**
|
|
1933
|
-
* Convert logical coordinates to physical coordinates, handling device ratio
|
|
1934
|
-
* @param x Logical X coordinate
|
|
1935
|
-
* @param y Logical Y coordinate
|
|
1936
|
-
* @returns Physical coordinate point
|
|
1937
|
-
*/
|
|
1938
|
-
adjustCoordinates(x, y) {
|
|
1939
|
-
const ratio = this.deviceRatio;
|
|
1940
|
-
return {
|
|
1941
|
-
x: Math.round(x * ratio),
|
|
1942
|
-
y: Math.round(y * ratio)
|
|
1943
|
-
};
|
|
1944
|
-
}
|
|
1945
|
-
/**
|
|
1946
|
-
* Convert physical coordinates to logical coordinates, handling device ratio
|
|
1947
|
-
* @param x Physical X coordinate
|
|
1948
|
-
* @param y Physical Y coordinate
|
|
1949
|
-
* @returns Logical coordinate point
|
|
1950
|
-
*/
|
|
1951
|
-
reverseAdjustCoordinates(x, y) {
|
|
1952
|
-
const ratio = this.deviceRatio;
|
|
1953
|
-
return {
|
|
1954
|
-
x: Math.round(x / ratio),
|
|
1955
|
-
y: Math.round(y / ratio)
|
|
1956
|
-
};
|
|
1865
|
+
return this.browser.getWindowSize();
|
|
1957
1866
|
}
|
|
1958
1867
|
async screenshotBase64() {
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
await adb.shell("screencap -p /sdcard/screenshot.png");
|
|
1969
|
-
await adb.pull("/sdcard/screenshot.png", screenshotPath);
|
|
1970
|
-
screenshotBuffer = await fs.promises.readFile(screenshotPath);
|
|
1971
|
-
}
|
|
1972
|
-
const resizedScreenshotBuffer = await resizeImg(screenshotBuffer, {
|
|
1973
|
-
width,
|
|
1974
|
-
height
|
|
1975
|
-
});
|
|
1976
|
-
const result = `data:image/jpeg;base64,${resizedScreenshotBuffer.toString("base64")}`;
|
|
1977
|
-
debugPage("screenshotBase64 end");
|
|
1978
|
-
return result;
|
|
1979
|
-
} catch (error) {
|
|
1980
|
-
console.error("Error taking screenshot:", error);
|
|
1981
|
-
throw error;
|
|
1982
|
-
}
|
|
1868
|
+
const { width, height } = await this.size();
|
|
1869
|
+
const path = getTmpFile("png");
|
|
1870
|
+
const screenshotBuffer = await this.browser.saveScreenshot(path);
|
|
1871
|
+
const resizedScreenshotBuffer = await resizeImg(screenshotBuffer, {
|
|
1872
|
+
width,
|
|
1873
|
+
height
|
|
1874
|
+
});
|
|
1875
|
+
fs.writeFileSync(path, resizedScreenshotBuffer);
|
|
1876
|
+
return base64Encoded(path);
|
|
1983
1877
|
}
|
|
1984
1878
|
get mouse() {
|
|
1985
1879
|
return {
|
|
@@ -1989,6 +1883,7 @@ var Page = class {
|
|
|
1989
1883
|
drag: (from, to) => this.mouseDrag(from, to)
|
|
1990
1884
|
};
|
|
1991
1885
|
}
|
|
1886
|
+
// Object that includes keyboard and mouse operations
|
|
1992
1887
|
get keyboard() {
|
|
1993
1888
|
return {
|
|
1994
1889
|
type: (text) => this.keyboardType(text),
|
|
@@ -1999,218 +1894,221 @@ var Page = class {
|
|
|
1999
1894
|
if (!element) {
|
|
2000
1895
|
return;
|
|
2001
1896
|
}
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
'app_process -Djava.class.path=/data/local/tmp/yadb /data/local/tmp com.ysbing.yadb.Main -keyboard "~CLEAR~"'
|
|
2007
|
-
);
|
|
2008
|
-
} catch (error) {
|
|
2009
|
-
console.error("Error clearing input:", error);
|
|
2010
|
-
}
|
|
1897
|
+
const ele = await this.browser.$(element.locator);
|
|
1898
|
+
const blank = " ";
|
|
1899
|
+
await this.keyboardType(blank);
|
|
1900
|
+
await ele.clearValue();
|
|
2011
1901
|
}
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
const
|
|
2016
|
-
return
|
|
2017
|
-
}
|
|
2018
|
-
|
|
2019
|
-
|
|
1902
|
+
url() {
|
|
1903
|
+
const platformName = this.browser.capabilities.platformName?.toLowerCase();
|
|
1904
|
+
if (platformName === "ios") {
|
|
1905
|
+
const bundleId = this.browser.capabilities.bundleId;
|
|
1906
|
+
return bundleId;
|
|
1907
|
+
}
|
|
1908
|
+
if (platformName === "android") {
|
|
1909
|
+
const appActivity = this.browser.capabilities.appActivity;
|
|
1910
|
+
return appActivity;
|
|
2020
1911
|
}
|
|
1912
|
+
return "";
|
|
2021
1913
|
}
|
|
1914
|
+
// Scroll to top element
|
|
2022
1915
|
async scrollUntilTop(startingPoint) {
|
|
2023
1916
|
if (startingPoint) {
|
|
2024
1917
|
await this.mouse.move(startingPoint.left, startingPoint.top);
|
|
2025
1918
|
}
|
|
2026
|
-
await this.mouseWheel(0, 9999999, 100);
|
|
1919
|
+
await this.mouseWheel(0, -9999999, 100);
|
|
2027
1920
|
}
|
|
1921
|
+
// Scroll to bottom element
|
|
2028
1922
|
async scrollUntilBottom(startingPoint) {
|
|
2029
1923
|
if (startingPoint) {
|
|
2030
1924
|
await this.mouse.move(startingPoint.left, startingPoint.top);
|
|
2031
1925
|
}
|
|
2032
|
-
await this.mouseWheel(0,
|
|
1926
|
+
await this.mouseWheel(0, 9999999, 100);
|
|
2033
1927
|
}
|
|
2034
1928
|
async scrollUntilLeft(startingPoint) {
|
|
2035
1929
|
if (startingPoint) {
|
|
2036
1930
|
await this.mouse.move(startingPoint.left, startingPoint.top);
|
|
2037
1931
|
}
|
|
2038
|
-
await this.mouseWheel(9999999, 0, 100);
|
|
1932
|
+
await this.mouseWheel(-9999999, 0, 100);
|
|
2039
1933
|
}
|
|
2040
1934
|
async scrollUntilRight(startingPoint) {
|
|
2041
1935
|
if (startingPoint) {
|
|
2042
1936
|
await this.mouse.move(startingPoint.left, startingPoint.top);
|
|
2043
1937
|
}
|
|
2044
|
-
await this.mouseWheel(
|
|
1938
|
+
await this.mouseWheel(9999999, 0, 100);
|
|
2045
1939
|
}
|
|
1940
|
+
// Scroll up one screen
|
|
2046
1941
|
async scrollUp(distance, startingPoint) {
|
|
2047
|
-
const { height } = await this.
|
|
1942
|
+
const { height } = await this.browser.getWindowSize();
|
|
2048
1943
|
const scrollDistance = distance || height * 0.7;
|
|
2049
1944
|
if (startingPoint) {
|
|
2050
1945
|
await this.mouse.move(startingPoint.left, startingPoint.top);
|
|
2051
1946
|
}
|
|
2052
|
-
await this.mouseWheel(0, scrollDistance, 1e3);
|
|
1947
|
+
await this.mouseWheel(0, -scrollDistance, 1e3);
|
|
2053
1948
|
}
|
|
1949
|
+
// Scroll down one screen
|
|
2054
1950
|
async scrollDown(distance, startingPoint) {
|
|
2055
|
-
const { height } = await this.
|
|
1951
|
+
const { height } = await this.browser.getWindowSize();
|
|
2056
1952
|
const scrollDistance = distance || height * 0.7;
|
|
2057
1953
|
if (startingPoint) {
|
|
2058
1954
|
await this.mouse.move(startingPoint.left, startingPoint.top);
|
|
2059
1955
|
}
|
|
2060
|
-
await this.mouseWheel(0,
|
|
1956
|
+
await this.mouseWheel(0, scrollDistance, 1e3);
|
|
2061
1957
|
}
|
|
2062
1958
|
async scrollLeft(distance, startingPoint) {
|
|
2063
|
-
const { width } = await this.
|
|
1959
|
+
const { width } = await this.browser.getWindowSize();
|
|
2064
1960
|
const scrollDistance = distance || width * 0.7;
|
|
2065
1961
|
if (startingPoint) {
|
|
2066
1962
|
await this.mouse.move(startingPoint.left, startingPoint.top);
|
|
2067
1963
|
}
|
|
2068
|
-
await this.mouseWheel(scrollDistance, 0, 1e3);
|
|
1964
|
+
await this.mouseWheel(-scrollDistance, 0, 1e3);
|
|
2069
1965
|
}
|
|
2070
1966
|
async scrollRight(distance, startingPoint) {
|
|
2071
|
-
const { width } = await this.
|
|
1967
|
+
const { width } = await this.browser.getWindowSize();
|
|
2072
1968
|
const scrollDistance = distance || width * 0.7;
|
|
2073
1969
|
if (startingPoint) {
|
|
2074
1970
|
await this.mouse.move(startingPoint.left, startingPoint.top);
|
|
2075
1971
|
}
|
|
2076
|
-
await this.mouseWheel(
|
|
2077
|
-
}
|
|
2078
|
-
async pushYadb() {
|
|
2079
|
-
if (!this.yadbPushed) {
|
|
2080
|
-
const adb = await this.getAdb();
|
|
2081
|
-
const yadbBin = path.join(__dirname, "../../bin/yadb");
|
|
2082
|
-
await adb.push(yadbBin, "/data/local/tmp");
|
|
2083
|
-
this.yadbPushed = true;
|
|
2084
|
-
}
|
|
1972
|
+
await this.mouseWheel(scrollDistance, 0, 1e3);
|
|
2085
1973
|
}
|
|
2086
1974
|
async keyboardType(text) {
|
|
2087
|
-
|
|
1975
|
+
const actions = [];
|
|
1976
|
+
for (const char of text) {
|
|
1977
|
+
actions.push({ type: "keyDown", value: char });
|
|
1978
|
+
actions.push({ type: "keyUp", value: char });
|
|
1979
|
+
}
|
|
1980
|
+
if (!actions.length) {
|
|
2088
1981
|
return;
|
|
2089
|
-
try {
|
|
2090
|
-
const adb = await this.getAdb();
|
|
2091
|
-
const isChinese = /[\p{Script=Han}\p{sc=Hani}]/u.test(text);
|
|
2092
|
-
if (!isChinese) {
|
|
2093
|
-
await adb.inputText(text);
|
|
2094
|
-
return;
|
|
2095
|
-
}
|
|
2096
|
-
await this.execYadb(text);
|
|
2097
|
-
} catch (error) {
|
|
2098
|
-
console.error("Error typing text:", error);
|
|
2099
|
-
throw error;
|
|
2100
1982
|
}
|
|
1983
|
+
await this.browser.performActions([
|
|
1984
|
+
{
|
|
1985
|
+
type: "key",
|
|
1986
|
+
id: "keyboard",
|
|
1987
|
+
actions
|
|
1988
|
+
}
|
|
1989
|
+
]);
|
|
2101
1990
|
}
|
|
2102
1991
|
async keyboardPress(key) {
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
Escape: 111,
|
|
2112
|
-
Home: 3,
|
|
2113
|
-
End: 123
|
|
2114
|
-
};
|
|
2115
|
-
const adb = await this.getAdb();
|
|
2116
|
-
const keyCode = keyCodeMap[key];
|
|
2117
|
-
if (keyCode !== void 0) {
|
|
2118
|
-
await adb.keyevent(keyCode);
|
|
2119
|
-
} else {
|
|
2120
|
-
if (key.length === 1) {
|
|
2121
|
-
const asciiCode = key.toUpperCase().charCodeAt(0);
|
|
2122
|
-
if (asciiCode >= 65 && asciiCode <= 90) {
|
|
2123
|
-
await adb.keyevent(asciiCode - 36);
|
|
2124
|
-
}
|
|
1992
|
+
await this.browser.performActions([
|
|
1993
|
+
{
|
|
1994
|
+
type: "key",
|
|
1995
|
+
id: "keyboard",
|
|
1996
|
+
actions: [
|
|
1997
|
+
{ type: "keyDown", value: key },
|
|
1998
|
+
{ type: "keyUp", value: key }
|
|
1999
|
+
]
|
|
2125
2000
|
}
|
|
2126
|
-
|
|
2001
|
+
]);
|
|
2127
2002
|
}
|
|
2128
2003
|
async keyboardPressAction(action) {
|
|
2129
2004
|
if (Array.isArray(action)) {
|
|
2130
2005
|
for (const act of action) {
|
|
2131
|
-
await this.
|
|
2006
|
+
await this.browser.performActions([
|
|
2007
|
+
{
|
|
2008
|
+
type: "key",
|
|
2009
|
+
id: "keyboard",
|
|
2010
|
+
actions: [
|
|
2011
|
+
{ type: "keyDown", value: act.key },
|
|
2012
|
+
{ type: "keyUp", value: act.key }
|
|
2013
|
+
]
|
|
2014
|
+
}
|
|
2015
|
+
]);
|
|
2132
2016
|
}
|
|
2133
2017
|
} else {
|
|
2134
|
-
await this.
|
|
2018
|
+
await this.browser.performActions([
|
|
2019
|
+
{
|
|
2020
|
+
type: "key",
|
|
2021
|
+
id: "keyboard",
|
|
2022
|
+
actions: [
|
|
2023
|
+
{ type: "keyDown", value: action.key },
|
|
2024
|
+
{ type: "keyUp", value: action.key }
|
|
2025
|
+
]
|
|
2026
|
+
}
|
|
2027
|
+
]);
|
|
2135
2028
|
}
|
|
2136
2029
|
}
|
|
2137
2030
|
async mouseClick(x, y, button = "left") {
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2031
|
+
await this.mouseMove(x, y);
|
|
2032
|
+
await this.browser.performActions([
|
|
2033
|
+
{
|
|
2034
|
+
type: "pointer",
|
|
2035
|
+
id: "mouse",
|
|
2036
|
+
parameters: { pointerType: "mouse" },
|
|
2037
|
+
actions: [
|
|
2038
|
+
{ type: "pointerMove", duration: 0, x, y },
|
|
2039
|
+
{ type: "pointerDown", button: buttonToNumber(button) },
|
|
2040
|
+
{ type: "pause", duration: 100 },
|
|
2041
|
+
{ type: "pointerUp", button: buttonToNumber(button) }
|
|
2042
|
+
]
|
|
2143
2043
|
}
|
|
2144
|
-
|
|
2145
|
-
const adb = await this.getAdb();
|
|
2146
|
-
const { x: adjustedX, y: adjustedY } = this.adjustCoordinates(x, y);
|
|
2147
|
-
await adb.shell(`input tap ${adjustedX} ${adjustedY}`);
|
|
2148
|
-
} catch (error) {
|
|
2149
|
-
console.error("Error clicking:", error);
|
|
2150
|
-
}
|
|
2044
|
+
]);
|
|
2151
2045
|
}
|
|
2152
2046
|
async mouseMove(x, y) {
|
|
2153
|
-
|
|
2047
|
+
await this.browser.performActions([
|
|
2048
|
+
{
|
|
2049
|
+
type: "pointer",
|
|
2050
|
+
id: "mouse",
|
|
2051
|
+
parameters: { pointerType: "mouse" },
|
|
2052
|
+
actions: [{ type: "pointerMove", duration: 0, x, y }]
|
|
2053
|
+
}
|
|
2054
|
+
]);
|
|
2154
2055
|
}
|
|
2155
2056
|
async mouseDrag(from, to) {
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2057
|
+
await this.browser.performActions([
|
|
2058
|
+
{
|
|
2059
|
+
type: "pointer",
|
|
2060
|
+
id: "mouse",
|
|
2061
|
+
parameters: { pointerType: "mouse" },
|
|
2062
|
+
actions: [
|
|
2063
|
+
{ type: "pointerMove", duration: 0, x: from.x, y: from.y },
|
|
2064
|
+
{ type: "pointerDown", button: 0 },
|
|
2065
|
+
{ type: "pointerMove", duration: 500, x: to.x, y: to.y },
|
|
2066
|
+
{ type: "pointerUp", button: 0 }
|
|
2067
|
+
]
|
|
2068
|
+
}
|
|
2069
|
+
]);
|
|
2164
2070
|
}
|
|
2165
2071
|
async mouseWheel(deltaX, deltaY, duration = 1e3) {
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
}
|
|
2072
|
+
const n = 4;
|
|
2073
|
+
const windowSize = await this.browser.getWindowSize();
|
|
2074
|
+
const startX = deltaX < 0 ? (n - 1) * (windowSize.width / n) : windowSize.width / n;
|
|
2075
|
+
const startY = deltaY < 0 ? (n - 1) * (windowSize.height / n) : windowSize.height / n;
|
|
2076
|
+
const maxNegativeDeltaX = startX;
|
|
2077
|
+
const maxPositiveDeltaX = (n - 1) * (windowSize.width / n);
|
|
2078
|
+
const maxNegativeDeltaY = startY;
|
|
2079
|
+
const maxPositiveDeltaY = (n - 1) * (windowSize.height / n);
|
|
2080
|
+
deltaX = Math.max(-maxNegativeDeltaX, Math.min(deltaX, maxPositiveDeltaX));
|
|
2081
|
+
deltaY = Math.max(-maxNegativeDeltaY, Math.min(deltaY, maxPositiveDeltaY));
|
|
2082
|
+
await this.browser.performActions([
|
|
2083
|
+
{
|
|
2084
|
+
type: "pointer",
|
|
2085
|
+
id: "finger1",
|
|
2086
|
+
parameters: { pointerType: "touch" },
|
|
2087
|
+
actions: [
|
|
2088
|
+
{ type: "pointerMove", duration: 0, x: startX, y: startY },
|
|
2089
|
+
{ type: "pointerDown", button: 0 },
|
|
2090
|
+
{ type: "pause", duration },
|
|
2091
|
+
{
|
|
2092
|
+
type: "pointerMove",
|
|
2093
|
+
duration,
|
|
2094
|
+
origin: "pointer",
|
|
2095
|
+
// Use 'pointer' as the starting point
|
|
2096
|
+
x: deltaX,
|
|
2097
|
+
// X offset relative to the starting point
|
|
2098
|
+
y: deltaY
|
|
2099
|
+
// Y offset relative to the starting point
|
|
2100
|
+
},
|
|
2101
|
+
{ type: "pointerUp", button: 0 }
|
|
2102
|
+
]
|
|
2103
|
+
}
|
|
2104
|
+
]);
|
|
2200
2105
|
}
|
|
2201
2106
|
async destroy() {
|
|
2202
|
-
try {
|
|
2203
|
-
const adb = await this.getAdb();
|
|
2204
|
-
await adb.shell("rm -f /sdcard/screenshot.png");
|
|
2205
|
-
await adb.shell("rm -f /sdcard/window_dump.xml");
|
|
2206
|
-
} catch (error) {
|
|
2207
|
-
console.error("Error during cleanup:", error);
|
|
2208
|
-
}
|
|
2209
2107
|
}
|
|
2210
2108
|
};
|
|
2211
2109
|
export {
|
|
2212
|
-
PageAgent as
|
|
2213
|
-
Page as
|
|
2110
|
+
PageAgent as AppiumAgent,
|
|
2111
|
+
Page as AppiumPage
|
|
2214
2112
|
};
|
|
2215
2113
|
|
|
2216
|
-
//# sourceMappingURL=
|
|
2114
|
+
//# sourceMappingURL=appium.js.map
|