appium-cdp-driver 1.0.0-beta.3
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/LICENSE +21 -0
- package/README.md +95 -0
- package/build/adb.js +87 -0
- package/build/commands/createSession.js +2 -0
- package/build/commands/element.js +61 -0
- package/build/commands/find.js +66 -0
- package/build/commands/index.js +12 -0
- package/build/commands/url.js +29 -0
- package/build/driver.js +85 -0
- package/build/index.js +51 -0
- package/build/logger.js +6 -0
- package/package.json +62 -0
- package/src/adb.js +72 -0
- package/src/cdp.js +9 -0
- package/src/commands/cookies.js +47 -0
- package/src/commands/createSession.js +1 -0
- package/src/commands/document.js +13 -0
- package/src/commands/element.js +43 -0
- package/src/commands/find.js +54 -0
- package/src/commands/index.js +12 -0
- package/src/commands/navigation.js +21 -0
- package/src/commands/url.js +17 -0
- package/src/driver.js +65 -0
- package/src/index.js +38 -0
- package/src/logger.js +5 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 AppiumTestDistribution
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Appium CDP Driver
|
|
2
|
+
|
|
3
|
+
Appium CDP Driver is a W3C WebDriver that allows you to connect to chromium based android mobile browsers like chrome & samsung browser through any WebDriver client.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Install `cdp-driver` (if not installed)
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
appium driver install --source npm appium-cdp-driver
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Run Appium
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
LOCAL_PROTOCOL=true appium server -pa /wd/hub --use-drivers=cdp-driver
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Capabilities
|
|
20
|
+
|
|
21
|
+
### Appium Capabilities
|
|
22
|
+
|
|
23
|
+
| Capability | Required | Type | Description |
|
|
24
|
+
| ----------------------- | :------: | :----: | ----------------------------- |
|
|
25
|
+
| `appium:automationName` | + | string | Must be `CDP` |
|
|
26
|
+
| `appium:browserName` | + | string | Must be `chrome` or `Terrace` |
|
|
27
|
+
|
|
28
|
+
### W3C Capabilities
|
|
29
|
+
|
|
30
|
+
| Capability | Required | Type | Description |
|
|
31
|
+
| -------------- | :------: | :----: | ----------------- |
|
|
32
|
+
| `platformName` | + | string | Must be `android` |
|
|
33
|
+
|
|
34
|
+
## Commands
|
|
35
|
+
|
|
36
|
+
| Command | Ref | Description | Implementation Status |
|
|
37
|
+
| ------------------------------------------------------------ | -------------------------------------------------------------------- | ----------------------- | --------------------- |
|
|
38
|
+
| [active](src/commands/active.js) | [here](https://www.w3.org/TR/webdriver/#dfn-get-active-element) | Get Active Element | ❌ |
|
|
39
|
+
| [back](src/commands/back.js) | [here](https://www.w3.org/TR/webdriver/#dfn-back) | Back | ✅ |
|
|
40
|
+
| [clear](src/commands/clear.js) | [here](https://www.w3.org/TR/webdriver/#dfn-element-clear) | Element Clear | ✅ |
|
|
41
|
+
| [click](src/commands/click.js) | [here](https://www.w3.org/TR/webdriver/#dfn-element-click) | Element Click | ✅ |
|
|
42
|
+
| [closeWindow](src/commands/closeWindow.js) | [here](https://www.w3.org/TR/webdriver/#dfn-close-window) | Close Window | ❌ |
|
|
43
|
+
| [createSession](src/commands/createSession.js) | [here](https://www.w3.org/TR/webdriver/#dfn-new-sessions) | New Session | ✅ |
|
|
44
|
+
| [createWindow](src/commands/createWindow.js) | [here](https://www.w3.org/TR/webdriver/#dfn-new-window) | New Window | ❌ |
|
|
45
|
+
| [deleteCookie](src/commands/deleteCookie.js) | [here](https://www.w3.org/TR/webdriver/#dfn-delete-cookie) | Delete Cookie | ✅ |
|
|
46
|
+
| [deleteCookies](src/commands/deleteCookies.js) | [here](https://www.w3.org/TR/webdriver/#dfn-delete-all-cookies) | Delete All Cookies | ✅ |
|
|
47
|
+
| [deleteSession](src/commands/deleteSession.js) | [here](https://www.w3.org/TR/webdriver/#dfn-delete-session) | Delete Session | ❌ |
|
|
48
|
+
| [elementDisplayed](src/commands/elementDisplayed.js) | [here](https://www.w3.org/TR/webdriver/#element-displayedness) | Is Element Displayed | ✅ |
|
|
49
|
+
| [elementEnabled](src/commands/elementEnabled.js) | [here](https://www.w3.org/TR/webdriver/#dfn-is-element-enabled) | Is Element Enabled | ✅ |
|
|
50
|
+
| [elementSelected](src/commands/elementSelected.js) | [here](https://www.w3.org/TR/webdriver/#dfn-is-element-selected) | Is Element Selected | ❌ |
|
|
51
|
+
| [execute](src/commands/execute.js) | [here](https://www.w3.org/TR/webdriver/#dfn-execute-script) | Execute Script | ❌ |
|
|
52
|
+
| [executeAsync](src/commands/executeAsync.js) | [here](https://www.w3.org/TR/webdriver/#dfn-execute-async-script) | Execute Async Script | ❌ |
|
|
53
|
+
| [findElOrEls](src/commands/findElOrEls.js) | [here](https://www.w3.org/TR/webdriver/#element-retrieval) | Find Elements | ✅ |
|
|
54
|
+
| [forward](src/commands/forward.js) | [here](https://www.w3.org/TR/webdriver/#dfn-forward) | Forward | ✅ |
|
|
55
|
+
| [fullScreenWindow](src/commands/fullScreenWindow.js) | [here](https://www.w3.org/TR/webdriver/#dfn-fullscreen-window) | Fullscreen Window | ❌ |
|
|
56
|
+
| [getAlertText](src/commands/getAlertText.js) | [here](https://www.w3.org/TR/webdriver/#dfn-get-alert-text) | Get Alert Text | ❌ |
|
|
57
|
+
| [getAttribute](src/commands/getAttribute.js) | [here](https://www.w3.org/TR/webdriver/#dfn-get-element-attribute) | Get Element Attribute | ❌ |
|
|
58
|
+
| [getComputedLabel](src/commands/getComputedLabel.js) | [here](https://www.w3.org/TR/webdriver/#dfn-get-computed-label) | Get Computed Label | ❌ |
|
|
59
|
+
| [getComputedRole](src/commands/getComputedRole.js) | [here](https://www.w3.org/TR/webdriver/#dfn-get-computed-role) | Get Computed Role | ❌ |
|
|
60
|
+
| [getCookie](src/commands/getCookie.js) | [here](https://www.w3.org/TR/webdriver/#dfn-get-named-cookie) | Get Named Cookie | ✅ |
|
|
61
|
+
| [getCookies](src/commands/getCookies.js) | [here](https://www.w3.org/TR/webdriver/#dfn-get-all-cookies) | Get All Cookies | ✅ |
|
|
62
|
+
| [getCssProperty](src/commands/getCssProperty.js) | [here](https://www.w3.org/TR/webdriver/#dfn-get-element-css-value) | Get Element CSS Value | ❌ |
|
|
63
|
+
| [getElementRect](src/commands/getElementRect.js) | [here](https://www.w3.org/TR/webdriver/#dfn-get-element-rect) | Get Element Rect | ❌ |
|
|
64
|
+
| [getElementScreenshot](src/commands/getElementScreenshot.js) | [here](https://www.w3.org/TR/webdriver/#dfn-take-element-screenshot) | Take Element Screenshot | ❌ |
|
|
65
|
+
| [getName](src/commands/getName.js) | [here](https://www.w3.org/TR/webdriver/#dfn-get-element-tag-name) | Get Element Tag Name | ❌ |
|
|
66
|
+
| [getPageSource](src/commands/getPageSource.js) | [here](https://www.w3.org/TR/webdriver/#dfn-get-page-source) | Get Page Source | ✅ |
|
|
67
|
+
| [getProperty](src/commands/getProperty.js) | [here](https://www.w3.org/TR/webdriver/#dfn-get-element-property) | Get Element Property | ❌ |
|
|
68
|
+
| [getScreenshot](src/commands/getScreenshot.js) | [here](https://www.w3.org/TR/webdriver/#dfn-take-screenshot) | Take Screenshot | ❌ |
|
|
69
|
+
| [getText](src/commands/getText.js) | [here](https://www.w3.org/TR/webdriver/#dfn-get-element-text) | Get Element Text | ✅ |
|
|
70
|
+
| [getTimeouts](src/commands/getTimeouts.js) | [here](https://www.w3.org/TR/webdriver/#dfn-get-timeouts) | Get Timeouts | ❌ |
|
|
71
|
+
| [getUrl](src/commands/url.js) | [here](https://www.w3.org/TR/webdriver/#dfn-get-current-url) | Get Current URL | ✅ |
|
|
72
|
+
| [getWindowHandle](src/commands/getWindowHandle.js) | [here](https://www.w3.org/TR/webdriver/#dfn-get-window-handle) | Get Window Handle | ❌ |
|
|
73
|
+
| [getWindowHandles](src/commands/getWindowHandles.js) | [here](https://www.w3.org/TR/webdriver/#dfn-get-window-handles) | Get Window Handles | ❌ |
|
|
74
|
+
| [getWindowRect](src/commands/getWindowRect.js) | [here](https://www.w3.org/TR/webdriver/#dfn-get-window-rect) | Get Window Rect | ❌ |
|
|
75
|
+
| [implicitWaitW3C](src/commands/implicitWaitW3C.js) | [here](https://www.w3.org/TR/webdriver/#dfn-set-timeouts) | Set Implicit Timeout | ❌ |
|
|
76
|
+
| [maximizeWindow](src/commands/maximizeWindow.js) | [here](https://www.w3.org/TR/webdriver/#dfn-maximize-window) | Maximize Window | ❌ |
|
|
77
|
+
| [minimizeWindow](src/commands/minimizeWindow.js) | [here](https://www.w3.org/TR/webdriver/#dfn-minimize-window) | Minimize Window | ❌ |
|
|
78
|
+
| [pageLoadTimeoutW3C](src/commands/pageLoadTimeoutW3C.js) | [here](https://www.w3.org/TR/webdriver/#dfn-set-timeouts) | Set Page Load Timeout | ❌ |
|
|
79
|
+
| [parentFrame](src/commands/parentFrame.js) | [here](https://www.w3.org/TR/webdriver/#dfn-switch-to-parent-frame) | Switch To Parent Frame | ❌ |
|
|
80
|
+
| [performActions](src/commands/performActions.js) | [here](https://www.w3.org/TR/webdriver/#dfn-perform-actions) | Perform Actions | ❌ |
|
|
81
|
+
| [postAcceptAlert](src/commands/postAcceptAlert.js) | [here](https://www.w3.org/TR/webdriver/#dfn-accept-alert) | Accept Alert | ❌ |
|
|
82
|
+
| [postDismissAlert](src/commands/postDismissAlert.js) | [here](https://www.w3.org/TR/webdriver/#dfn-dismiss-alert) | Dismiss Alert | ❌ |
|
|
83
|
+
| [printPage](src/commands/printPage.js) | [here](https://www.w3.org/TR/webdriver/#dfn-print-page) | Print Page | ❌ |
|
|
84
|
+
| [refresh](src/commands/refresh.js) | [here](https://www.w3.org/TR/webdriver/#dfn-refresh) | Refresh | ❌ |
|
|
85
|
+
| [releaseActions](src/commands/releaseActions.js) | [here](https://www.w3.org/TR/webdriver/#dfn-release-actions) | Release Actions | ❌ |
|
|
86
|
+
| [scriptTimeoutW3C](src/commands/scriptTimeoutW3C.js) | [here](https://www.w3.org/TR/webdriver/#dfn-set-timeouts) | Set Script Timeout | ❌ |
|
|
87
|
+
| [setAlertText](src/commands/setAlertText.js) | [here](https://www.w3.org/TR/webdriver/#dfn-send-alert-text) | Send Alert Text | ❌ |
|
|
88
|
+
| [setCookie](src/commands/setCookie.js) | [here](https://www.w3.org/TR/webdriver/#dfn-adding-a-cookie) | Add Cookie | ✅ |
|
|
89
|
+
| [setFrame](src/commands/setFrame.js) | [here](https://www.w3.org/TR/webdriver/#dfn-switch-to-frame) | Switch To Frame | ❌ |
|
|
90
|
+
| [setUrl](src/commands/url.js) | [here](https://www.w3.org/TR/webdriver/#dfn-navigate-to) | Navigate To | ✅ |
|
|
91
|
+
| [setValue](src/commands/setValue.js) | [here](https://www.w3.org/TR/webdriver/#dfn-element-send-keys) | Element Send Keys | ✅ |
|
|
92
|
+
| [setWindow](src/commands/setWindow.js) | [here](https://www.w3.org/TR/webdriver/#dfn-switch-to-window) | Switch To Window | ❌ |
|
|
93
|
+
| [setWindowRect](src/commands/setWindowRect.js) | [here](https://www.w3.org/TR/webdriver/#dfn-set-window-rect) | Set Window Rect | ❌ |
|
|
94
|
+
| [title](src/commands/title.js) | [here](https://www.w3.org/TR/webdriver/#dfn-get-title) | Get Title | ✅ |
|
|
95
|
+
| [uploadFile](src/commands/uploadFile.js) | - | Upload File | ❌ |
|
package/build/adb.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.startApplication = exports.adbExec = exports.requireSdkRoot = exports.getAdb = void 0;
|
|
16
|
+
const appium_adb_1 = require("appium-adb");
|
|
17
|
+
const support_1 = require("@appium/support");
|
|
18
|
+
const get_port_1 = __importDefault(require("get-port"));
|
|
19
|
+
let adb;
|
|
20
|
+
const START_APP_WAIT_DURATION = 60000;
|
|
21
|
+
function getAdb() {
|
|
22
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
23
|
+
try {
|
|
24
|
+
if (!adb) {
|
|
25
|
+
adb = yield appium_adb_1.ADB.createADB();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
catch (e) {
|
|
29
|
+
console.log(e);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
exports.getAdb = getAdb;
|
|
34
|
+
function requireSdkRoot() {
|
|
35
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
36
|
+
const sdkRoot = (0, appium_adb_1.getSdkRootFromEnv)();
|
|
37
|
+
const docMsg = "Read https://developer.android.com/studio/command-line/variables for more details";
|
|
38
|
+
if (_.isEmpty(sdkRoot)) {
|
|
39
|
+
throw new Error(`Neither ANDROID_HOME nor ANDROID_SDK_ROOT environment variable was exported. ${docMsg}`);
|
|
40
|
+
}
|
|
41
|
+
if (!(yield support_1.fs.exists(sdkRoot))) {
|
|
42
|
+
throw new Error(`The Android SDK root folder '${sdkRoot}' does not exist on the local file system. ${docMsg}`);
|
|
43
|
+
}
|
|
44
|
+
const stats = yield support_1.fs.stat(sdkRoot);
|
|
45
|
+
if (!stats.isDirectory()) {
|
|
46
|
+
throw new Error(`The Android SDK root '${sdkRoot}' must be a folder. ${docMsg}`);
|
|
47
|
+
}
|
|
48
|
+
return sdkRoot;
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
exports.requireSdkRoot = requireSdkRoot;
|
|
52
|
+
function adbExec(browser = "chrome") {
|
|
53
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
54
|
+
let freePort = yield (0, get_port_1.default)();
|
|
55
|
+
yield adb.adbExec([
|
|
56
|
+
"forward",
|
|
57
|
+
`tcp:${freePort}`,
|
|
58
|
+
`localabstract:${browser}_devtools_remote`,
|
|
59
|
+
]);
|
|
60
|
+
return freePort;
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
exports.adbExec = adbExec;
|
|
64
|
+
function startApplication(browser = 'chrome') {
|
|
65
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
66
|
+
const common = {
|
|
67
|
+
waitDuration: START_APP_WAIT_DURATION,
|
|
68
|
+
optionalIntentArguments: "-d www.appium.io",
|
|
69
|
+
};
|
|
70
|
+
const chrome = {
|
|
71
|
+
pkg: "com.android.chrome",
|
|
72
|
+
activity: "com.google.android.apps.chrome.Main",
|
|
73
|
+
};
|
|
74
|
+
const terrance = {
|
|
75
|
+
pkg: "com.sec.android.app.sbrowser",
|
|
76
|
+
activity: "com.sec.android.app.sbrowser.SBrowserMainActivity",
|
|
77
|
+
};
|
|
78
|
+
if (browser === 'chrome') {
|
|
79
|
+
yield adb.startApp(Object.assign({}, chrome, common));
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
yield adb.startApp(Object.assign({}, terrance, common));
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
exports.startApplication = startApplication;
|
|
87
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRiLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2FkYi5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7QUFBQSwyQ0FBb0Q7QUFDcEQsNkNBQXFDO0FBRXJDLHdEQUErQjtBQUUvQixJQUFJLEdBQUcsQ0FBQztBQUNSLE1BQU0sdUJBQXVCLEdBQUcsS0FBSyxDQUFDO0FBRXRDLFNBQXNCLE1BQU07O1FBQzFCLElBQUk7WUFDRixJQUFJLENBQUMsR0FBRyxFQUFFO2dCQUNSLEdBQUcsR0FBRyxNQUFNLGdCQUFHLENBQUMsU0FBUyxFQUFFLENBQUM7YUFDN0I7U0FDRjtRQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ1YsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUNoQjtJQUNILENBQUM7Q0FBQTtBQVJELHdCQVFDO0FBRUQsU0FBc0IsY0FBYzs7UUFDbEMsTUFBTSxPQUFPLEdBQUcsSUFBQSw4QkFBaUIsR0FBRSxDQUFDO1FBQ3BDLE1BQU0sTUFBTSxHQUNWLG1GQUFtRixDQUFDO1FBQ3RGLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRTtZQUN0QixNQUFNLElBQUksS0FBSyxDQUNiLGdGQUFnRixNQUFNLEVBQUUsQ0FDekYsQ0FBQztTQUNIO1FBRUQsSUFBSSxDQUFDLENBQUMsTUFBTSxZQUFFLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQUU7WUFDL0IsTUFBTSxJQUFJLEtBQUssQ0FDYixnQ0FBZ0MsT0FBTyw4Q0FBOEMsTUFBTSxFQUFFLENBQzlGLENBQUM7U0FDSDtRQUNELE1BQU0sS0FBSyxHQUFHLE1BQU0sWUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNyQyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxFQUFFO1lBQ3hCLE1BQU0sSUFBSSxLQUFLLENBQ2IseUJBQXlCLE9BQU8sdUJBQXVCLE1BQU0sRUFBRSxDQUNoRSxDQUFDO1NBQ0g7UUFDRCxPQUFPLE9BQU8sQ0FBQztJQUNqQixDQUFDO0NBQUE7QUF0QkQsd0NBc0JDO0FBRUQsU0FBc0IsT0FBTyxDQUFDLE9BQU8sR0FBRyxRQUFROztRQUM5QyxJQUFJLFFBQVEsR0FBRyxNQUFNLElBQUEsa0JBQU8sR0FBRSxDQUFDO1FBQy9CLE1BQU0sR0FBRyxDQUFDLE9BQU8sQ0FBQztZQUNoQixTQUFTO1lBQ1QsT0FBTyxRQUFRLEVBQUU7WUFDakIsaUJBQWlCLE9BQU8sa0JBQWtCO1NBQzNDLENBQUMsQ0FBQztRQUNILE9BQU8sUUFBUSxDQUFDO0lBQ2xCLENBQUM7Q0FBQTtBQVJELDBCQVFDO0FBRUQsU0FBc0IsZ0JBQWdCLENBQUMsT0FBTyxHQUFHLFFBQVE7O1FBQ3ZELE1BQU0sTUFBTSxHQUFHO1lBQ2IsWUFBWSxFQUFFLHVCQUF1QjtZQUNyQyx1QkFBdUIsRUFBRSxrQkFBa0I7U0FDNUMsQ0FBQztRQUNGLE1BQU0sTUFBTSxHQUFHO1lBQ2IsR0FBRyxFQUFFLG9CQUFvQjtZQUN6QixRQUFRLEVBQUUscUNBQXFDO1NBQ2hELENBQUM7UUFFRixNQUFNLFFBQVEsR0FBRztZQUNmLEdBQUcsRUFBRSw4QkFBOEI7WUFDbkMsUUFBUSxFQUFFLG1EQUFtRDtTQUM5RCxDQUFDO1FBQ0YsSUFBSSxPQUFPLEtBQUssUUFBUSxFQUFFO1lBQ3RCLE1BQU0sR0FBRyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQztTQUN6RDthQUFNO1lBQ0wsTUFBTSxHQUFHLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO1NBQ3pEO0lBQ0gsQ0FBQztDQUFBO0FBbkJELDRDQW1CQyJ9
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.helpers = exports.commands = void 0;
|
|
13
|
+
const taiko_1 = require("taiko");
|
|
14
|
+
const find_1 = require("./find");
|
|
15
|
+
let commands = {}, helpers = {}, extensions = {};
|
|
16
|
+
exports.commands = commands;
|
|
17
|
+
exports.helpers = helpers;
|
|
18
|
+
function _click(element) {
|
|
19
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
20
|
+
yield (0, taiko_1.click)(element);
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
commands.click = function click(elementId) {
|
|
24
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
25
|
+
const element = find_1.elementCache[elementId];
|
|
26
|
+
yield _click(element);
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
commands.getText = function getText(elementId) {
|
|
30
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
31
|
+
const element = find_1.elementCache[elementId];
|
|
32
|
+
return element.text();
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
commands.elementDisplayed = function elementDisplayed(elementId) {
|
|
36
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
37
|
+
const element = find_1.elementCache[elementId];
|
|
38
|
+
return element.isVisible();
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
commands.elementEnabled = function elementEnabled(elementId) {
|
|
42
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
43
|
+
const element = find_1.elementCache[elementId];
|
|
44
|
+
return !element.isDisabled();
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
commands.setValue = function setValue(value, elementId) {
|
|
48
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
49
|
+
const element = find_1.elementCache[elementId];
|
|
50
|
+
yield (0, taiko_1.write)(value, (0, taiko_1.into)(element));
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
commands.clear = function clear(elementId) {
|
|
54
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
55
|
+
const element = find_1.elementCache[elementId];
|
|
56
|
+
yield (0, taiko_1.write)('', (0, taiko_1.into)(element));
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
Object.assign(extensions, commands, helpers);
|
|
60
|
+
exports.default = extensions;
|
|
61
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWxlbWVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21tYW5kcy9lbGVtZW50LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQUNBLGlDQUEyQztBQUMzQyxpQ0FBc0M7QUFFdEMsSUFBSSxRQUFRLEdBQUcsRUFBRSxFQUNmLE9BQU8sR0FBRyxFQUFFLEVBQ1osVUFBVSxHQUFHLEVBQUUsQ0FBQztBQW9DVCw0QkFBUTtBQUFFLDBCQUFPO0FBbEMxQixTQUFlLE1BQU0sQ0FBQyxPQUFPOztRQUMzQixNQUFNLElBQUEsYUFBSyxFQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3ZCLENBQUM7Q0FBQTtBQUNELFFBQVEsQ0FBQyxLQUFLLEdBQUcsU0FBZSxLQUFLLENBQUMsU0FBUzs7UUFDN0MsTUFBTSxPQUFPLEdBQUcsbUJBQVksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN4QyxNQUFNLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUN4QixDQUFDO0NBQUEsQ0FBQztBQUVGLFFBQVEsQ0FBQyxPQUFPLEdBQUcsU0FBZSxPQUFPLENBQUMsU0FBUzs7UUFDakQsTUFBTSxPQUFPLEdBQUcsbUJBQVksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN4QyxPQUFPLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUN4QixDQUFDO0NBQUEsQ0FBQztBQUVGLFFBQVEsQ0FBQyxnQkFBZ0IsR0FBRyxTQUFlLGdCQUFnQixDQUFDLFNBQVM7O1FBQ25FLE1BQU0sT0FBTyxHQUFHLG1CQUFZLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDeEMsT0FBTyxPQUFPLENBQUMsU0FBUyxFQUFFLENBQUM7SUFDN0IsQ0FBQztDQUFBLENBQUM7QUFFRixRQUFRLENBQUMsY0FBYyxHQUFHLFNBQWUsY0FBYyxDQUFDLFNBQVM7O1FBQy9ELE1BQU0sT0FBTyxHQUFHLG1CQUFZLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDeEMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsQ0FBQztJQUMvQixDQUFDO0NBQUEsQ0FBQztBQUVGLFFBQVEsQ0FBQyxRQUFRLEdBQUcsU0FBZSxRQUFRLENBQUMsS0FBSyxFQUFFLFNBQVM7O1FBQzFELE1BQU0sT0FBTyxHQUFHLG1CQUFZLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDeEMsTUFBTSxJQUFBLGFBQUssRUFBQyxLQUFLLEVBQUUsSUFBQSxZQUFJLEVBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztJQUNwQyxDQUFDO0NBQUEsQ0FBQTtBQUVELFFBQVEsQ0FBQyxLQUFLLEdBQUcsU0FBZSxLQUFLLENBQUMsU0FBUzs7UUFDN0MsTUFBTSxPQUFPLEdBQUcsbUJBQVksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN4QyxNQUFNLElBQUEsYUFBSyxFQUFDLEVBQUUsRUFBRSxJQUFBLFlBQUksRUFBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO0lBQ2pDLENBQUM7Q0FBQSxDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUUsUUFBUSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBRTdDLGtCQUFlLFVBQVUsQ0FBQyJ9
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.elementCache = exports.helpers = exports.commands = void 0;
|
|
16
|
+
const base_driver_1 = require("@appium/base-driver");
|
|
17
|
+
const taiko_1 = require("taiko");
|
|
18
|
+
const logger_1 = __importDefault(require("../logger"));
|
|
19
|
+
const support_1 = require("@appium/support");
|
|
20
|
+
const constants_1 = require("@appium/base-driver/build/lib/constants");
|
|
21
|
+
let commands = {}, helpers = {}, extensions = {}, elementCache = {};
|
|
22
|
+
exports.commands = commands;
|
|
23
|
+
exports.helpers = helpers;
|
|
24
|
+
exports.elementCache = elementCache;
|
|
25
|
+
function getUUID() {
|
|
26
|
+
return support_1.util.uuidV4();
|
|
27
|
+
}
|
|
28
|
+
helpers.findElOrEls = function findElOrEls(strategy, selector, mult, context) {
|
|
29
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
30
|
+
logger_1.default.info(`Strategy is ${strategy}`);
|
|
31
|
+
logger_1.default.info(`Selector is ${selector}`);
|
|
32
|
+
logger_1.default.info(`Mult is ${mult}`);
|
|
33
|
+
logger_1.default.info(`Context is ${context}`);
|
|
34
|
+
const elStrategy = strategy === "xpath" ? (0, taiko_1.$)(selector) : (0, taiko_1.$)(`#${selector}`);
|
|
35
|
+
if ((yield elStrategy.exists()) && !mult) {
|
|
36
|
+
const elementId = getUUID();
|
|
37
|
+
elementCache[elementId] = elStrategy;
|
|
38
|
+
return { [constants_1.W3C_ELEMENT_KEY]: elementId };
|
|
39
|
+
}
|
|
40
|
+
else if (mult) {
|
|
41
|
+
let els = [];
|
|
42
|
+
(yield (0, taiko_1.$)(selector).elements()).forEach((element) => {
|
|
43
|
+
const elementId = getUUID();
|
|
44
|
+
elementCache[elementId] = element;
|
|
45
|
+
els.push({ ELEMENT: elementId });
|
|
46
|
+
});
|
|
47
|
+
return els;
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
throw new base_driver_1.errors.NoSuchElementError(`unable to find element: ${selector}`);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
};
|
|
54
|
+
commands.findElement = function findElement(strategy, selector) {
|
|
55
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
56
|
+
return this.findElOrEls(strategy, selector, false);
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
commands.findElements = function findElements(strategy, selector) {
|
|
60
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
61
|
+
return this.findElOrEls(strategy, selector, true);
|
|
62
|
+
});
|
|
63
|
+
};
|
|
64
|
+
Object.assign(extensions, commands, helpers);
|
|
65
|
+
exports.default = extensions;
|
|
66
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmluZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21tYW5kcy9maW5kLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHFEQUE2QztBQUM3QyxpQ0FBMEI7QUFDMUIsdURBQTRCO0FBQzVCLDZDQUF1QztBQUN2Qyx1RUFBMEU7QUFFMUUsSUFBSSxRQUFRLEdBQUcsRUFBRSxFQUNmLE9BQU8sR0FBRyxFQUFFLEVBQ1osVUFBVSxHQUFHLEVBQUUsRUFDZixZQUFZLEdBQUcsRUFBRSxDQUFDO0FBMkNYLDRCQUFRO0FBQUUsMEJBQU87QUFBRSxvQ0FBWTtBQXpDeEMsU0FBUyxPQUFPO0lBQ2QsT0FBTyxjQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7QUFDdkIsQ0FBQztBQUVELE9BQU8sQ0FBQyxXQUFXLEdBQUcsU0FBZSxXQUFXLENBQzlDLFFBQVEsRUFDUixRQUFRLEVBQ1IsSUFBSSxFQUNKLE9BQU87O1FBRVAsZ0JBQUcsQ0FBQyxJQUFJLENBQUMsZUFBZSxRQUFRLEVBQUUsQ0FBQyxDQUFDO1FBQ3BDLGdCQUFHLENBQUMsSUFBSSxDQUFDLGVBQWUsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUNwQyxnQkFBRyxDQUFDLElBQUksQ0FBQyxXQUFXLElBQUksRUFBRSxDQUFDLENBQUM7UUFDNUIsZ0JBQUcsQ0FBQyxJQUFJLENBQUMsY0FBYyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQ2xDLE1BQU0sVUFBVSxHQUFHLFFBQVEsS0FBSyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUEsU0FBQyxFQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFBLFNBQUMsRUFBQyxJQUFJLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDMUUsSUFBSSxDQUFDLE1BQU0sVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUU7WUFDeEMsTUFBTSxTQUFTLEdBQUcsT0FBTyxFQUFFLENBQUM7WUFDNUIsWUFBWSxDQUFDLFNBQVMsQ0FBQyxHQUFHLFVBQVUsQ0FBQztZQUNyQyxPQUFPLEVBQUUsQ0FBQywyQkFBZSxDQUFDLEVBQUUsU0FBUyxFQUFFLENBQUM7U0FDekM7YUFBTSxJQUFJLElBQUksRUFBRTtZQUNmLElBQUksR0FBRyxHQUFHLEVBQUUsQ0FBQztZQUNiLENBQUMsTUFBTSxJQUFBLFNBQUMsRUFBQyxRQUFRLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO2dCQUNqRCxNQUFNLFNBQVMsR0FBRyxPQUFPLEVBQUUsQ0FBQztnQkFDNUIsWUFBWSxDQUFDLFNBQVMsQ0FBQyxHQUFHLE9BQU8sQ0FBQztnQkFDbEMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDO1lBQ25DLENBQUMsQ0FBQyxDQUFDO1lBQ0gsT0FBTyxHQUFHLENBQUM7U0FDWjthQUFNO1lBQ0wsTUFBTSxJQUFJLG9CQUFNLENBQUMsa0JBQWtCLENBQUMsMkJBQTJCLFFBQVEsRUFBRSxDQUFDLENBQUM7U0FDNUU7SUFDSCxDQUFDO0NBQUEsQ0FBQztBQUVGLFFBQVEsQ0FBQyxXQUFXLEdBQUcsU0FBZSxXQUFXLENBQUMsUUFBUSxFQUFFLFFBQVE7O1FBQ2xFLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLEVBQUUsUUFBUSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ3JELENBQUM7Q0FBQSxDQUFDO0FBRUYsUUFBUSxDQUFDLFlBQVksR0FBRyxTQUFlLFlBQVksQ0FBQyxRQUFRLEVBQUUsUUFBUTs7UUFDcEUsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDcEQsQ0FBQztDQUFBLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFFN0Msa0JBQWUsVUFBVSxDQUFDIn0=
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const url_1 = __importDefault(require("./url"));
|
|
7
|
+
const find_1 = __importDefault(require("./find"));
|
|
8
|
+
const element_1 = __importDefault(require("./element"));
|
|
9
|
+
let commands = {};
|
|
10
|
+
Object.assign(commands, url_1.default, find_1.default, element_1.default);
|
|
11
|
+
exports.default = commands;
|
|
12
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29tbWFuZHMvaW5kZXguanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxnREFBZ0M7QUFDaEMsa0RBQWlDO0FBQ2pDLHdEQUF3QztBQUN4QyxJQUFJLFFBQVEsR0FBRyxFQUFFLENBQUM7QUFFbEIsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsYUFBVyxFQUFFLGNBQVcsRUFBRSxpQkFBZSxDQUFDLENBQUM7QUFFbkUsa0JBQWUsUUFBUSxDQUFDIn0=
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.helpers = exports.commands = void 0;
|
|
13
|
+
const taiko_1 = require("taiko");
|
|
14
|
+
let commands = {}, helpers = {}, extensions = {};
|
|
15
|
+
exports.commands = commands;
|
|
16
|
+
exports.helpers = helpers;
|
|
17
|
+
commands.setUrl = function setUrl(url) {
|
|
18
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
19
|
+
yield (0, taiko_1.goto)(url, { waitForNavigation: false });
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
commands.getUrl = function getUrl() {
|
|
23
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
24
|
+
return yield (0, taiko_1.currentURL)();
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
Object.assign(extensions, commands, helpers);
|
|
28
|
+
exports.default = extensions;
|
|
29
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXJsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbW1hbmRzL3VybC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUFBQSxpQ0FBeUM7QUFFekMsSUFBSSxRQUFRLEdBQUcsRUFBRSxFQUNmLE9BQU8sR0FBRyxFQUFFLEVBQ1osVUFBVSxHQUFHLEVBQUUsQ0FBQztBQVdULDRCQUFRO0FBQUUsMEJBQU87QUFUMUIsUUFBUSxDQUFDLE1BQU0sR0FBRyxTQUFlLE1BQU0sQ0FBQyxHQUFHOztRQUN6QyxNQUFNLElBQUEsWUFBSSxFQUFDLEdBQUcsRUFBRSxFQUFFLGlCQUFpQixFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7SUFDaEQsQ0FBQztDQUFBLENBQUM7QUFFRixRQUFRLENBQUMsTUFBTSxHQUFHLFNBQWUsTUFBTTs7UUFDckMsT0FBTyxNQUFNLElBQUEsa0JBQVUsR0FBRSxDQUFDO0lBQzVCLENBQUM7Q0FBQSxDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUUsUUFBUSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBRTdDLGtCQUFlLFVBQVUsQ0FBQyJ9
|
package/build/driver.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.AppiumCDPDriver = void 0;
|
|
16
|
+
const base_driver_1 = require("@appium/base-driver");
|
|
17
|
+
const adb_1 = require("./adb");
|
|
18
|
+
const taiko_1 = require("taiko");
|
|
19
|
+
const commands_1 = __importDefault(require("./commands"));
|
|
20
|
+
const logger_1 = __importDefault(require("./logger"));
|
|
21
|
+
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
22
|
+
const async_retry_1 = __importDefault(require("async-retry"));
|
|
23
|
+
process.env.LOCAL_PROTOCOL = true;
|
|
24
|
+
class AppiumCDPDriver extends base_driver_1.BaseDriver {
|
|
25
|
+
constructor(args) {
|
|
26
|
+
super(args);
|
|
27
|
+
this.locatorStrategies = ["xpath", "id"];
|
|
28
|
+
this.desiredCapConstraints = {
|
|
29
|
+
automationName: {
|
|
30
|
+
presence: true,
|
|
31
|
+
isString: true,
|
|
32
|
+
},
|
|
33
|
+
browserName: {
|
|
34
|
+
presence: true,
|
|
35
|
+
isString: true,
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
createSession(jwpCaps, reqCaps, w3cCaps, otherDriverData) {
|
|
40
|
+
const _super = Object.create(null, {
|
|
41
|
+
createSession: { get: () => super.createSession }
|
|
42
|
+
});
|
|
43
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
44
|
+
console.log(yield (0, taiko_1.getConfig)("local"));
|
|
45
|
+
const res = yield _super.createSession.call(this, w3cCaps);
|
|
46
|
+
const browser = w3cCaps.alwaysMatch["browserName"];
|
|
47
|
+
yield (0, adb_1.getAdb)();
|
|
48
|
+
const port = yield (0, adb_1.adbExec)(browser);
|
|
49
|
+
yield (0, adb_1.startApplication)(browser);
|
|
50
|
+
logger_1.default.info("Browser opened");
|
|
51
|
+
const data = yield (0, async_retry_1.default)((bail) => __awaiter(this, void 0, void 0, function* () {
|
|
52
|
+
const res = yield yield (0, node_fetch_1.default)(`http://localhost:${port}/json/list`);
|
|
53
|
+
const data = yield res.json();
|
|
54
|
+
if (data.length == 0) {
|
|
55
|
+
throw new Error('Debug list is empty');
|
|
56
|
+
}
|
|
57
|
+
return data;
|
|
58
|
+
}), {
|
|
59
|
+
retries: 5,
|
|
60
|
+
factor: 1,
|
|
61
|
+
});
|
|
62
|
+
const target = data.find((target) => {
|
|
63
|
+
return (target.url).includes("appium.io");
|
|
64
|
+
});
|
|
65
|
+
logger_1.default.info(`Target found: ${target.webSocketDebuggerUrl}`);
|
|
66
|
+
yield (0, taiko_1.openBrowser)({
|
|
67
|
+
port: port,
|
|
68
|
+
host: "127.0.0.1",
|
|
69
|
+
target: target.webSocketDebuggerUrl,
|
|
70
|
+
});
|
|
71
|
+
return res;
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
deleteSession() {
|
|
75
|
+
const _super = Object.create(null, {
|
|
76
|
+
deleteSession: { get: () => super.deleteSession }
|
|
77
|
+
});
|
|
78
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
79
|
+
yield _super.deleteSession.call(this);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
exports.AppiumCDPDriver = AppiumCDPDriver;
|
|
84
|
+
Object.assign(AppiumCDPDriver.prototype, commands_1.default);
|
|
85
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJpdmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2RyaXZlci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7QUFBQSxxREFBeUQ7QUFDekQsK0JBQTBEO0FBQzFELGlDQUFxRDtBQUNyRCwwREFBa0M7QUFDbEMsc0RBQTJCO0FBQzNCLDREQUErQjtBQUMvQiw4REFBZ0M7QUFDaEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDO0FBQ2xDLE1BQU0sZUFBZ0IsU0FBUSx3QkFBVTtJQUN0QyxZQUFZLElBQUk7UUFDZCxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDWixJQUFJLENBQUMsaUJBQWlCLEdBQUcsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDekMsSUFBSSxDQUFDLHFCQUFxQixHQUFHO1lBQzNCLGNBQWMsRUFBRTtnQkFDZCxRQUFRLEVBQUUsSUFBSTtnQkFDZCxRQUFRLEVBQUUsSUFBSTthQUNmO1lBQ0QsV0FBVyxFQUFFO2dCQUNYLFFBQVEsRUFBRSxJQUFJO2dCQUNkLFFBQVEsRUFBRSxJQUFJO2FBQ2Y7U0FDRixDQUFDO0lBQ0osQ0FBQztJQUVLLGFBQWEsQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxlQUFlOzs7OztZQUM1RCxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sSUFBQSxpQkFBUyxFQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7WUFDdEMsTUFBTSxHQUFHLEdBQUcsTUFBTSxPQUFNLGFBQWEsWUFBQyxPQUFPLENBQUMsQ0FBQztZQUMvQyxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQ25ELE1BQU0sSUFBQSxZQUFNLEdBQUUsQ0FBQztZQUNmLE1BQU0sSUFBSSxHQUFHLE1BQU0sSUFBQSxhQUFPLEVBQUMsT0FBTyxDQUFDLENBQUM7WUFDcEMsTUFBTSxJQUFBLHNCQUFnQixFQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ2hDLGdCQUFHLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFDM0IsTUFBTSxJQUFJLEdBQUcsTUFBTSxJQUFBLHFCQUFLLEVBQ3RCLENBQU8sSUFBSSxFQUFFLEVBQUU7Z0JBQ2IsTUFBTSxHQUFHLEdBQUcsTUFBTSxNQUFNLElBQUEsb0JBQUssRUFBQyxvQkFBb0IsSUFBSSxZQUFZLENBQUMsQ0FBQztnQkFDcEUsTUFBTSxJQUFJLEdBQUcsTUFBTSxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQzlCLElBQUksSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLEVBQUU7b0JBQ3BCLE1BQU0sSUFBSSxLQUFLLENBQUMscUJBQXFCLENBQUMsQ0FBQztpQkFDeEM7Z0JBQ0QsT0FBTyxJQUFJLENBQUM7WUFDZCxDQUFDLENBQUEsRUFDRDtnQkFDRSxPQUFPLEVBQUUsQ0FBQztnQkFDVixNQUFNLEVBQUUsQ0FBQzthQUNWLENBQ0YsQ0FBQztZQUNGLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRTtnQkFDbEMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDNUMsQ0FBQyxDQUFDLENBQUM7WUFDSCxnQkFBRyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsTUFBTSxDQUFDLG9CQUFvQixFQUFFLENBQUMsQ0FBQztZQUN6RCxNQUFNLElBQUEsbUJBQVcsRUFBQztnQkFDaEIsSUFBSSxFQUFFLElBQUk7Z0JBQ1YsSUFBSSxFQUFFLFdBQVc7Z0JBQ2pCLE1BQU0sRUFBRSxNQUFNLENBQUMsb0JBQW9CO2FBQ3BDLENBQUMsQ0FBQztZQUNILE9BQU8sR0FBRyxDQUFDO1FBQ2IsQ0FBQztLQUFBO0lBRUssYUFBYTs7Ozs7WUFDakIsTUFBTSxPQUFNLGFBQWEsV0FBRSxDQUFDO1FBQzlCLENBQUM7S0FBQTtDQUNGO0FBR1EsMENBQWU7QUFEeEIsTUFBTSxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsU0FBUyxFQUFFLGtCQUFRLENBQUMsQ0FBQyJ9
|
package/build/index.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
const CDP = require("chrome-remote-interface");
|
|
12
|
+
const { openBrowser, goto, closeBrowser } = require("taiko");
|
|
13
|
+
const fetch = require("node-fetch");
|
|
14
|
+
function example() {
|
|
15
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
16
|
+
let client;
|
|
17
|
+
try {
|
|
18
|
+
// connect to endpoint
|
|
19
|
+
// client = await CDP({
|
|
20
|
+
// host: "127.0.0.1",
|
|
21
|
+
// port: 9241,
|
|
22
|
+
// local: true,
|
|
23
|
+
// target: "ws://localhost:9241/devtools/page/1516",
|
|
24
|
+
// });
|
|
25
|
+
// await openBrowser({
|
|
26
|
+
// host: "127.0.0.1",
|
|
27
|
+
// port: 9241,
|
|
28
|
+
// target: "ws://localhost:9241/devtools/page/1515",
|
|
29
|
+
// });
|
|
30
|
+
// await goto('github.com');
|
|
31
|
+
// await closeBrowser();
|
|
32
|
+
// extract domains
|
|
33
|
+
const targets = yield fetch(`http://localhost:9241/json/list`);
|
|
34
|
+
const data = yield targets.json();
|
|
35
|
+
const target = data.find((target) => {
|
|
36
|
+
return target.url === "http://appium.io/";
|
|
37
|
+
});
|
|
38
|
+
console.log(target);
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
console.error(err);
|
|
42
|
+
}
|
|
43
|
+
finally {
|
|
44
|
+
if (client) {
|
|
45
|
+
yield client.close();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
example();
|
|
51
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXguanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7OztBQUFBLE1BQU0sR0FBRyxHQUFHLE9BQU8sQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO0FBQy9DLE1BQU0sRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUM3RCxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUM7QUFDcEMsU0FBZSxPQUFPOztRQUNwQixJQUFJLE1BQU0sQ0FBQztRQUNYLElBQUk7WUFDRixzQkFBc0I7WUFDdEIsdUJBQXVCO1lBQ3ZCLHVCQUF1QjtZQUN2QixnQkFBZ0I7WUFDaEIsaUJBQWlCO1lBQ2pCLHNEQUFzRDtZQUN0RCxNQUFNO1lBQ04sc0JBQXNCO1lBQ3RCLHVCQUF1QjtZQUN2QixnQkFBZ0I7WUFDaEIsc0RBQXNEO1lBQ3RELE1BQU07WUFDTiw0QkFBNEI7WUFDNUIsd0JBQXdCO1lBQ3hCLGtCQUFrQjtZQUVsQixNQUFNLE9BQU8sR0FBRyxNQUFNLEtBQUssQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO1lBQy9ELE1BQU0sSUFBSSxHQUFHLE1BQU0sT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ2xDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRTtnQkFDbEMsT0FBTyxNQUFNLENBQUMsR0FBRyxLQUFLLG1CQUFtQixDQUFDO1lBQzVDLENBQUMsQ0FBQyxDQUFDO1lBQ0gsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztTQUNyQjtRQUFDLE9BQU8sR0FBRyxFQUFFO1lBQ1osT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztTQUNwQjtnQkFBUztZQUNSLElBQUksTUFBTSxFQUFFO2dCQUNWLE1BQU0sTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO2FBQ3RCO1NBQ0Y7SUFDSCxDQUFDO0NBQUE7QUFFRCxPQUFPLEVBQUUsQ0FBQyJ9
|
package/build/logger.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const support_1 = require("@appium/support");
|
|
4
|
+
const log = support_1.logger.getLogger("CDPDriver");
|
|
5
|
+
exports.default = log;
|
|
6
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2xvZ2dlci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDZDQUF5QztBQUV6QyxNQUFNLEdBQUcsR0FBRyxnQkFBTSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsQ0FBQztBQUUxQyxrQkFBZSxHQUFHLENBQUMifQ==
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "appium-cdp-driver",
|
|
3
|
+
"description": "Appium driver for the filesystem",
|
|
4
|
+
"keywords": [
|
|
5
|
+
"appium",
|
|
6
|
+
"chrome-dev-tools"
|
|
7
|
+
],
|
|
8
|
+
"version": "1.0.0-beta.3",
|
|
9
|
+
"author": "",
|
|
10
|
+
"license": "Apache-2.0",
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "https://github.com/appium/appium-fs-driver.git"
|
|
14
|
+
},
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/appium/appium-fs-driver/issues"
|
|
17
|
+
},
|
|
18
|
+
"main": "./build/driver.js",
|
|
19
|
+
"bin": {},
|
|
20
|
+
"directories": {
|
|
21
|
+
"src": "src"
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
"build",
|
|
25
|
+
"src"
|
|
26
|
+
],
|
|
27
|
+
"appium": {
|
|
28
|
+
"driverName": "cdp-driver",
|
|
29
|
+
"automationName": "CDP",
|
|
30
|
+
"platformNames": [
|
|
31
|
+
"Android"
|
|
32
|
+
],
|
|
33
|
+
"mainClass": "AppiumCDPDriver"
|
|
34
|
+
},
|
|
35
|
+
"scripts": {
|
|
36
|
+
"clean": "rimraf package-lock.json && rimraf node_modules && TAIKO_SKIP_CHROMIUM_DOWNLOAD=true npm install",
|
|
37
|
+
"build": "rimraf build && tsc",
|
|
38
|
+
"watch": "tsc --watch",
|
|
39
|
+
"test": "mocha --require ts-node/register -p ./test/*.spec.js --timeout 260000 ",
|
|
40
|
+
"install-driver": "npm run build && appium driver install --source=local $(pwd)",
|
|
41
|
+
"reinstall-driver": "(appium driver uninstall cdp-driver || exit 0) && npm run install-driver"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/jest": "^27.0.1",
|
|
45
|
+
"jest": "^27.2.0",
|
|
46
|
+
"mocha": "^10.0.0",
|
|
47
|
+
"rimraf": "^3.0.2",
|
|
48
|
+
"ts-node": "^10.9.1",
|
|
49
|
+
"typescript": "^4.1.2",
|
|
50
|
+
"webdriverio": "^7.12.4"
|
|
51
|
+
},
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"@appium/base-driver": "^8.5.7",
|
|
54
|
+
"@appium/support": "^2.59.2",
|
|
55
|
+
"appium-adb": "^9.10.0",
|
|
56
|
+
"async-retry": "^1.3.3",
|
|
57
|
+
"chai": "^4.3.6",
|
|
58
|
+
"chrome-remote-interface": "^0.31.3",
|
|
59
|
+
"get-port": "^5.1.1",
|
|
60
|
+
"taiko": "https://github.com/getgauge/taiko.git"
|
|
61
|
+
}
|
|
62
|
+
}
|
package/src/adb.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { ADB, getSdkRootFromEnv } from "appium-adb";
|
|
2
|
+
import { fs } from "@appium/support";
|
|
3
|
+
import log from "./logger";
|
|
4
|
+
import getPort from "get-port";
|
|
5
|
+
|
|
6
|
+
let adb;
|
|
7
|
+
const START_APP_WAIT_DURATION = 60000;
|
|
8
|
+
|
|
9
|
+
export async function getAdb() {
|
|
10
|
+
try {
|
|
11
|
+
if (!adb) {
|
|
12
|
+
adb = await ADB.createADB();
|
|
13
|
+
}
|
|
14
|
+
} catch (e) {
|
|
15
|
+
console.log(e);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export async function requireSdkRoot() {
|
|
20
|
+
const sdkRoot = getSdkRootFromEnv();
|
|
21
|
+
const docMsg =
|
|
22
|
+
"Read https://developer.android.com/studio/command-line/variables for more details";
|
|
23
|
+
if (_.isEmpty(sdkRoot)) {
|
|
24
|
+
throw new Error(
|
|
25
|
+
`Neither ANDROID_HOME nor ANDROID_SDK_ROOT environment variable was exported. ${docMsg}`
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (!(await fs.exists(sdkRoot))) {
|
|
30
|
+
throw new Error(
|
|
31
|
+
`The Android SDK root folder '${sdkRoot}' does not exist on the local file system. ${docMsg}`
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
const stats = await fs.stat(sdkRoot);
|
|
35
|
+
if (!stats.isDirectory()) {
|
|
36
|
+
throw new Error(
|
|
37
|
+
`The Android SDK root '${sdkRoot}' must be a folder. ${docMsg}`
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
return sdkRoot;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export async function adbExec(browser = "chrome") {
|
|
44
|
+
let freePort = await getPort();
|
|
45
|
+
await adb.adbExec([
|
|
46
|
+
"forward",
|
|
47
|
+
`tcp:${freePort}`,
|
|
48
|
+
`localabstract:${browser}_devtools_remote`,
|
|
49
|
+
]);
|
|
50
|
+
return freePort;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export async function startApplication(browser = 'chrome') {
|
|
54
|
+
const common = {
|
|
55
|
+
waitDuration: START_APP_WAIT_DURATION,
|
|
56
|
+
optionalIntentArguments: "-d www.appium.io",
|
|
57
|
+
};
|
|
58
|
+
const chrome = {
|
|
59
|
+
pkg: "com.android.chrome",
|
|
60
|
+
activity: "com.google.android.apps.chrome.Main",
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const terrance = {
|
|
64
|
+
pkg: "com.sec.android.app.sbrowser",
|
|
65
|
+
activity: "com.sec.android.app.sbrowser.SBrowserMainActivity",
|
|
66
|
+
};
|
|
67
|
+
if (browser === 'chrome') {
|
|
68
|
+
await adb.startApp(Object.assign({}, chrome, common));
|
|
69
|
+
} else {
|
|
70
|
+
await adb.startApp(Object.assign({}, terrance, common));
|
|
71
|
+
}
|
|
72
|
+
}
|
package/src/cdp.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { getNetwork } from '../cdp';
|
|
2
|
+
import urlCommands from './url';
|
|
3
|
+
|
|
4
|
+
let commands = {},
|
|
5
|
+
helpers = {},
|
|
6
|
+
extensions = {};
|
|
7
|
+
|
|
8
|
+
commands.setCookie = async function setCookie(cookie){
|
|
9
|
+
const url = await urlCommands.getUrl();
|
|
10
|
+
const origin = (new URL(url)).origin;
|
|
11
|
+
|
|
12
|
+
const options = {};
|
|
13
|
+
options.name = cookie.name;
|
|
14
|
+
options.value = cookie.value;
|
|
15
|
+
options.url = origin;
|
|
16
|
+
|
|
17
|
+
const network = await getNetwork();
|
|
18
|
+
return network.setCookie(options);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
commands.getCookies = async function getCookies(){
|
|
22
|
+
const network = await getNetwork();
|
|
23
|
+
const allCookies = await network.getAllCookies();
|
|
24
|
+
return allCookies.cookies;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
commands.getCookie = async function getCookie(key){
|
|
28
|
+
const network = await getNetwork();
|
|
29
|
+
const allCookies = await network.getAllCookies();
|
|
30
|
+
return allCookies.cookies.filter((cookie) => {return cookie.name === key})[0];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
commands.deleteCookie = async function deleteCookie(key) {
|
|
34
|
+
const allCookies = await commands.getCookies();
|
|
35
|
+
const cookie = allCookies.filter( (cookie) => { return cookie.name === key })[0];
|
|
36
|
+
const network = await getNetwork();
|
|
37
|
+
return network.deleteCookies({name: key, domain: cookie.domain});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
commands.deleteCookies = async function deleteAllCookies() {
|
|
41
|
+
const network = await getNetwork();
|
|
42
|
+
return network.clearBrowserCookies();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
Object.assign(extensions, commands, helpers);
|
|
46
|
+
export { commands, helpers, elementCache };
|
|
47
|
+
export default extensions;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { evaluate } from "taiko";
|
|
2
|
+
|
|
3
|
+
let commands = {},
|
|
4
|
+
helpers = {},
|
|
5
|
+
extensions = {};
|
|
6
|
+
|
|
7
|
+
commands.getPageSource = async function pageSource() {
|
|
8
|
+
return evaluate( () => { return document.documentElement.outerHTML });
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
Object.assign(extensions, commands, helpers);
|
|
12
|
+
export { commands, helpers, elementCache };
|
|
13
|
+
export default extensions;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { click, into, write } from "taiko";
|
|
2
|
+
import { elementCache } from "./find";
|
|
3
|
+
|
|
4
|
+
let commands = {},
|
|
5
|
+
helpers = {},
|
|
6
|
+
extensions = {};
|
|
7
|
+
|
|
8
|
+
async function _click(element) {
|
|
9
|
+
await click(element);
|
|
10
|
+
}
|
|
11
|
+
commands.click = async function click(elementId) {
|
|
12
|
+
const element = elementCache[elementId];
|
|
13
|
+
await _click(element);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
commands.getText = async function getText(elementId) {
|
|
17
|
+
const element = elementCache[elementId];
|
|
18
|
+
return element.text();
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
commands.elementDisplayed = async function elementDisplayed(elementId) {
|
|
22
|
+
const element = elementCache[elementId];
|
|
23
|
+
return element.isVisible();
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
commands.elementEnabled = async function elementEnabled(elementId) {
|
|
27
|
+
const element = elementCache[elementId];
|
|
28
|
+
return !element.isDisabled();
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
commands.setValue = async function setValue(value, elementId) {
|
|
32
|
+
const element = elementCache[elementId];
|
|
33
|
+
await write(value, into(element));
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
commands.clear = async function clear(elementId) {
|
|
37
|
+
const element = elementCache[elementId];
|
|
38
|
+
await write("", into(element));
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
Object.assign(extensions, commands, helpers);
|
|
42
|
+
export { commands, helpers };
|
|
43
|
+
export default extensions;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { errors } from "@appium/base-driver";
|
|
2
|
+
import { $ } from "taiko";
|
|
3
|
+
import log from "../logger";
|
|
4
|
+
import { util } from "@appium/support";
|
|
5
|
+
import { W3C_ELEMENT_KEY } from "@appium/base-driver/build/lib/constants";
|
|
6
|
+
|
|
7
|
+
let commands = {},
|
|
8
|
+
helpers = {},
|
|
9
|
+
extensions = {},
|
|
10
|
+
elementCache = {};
|
|
11
|
+
|
|
12
|
+
function getUUID() {
|
|
13
|
+
return util.uuidV4();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
helpers.findElOrEls = async function findElOrEls(
|
|
17
|
+
strategy,
|
|
18
|
+
selector,
|
|
19
|
+
mult,
|
|
20
|
+
context
|
|
21
|
+
) {
|
|
22
|
+
log.info(`Strategy is ${strategy}`);
|
|
23
|
+
log.info(`Selector is ${selector}`);
|
|
24
|
+
log.info(`Mult is ${mult}`);
|
|
25
|
+
log.info(`Context is ${context}`);
|
|
26
|
+
const elStrategy = strategy === "xpath" ? $(selector) : $(`#${selector}`);
|
|
27
|
+
if ((await elStrategy.exists()) && !mult) {
|
|
28
|
+
const elementId = getUUID();
|
|
29
|
+
elementCache[elementId] = elStrategy;
|
|
30
|
+
return { [W3C_ELEMENT_KEY]: elementId };
|
|
31
|
+
} else if (mult) {
|
|
32
|
+
let els = [];
|
|
33
|
+
(await $(selector).elements()).forEach((element) => {
|
|
34
|
+
const elementId = getUUID();
|
|
35
|
+
elementCache[elementId] = element;
|
|
36
|
+
els.push({ ELEMENT: elementId });
|
|
37
|
+
});
|
|
38
|
+
return els;
|
|
39
|
+
} else {
|
|
40
|
+
throw new errors.NoSuchElementError(`unable to find element: ${selector}`);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
commands.findElement = async function findElement(strategy, selector) {
|
|
45
|
+
return this.findElOrEls(strategy, selector, false);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
commands.findElements = async function findElements(strategy, selector) {
|
|
49
|
+
return this.findElOrEls(strategy, selector, true);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
Object.assign(extensions, commands, helpers);
|
|
53
|
+
export { commands, helpers, elementCache };
|
|
54
|
+
export default extensions;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import urlCommands from "./url";
|
|
2
|
+
import findCommand from "./find";
|
|
3
|
+
import elementCommands from "./element";
|
|
4
|
+
import navigationCommands from "./navigation";
|
|
5
|
+
import documentCommands from "./document";
|
|
6
|
+
import cookieCommands from "./cookies";
|
|
7
|
+
|
|
8
|
+
let commands = {};
|
|
9
|
+
|
|
10
|
+
Object.assign(commands, cookieCommands, documentCommands, navigationCommands, urlCommands, findCommand, elementCommands);
|
|
11
|
+
|
|
12
|
+
export default commands;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { title, goBack, goForward } from "taiko";
|
|
2
|
+
|
|
3
|
+
let commands = {},
|
|
4
|
+
helpers = {},
|
|
5
|
+
extensions = {};
|
|
6
|
+
|
|
7
|
+
commands.title = async function pageTitle() {
|
|
8
|
+
return await title();
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
commands.back = async function back() {
|
|
12
|
+
await goBack();
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
commands.forward = async function forward() {
|
|
16
|
+
await goForward();
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
Object.assign(extensions, commands, helpers);
|
|
20
|
+
export { commands, helpers, elementCache };
|
|
21
|
+
export default extensions;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { goto, currentURL } from "taiko";
|
|
2
|
+
|
|
3
|
+
let commands = {},
|
|
4
|
+
helpers = {},
|
|
5
|
+
extensions = {};
|
|
6
|
+
|
|
7
|
+
commands.setUrl = async function setUrl(url) {
|
|
8
|
+
await goto(url, { waitForNavigation: false });
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
commands.getUrl = async function getUrl() {
|
|
12
|
+
return await currentURL();
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
Object.assign(extensions, commands, helpers);
|
|
16
|
+
export { commands, helpers };
|
|
17
|
+
export default extensions;
|
package/src/driver.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { BaseDriver, errors } from "@appium/base-driver";
|
|
2
|
+
import { getAdb, adbExec, startApplication } from "./adb";
|
|
3
|
+
import { openBrowser, getConfig, goto } from "taiko";
|
|
4
|
+
import commands from "./commands";
|
|
5
|
+
import log from "./logger";
|
|
6
|
+
import fetch from "node-fetch";
|
|
7
|
+
import retry from "async-retry";
|
|
8
|
+
process.env.LOCAL_PROTOCOL = true;
|
|
9
|
+
class AppiumCDPDriver extends BaseDriver {
|
|
10
|
+
constructor(args) {
|
|
11
|
+
super(args);
|
|
12
|
+
this.locatorStrategies = ["xpath", "id"];
|
|
13
|
+
this.desiredCapConstraints = {
|
|
14
|
+
automationName: {
|
|
15
|
+
presence: true,
|
|
16
|
+
isString: true,
|
|
17
|
+
},
|
|
18
|
+
browserName: {
|
|
19
|
+
presence: true,
|
|
20
|
+
isString: true,
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async createSession(jwpCaps, reqCaps, w3cCaps, otherDriverData) {
|
|
26
|
+
console.log(await getConfig("local"));
|
|
27
|
+
const res = await super.createSession(w3cCaps);
|
|
28
|
+
const browser = w3cCaps.alwaysMatch["browserName"];
|
|
29
|
+
await getAdb();
|
|
30
|
+
const port = await adbExec(browser);
|
|
31
|
+
await startApplication(browser);
|
|
32
|
+
log.info("Browser opened");
|
|
33
|
+
const data = await retry(
|
|
34
|
+
async (bail) => {
|
|
35
|
+
const res = await await fetch(`http://localhost:${port}/json/list`);
|
|
36
|
+
const data = await res.json();
|
|
37
|
+
if (data.length == 0) {
|
|
38
|
+
throw new Error('Debug list is empty');
|
|
39
|
+
}
|
|
40
|
+
return data;
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
retries: 5,
|
|
44
|
+
factor: 1,
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
const target = data.find((target) => {
|
|
48
|
+
return (target.url).includes("appium.io");
|
|
49
|
+
});
|
|
50
|
+
log.info(`Target found: ${target.webSocketDebuggerUrl}`);
|
|
51
|
+
await openBrowser({
|
|
52
|
+
port: port,
|
|
53
|
+
host: "127.0.0.1",
|
|
54
|
+
target: target.webSocketDebuggerUrl,
|
|
55
|
+
});
|
|
56
|
+
return res;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async deleteSession() {
|
|
60
|
+
await super.deleteSession();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
Object.assign(AppiumCDPDriver.prototype, commands);
|
|
65
|
+
export { AppiumCDPDriver };
|
package/src/index.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
const CDP = require("chrome-remote-interface");
|
|
2
|
+
const { openBrowser, goto, closeBrowser } = require("taiko");
|
|
3
|
+
const fetch = require("node-fetch");
|
|
4
|
+
async function example() {
|
|
5
|
+
let client;
|
|
6
|
+
try {
|
|
7
|
+
// connect to endpoint
|
|
8
|
+
// client = await CDP({
|
|
9
|
+
// host: "127.0.0.1",
|
|
10
|
+
// port: 9241,
|
|
11
|
+
// local: true,
|
|
12
|
+
// target: "ws://localhost:9241/devtools/page/1516",
|
|
13
|
+
// });
|
|
14
|
+
// await openBrowser({
|
|
15
|
+
// host: "127.0.0.1",
|
|
16
|
+
// port: 9241,
|
|
17
|
+
// target: "ws://localhost:9241/devtools/page/1515",
|
|
18
|
+
// });
|
|
19
|
+
// await goto('github.com');
|
|
20
|
+
// await closeBrowser();
|
|
21
|
+
// extract domains
|
|
22
|
+
|
|
23
|
+
const targets = await fetch(`http://localhost:9241/json/list`);
|
|
24
|
+
const data = await targets.json();
|
|
25
|
+
const target = data.find((target) => {
|
|
26
|
+
return target.url === "http://appium.io/";
|
|
27
|
+
});
|
|
28
|
+
console.log(target);
|
|
29
|
+
} catch (err) {
|
|
30
|
+
console.error(err);
|
|
31
|
+
} finally {
|
|
32
|
+
if (client) {
|
|
33
|
+
await client.close();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
example();
|