appium-espresso-driver 8.2.2 → 8.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/build/lib/commands/misc.d.ts +7 -7
- package/build/lib/commands/misc.d.ts.map +1 -1
- package/build/lib/commands/misc.js.map +1 -1
- package/build/lib/commands/screenshot.d.ts.map +1 -1
- package/build/lib/commands/screenshot.js +1 -2
- package/build/lib/commands/screenshot.js.map +1 -1
- package/build/lib/driver.d.ts +42 -567
- package/build/lib/driver.d.ts.map +1 -1
- package/build/lib/driver.js +54 -66
- package/build/lib/driver.js.map +1 -1
- package/build/lib/espresso-runner.d.ts +9 -9
- package/build/lib/espresso-runner.d.ts.map +1 -1
- package/build/lib/espresso-runner.js +15 -16
- package/build/lib/espresso-runner.js.map +1 -1
- package/build/lib/server-builder.d.ts +7 -1
- package/build/lib/server-builder.d.ts.map +1 -1
- package/build/lib/server-builder.js +15 -9
- package/build/lib/server-builder.js.map +1 -1
- package/build/lib/utils.d.ts +8 -0
- package/build/lib/utils.d.ts.map +1 -1
- package/build/lib/utils.js +8 -0
- package/build/lib/utils.js.map +1 -1
- package/espresso-server/app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk +0 -0
- package/espresso-server/buildSrc/.gradle/9.5.0/executionHistory/executionHistory.bin +0 -0
- package/espresso-server/buildSrc/.gradle/9.5.0/executionHistory/executionHistory.lock +0 -0
- package/espresso-server/buildSrc/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/espresso-server/buildSrc/.gradle/buildOutputCleanup/cache.properties +1 -1
- package/espresso-server/buildSrc/.gradle/buildOutputCleanup/outputFiles.bin +0 -0
- package/espresso-server/buildSrc/.gradle/file-system.probe +0 -0
- package/espresso-server/buildSrc/build/kotlin/compileKotlin/cacheable/last-build.bin +0 -0
- package/espresso-server/library/src/main/java/io/appium/espressoserver/lib/helpers/Version.kt +1 -1
- package/lib/commands/misc.ts +9 -9
- package/lib/commands/screenshot.ts +1 -2
- package/lib/driver.ts +72 -77
- package/lib/espresso-runner.ts +44 -45
- package/lib/server-builder.ts +16 -10
- package/lib/utils.ts +8 -0
- package/npm-shrinkwrap.json +2 -4
- package/package.json +1 -3
package/build/lib/utils.js
CHANGED
|
@@ -58,6 +58,14 @@ async function copyGradleProjectRecursively(sourceBaseDir, targetBaseDir) {
|
|
|
58
58
|
return false;
|
|
59
59
|
});
|
|
60
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* Insert Gradle dependency lines after a `// placeholder` marker in a Gradle file.
|
|
63
|
+
*
|
|
64
|
+
* @param originalContent - Full text of the Gradle configuration file.
|
|
65
|
+
* @param dependencyPlaceholder - Placeholder comment label to find (e.g. from build.gradle).
|
|
66
|
+
* @param dependencyLines - Dependency lines to insert (e.g. `implementation "..."`).
|
|
67
|
+
* @returns Updated file content, or the original string if the placeholder is missing.
|
|
68
|
+
*/
|
|
61
69
|
function updateDependencyLines(originalContent, dependencyPlaceholder, dependencyLines) {
|
|
62
70
|
const configurationLines = originalContent.split('\n');
|
|
63
71
|
const searchRe = new RegExp(`^\\s*//\\s*\\b${lodash_1.default.escapeRegExp(dependencyPlaceholder)}\\b`, 'm');
|
package/build/lib/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../lib/utils.ts"],"names":[],"mappings":";;;;;AAkBA,kDAaC;AAQD,oEAqBC;
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../lib/utils.ts"],"names":[],"mappings":"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"}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
#Mon May 04
|
|
1
|
+
#Mon May 04 17:13:59 UTC 2026
|
|
2
2
|
gradle.version=9.5.0
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/espresso-server/library/src/main/java/io/appium/espressoserver/lib/helpers/Version.kt
CHANGED
|
@@ -2,6 +2,6 @@ package io.appium.espressoserver.lib.helpers
|
|
|
2
2
|
|
|
3
3
|
// This value is updated automatically by the NPM versioning script
|
|
4
4
|
// It should be in sync with the NPM module version from package.json
|
|
5
|
-
private const val VERSION = "8.
|
|
5
|
+
private const val VERSION = "8.3.0"
|
|
6
6
|
|
|
7
7
|
fun getEspressoServerVersion() = VERSION
|
package/lib/commands/misc.ts
CHANGED
|
@@ -4,6 +4,14 @@ import type {StringRecord} from '@appium/types';
|
|
|
4
4
|
import type {EspressoDriver} from '../driver';
|
|
5
5
|
import type {DeviceInfo} from '../types';
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Settings parameters that are available in
|
|
9
|
+
* https://github.com/appium/appium-espresso-driver#settings-api or enabled plugins.
|
|
10
|
+
*/
|
|
11
|
+
export interface SettingsOptions {
|
|
12
|
+
[key: string]: string | number | boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
7
15
|
/**
|
|
8
16
|
* Emulates key press event.
|
|
9
17
|
*
|
|
@@ -63,7 +71,6 @@ export async function mobileIsToastVisible(
|
|
|
63
71
|
isRegexp,
|
|
64
72
|
});
|
|
65
73
|
}
|
|
66
|
-
|
|
67
74
|
/**
|
|
68
75
|
* Gets the display density (DPI) of the connected Android device.
|
|
69
76
|
* @returns Promise that resolves to the display density value
|
|
@@ -75,6 +82,7 @@ export async function getDisplayDensity(this: EspressoDriver): Promise<number> {
|
|
|
75
82
|
{},
|
|
76
83
|
)) as number;
|
|
77
84
|
}
|
|
85
|
+
|
|
78
86
|
/**
|
|
79
87
|
* API to invoke methods defined in Android app.
|
|
80
88
|
*
|
|
@@ -184,14 +192,6 @@ export async function mobileUiautomatorPageSource(this: EspressoDriver): Promise
|
|
|
184
192
|
)) as string;
|
|
185
193
|
}
|
|
186
194
|
|
|
187
|
-
/**
|
|
188
|
-
* Settings parameters that is available in
|
|
189
|
-
* https://github.com/appium/appium-espresso-driver#settings-api or enabled plugins.
|
|
190
|
-
*/
|
|
191
|
-
export interface SettingsOptions {
|
|
192
|
-
[key: string]: string | number | boolean;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
195
|
/**
|
|
196
196
|
* Apply the given settings to the espresso driver and the espresso server.
|
|
197
197
|
* Errors by the espresso server will be printed as log, but it does not return an error message.
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
|
-
import B from 'bluebird';
|
|
3
2
|
import type {EspressoDriver} from '../driver';
|
|
4
3
|
import type {ScreenshotsInfo} from './types';
|
|
5
4
|
|
|
@@ -57,7 +56,7 @@ export async function mobileScreenshots(
|
|
|
57
56
|
}
|
|
58
57
|
|
|
59
58
|
const allInfos = _.values(infos);
|
|
60
|
-
const screenshots = await
|
|
59
|
+
const screenshots = await Promise.all(allInfos.map(({id}) => toB64Screenshot(id)));
|
|
61
60
|
const result: ScreenshotsInfo = {};
|
|
62
61
|
for (const [info, payload] of _.zip(allInfos, screenshots)) {
|
|
63
62
|
if (info && payload) {
|
package/lib/driver.ts
CHANGED
|
@@ -12,7 +12,6 @@ import type {
|
|
|
12
12
|
import type {EspressoConstraints} from './constraints';
|
|
13
13
|
import _ from 'lodash';
|
|
14
14
|
import path from 'node:path';
|
|
15
|
-
import B from 'bluebird';
|
|
16
15
|
import {errors, isErrorType, DeviceSettings, BaseDriver} from 'appium/driver';
|
|
17
16
|
import {EspressoRunner, TEST_APK_PKG} from './espresso-runner';
|
|
18
17
|
import {fs, tempDir, zip} from 'appium/support';
|
|
@@ -150,25 +149,76 @@ export class EspressoDriver
|
|
|
150
149
|
extends AndroidDriver
|
|
151
150
|
implements ExternalDriver<EspressoConstraints, string, StringRecord>
|
|
152
151
|
{
|
|
152
|
+
static newMethodMap = newMethodMap;
|
|
153
|
+
static executeMethodMap = executeMethodMap as unknown as typeof AndroidDriver.executeMethodMap;
|
|
154
|
+
|
|
153
155
|
_originalIme: string | null;
|
|
154
156
|
|
|
155
157
|
espresso: EspressoRunner;
|
|
156
158
|
|
|
157
159
|
wasAnimationEnabled?: boolean;
|
|
158
160
|
|
|
159
|
-
static newMethodMap = newMethodMap;
|
|
160
|
-
static executeMethodMap = executeMethodMap;
|
|
161
|
-
|
|
162
161
|
override caps: EspressoDriverCaps;
|
|
163
162
|
|
|
164
163
|
override opts: EspressoDriverOpts;
|
|
165
164
|
|
|
166
165
|
override desiredCapConstraints: EspressoConstraints;
|
|
167
166
|
|
|
167
|
+
performActions = actionsCmds.performActions as unknown as AndroidDriver['performActions'];
|
|
168
|
+
|
|
169
|
+
startActivity = appManagementCmds.startActivity;
|
|
170
|
+
mobileStartActivity =
|
|
171
|
+
appManagementCmds.mobileStartActivity as unknown as AndroidDriver['mobileStartActivity'];
|
|
172
|
+
|
|
173
|
+
mobileWebAtoms = contextCmds.mobileWebAtoms;
|
|
174
|
+
suspendChromedriverProxy =
|
|
175
|
+
contextCmds.suspendChromedriverProxy as unknown as AndroidDriver['suspendChromedriverProxy'];
|
|
176
|
+
|
|
177
|
+
mobilePerformEditorAction =
|
|
178
|
+
elementCmds.mobilePerformEditorAction as unknown as AndroidDriver['mobilePerformEditorAction'];
|
|
179
|
+
mobileSwipe = elementCmds.mobileSwipe;
|
|
180
|
+
mobileOpenDrawer = elementCmds.mobileOpenDrawer;
|
|
181
|
+
mobileCloseDrawer = elementCmds.mobileCloseDrawer;
|
|
182
|
+
mobileSetDate = elementCmds.mobileSetDate;
|
|
183
|
+
mobileSetTime = elementCmds.mobileSetTime;
|
|
184
|
+
mobileNavigateTo = elementCmds.mobileNavigateTo;
|
|
185
|
+
mobileScrollToPage = elementCmds.mobileScrollToPage;
|
|
186
|
+
mobileFlashElement = elementCmds.mobileFlashElement;
|
|
187
|
+
mobileClickAction = elementCmds.mobileClickAction;
|
|
188
|
+
mobileDismissAutofill = elementCmds.mobileDismissAutofill;
|
|
189
|
+
|
|
190
|
+
mobilePressKey = miscCmds.mobilePressKey;
|
|
191
|
+
mobileGetDeviceInfo = miscCmds.mobileGetDeviceInfo;
|
|
192
|
+
mobileIsToastVisible = miscCmds.mobileIsToastVisible;
|
|
193
|
+
getDisplayDensity = miscCmds.getDisplayDensity as unknown as AndroidDriver['getDisplayDensity'];
|
|
194
|
+
mobileBackdoor = miscCmds.mobileBackdoor;
|
|
195
|
+
mobileUiautomator = miscCmds.mobileUiautomator;
|
|
196
|
+
mobileUiautomatorPageSource = miscCmds.mobileUiautomatorPageSource;
|
|
197
|
+
updateSettings = miscCmds.updateSettings;
|
|
198
|
+
getSettings = miscCmds.getSettings;
|
|
199
|
+
|
|
200
|
+
getClipboard = clipboardCmds.getClipboard;
|
|
201
|
+
mobileGetClipboard = clipboardCmds.getClipboard;
|
|
202
|
+
mobileSetClipboard = clipboardCmds.mobileSetClipboard;
|
|
203
|
+
|
|
204
|
+
mobileStartService =
|
|
205
|
+
servicesCmds.mobileStartService as unknown as AndroidDriver['mobileStartService'];
|
|
206
|
+
mobileStopService =
|
|
207
|
+
servicesCmds.mobileStopService as unknown as AndroidDriver['mobileStopService'];
|
|
208
|
+
|
|
209
|
+
getScreenshot = screenshotCmds.getScreenshot;
|
|
210
|
+
mobileScreenshots = screenshotCmds.mobileScreenshots;
|
|
211
|
+
|
|
212
|
+
mobileRegisterIdlingResources = idlingResourcesCmds.mobileRegisterIdlingResources;
|
|
213
|
+
mobileUnregisterIdlingResources = idlingResourcesCmds.mobileUnregisterIdlingResources;
|
|
214
|
+
mobileListIdlingResources = idlingResourcesCmds.mobileListIdlingResources;
|
|
215
|
+
mobileWaitForUIThread = idlingResourcesCmds.mobileWaitForUIThread;
|
|
216
|
+
|
|
168
217
|
constructor(opts: InitialOpts = {} as InitialOpts, shouldValidateCaps = true) {
|
|
169
218
|
// `shell` overwrites adb.shell, so remove
|
|
170
|
-
|
|
171
|
-
|
|
219
|
+
if ('shell' in opts) {
|
|
220
|
+
delete (opts as {shell?: unknown}).shell;
|
|
221
|
+
}
|
|
172
222
|
|
|
173
223
|
super(opts, shouldValidateCaps);
|
|
174
224
|
this.locatorStrategies = ['id', 'class name', 'accessibility id'];
|
|
@@ -183,6 +233,15 @@ export class EspressoDriver
|
|
|
183
233
|
this.chromedriver = undefined;
|
|
184
234
|
}
|
|
185
235
|
|
|
236
|
+
get driverData() {
|
|
237
|
+
// TODO fill out resource info here
|
|
238
|
+
return {};
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
get appOnDevice(): boolean {
|
|
242
|
+
return !this.opts.app && this.helpers.isPackageOrBundle(this.opts.appPackage!);
|
|
243
|
+
}
|
|
244
|
+
|
|
186
245
|
override async getSession(): Promise<SingularSessionData<EspressoConstraints>> {
|
|
187
246
|
return await BaseDriver.prototype.getSession.call(this);
|
|
188
247
|
}
|
|
@@ -253,8 +312,7 @@ export class EspressoDriver
|
|
|
253
312
|
// get device udid for this session
|
|
254
313
|
const {udid, emPort} = await (this as unknown as AndroidDriver).getDeviceInfoFromCaps();
|
|
255
314
|
this.opts.udid = udid;
|
|
256
|
-
|
|
257
|
-
this.opts.emPort = emPort;
|
|
315
|
+
(this.opts as EspressoDriverOpts & {emPort: typeof emPort}).emPort = emPort;
|
|
258
316
|
// now that we know our java version and device info, we can create our
|
|
259
317
|
// ADB instance
|
|
260
318
|
this.adb = await (this as unknown as AndroidDriver).createADB();
|
|
@@ -398,11 +456,6 @@ export class EspressoDriver
|
|
|
398
456
|
return shouldResultAppPathBeCached ? {appPath: pathInCache} : false;
|
|
399
457
|
}
|
|
400
458
|
|
|
401
|
-
get driverData() {
|
|
402
|
-
// TODO fill out resource info here
|
|
403
|
-
return {};
|
|
404
|
-
}
|
|
405
|
-
|
|
406
459
|
// TODO much of this logic is duplicated from uiautomator2
|
|
407
460
|
async startEspressoSession(): Promise<void> {
|
|
408
461
|
const {manifestPayload} = await getPackageInfo();
|
|
@@ -445,8 +498,7 @@ export class EspressoDriver
|
|
|
445
498
|
|
|
446
499
|
if (!this.opts.skipUnlock) {
|
|
447
500
|
// unlock the device to prepare it for testing
|
|
448
|
-
|
|
449
|
-
await this.unlock();
|
|
501
|
+
await (this as unknown as AndroidDriver).unlock();
|
|
450
502
|
} else {
|
|
451
503
|
this.log.debug(`'skipUnlock' capability set, so skipping device unlock`);
|
|
452
504
|
}
|
|
@@ -647,20 +699,19 @@ export class EspressoDriver
|
|
|
647
699
|
if (this.jwpProxyActive) {
|
|
648
700
|
await this.espresso.deleteSession();
|
|
649
701
|
}
|
|
650
|
-
|
|
651
|
-
this.espresso = null;
|
|
702
|
+
(this as {espresso: EspressoRunner | null}).espresso = null;
|
|
652
703
|
}
|
|
653
704
|
this.jwpProxyActive = false;
|
|
654
705
|
|
|
655
706
|
if (this.adb) {
|
|
656
|
-
await
|
|
657
|
-
screenRecordingStopTasks.map((task) =>
|
|
707
|
+
await Promise.all(
|
|
708
|
+
screenRecordingStopTasks.map((task) =>
|
|
658
709
|
(async () => {
|
|
659
710
|
try {
|
|
660
711
|
await task();
|
|
661
712
|
} catch {}
|
|
662
|
-
})()
|
|
663
|
-
|
|
713
|
+
})(),
|
|
714
|
+
),
|
|
664
715
|
);
|
|
665
716
|
if (this.wasAnimationEnabled) {
|
|
666
717
|
try {
|
|
@@ -732,62 +783,6 @@ export class EspressoDriver
|
|
|
732
783
|
|
|
733
784
|
return this.jwpProxyAvoid;
|
|
734
785
|
}
|
|
735
|
-
|
|
736
|
-
get appOnDevice(): boolean {
|
|
737
|
-
return !this.opts.app && this.helpers.isPackageOrBundle(this.opts.appPackage!);
|
|
738
|
-
}
|
|
739
|
-
|
|
740
|
-
// @ts-ignore It's expected
|
|
741
|
-
performActions = actionsCmds.performActions;
|
|
742
|
-
|
|
743
|
-
startActivity = appManagementCmds.startActivity;
|
|
744
|
-
// @ts-ignore It's expected
|
|
745
|
-
mobileStartActivity = appManagementCmds.mobileStartActivity;
|
|
746
|
-
|
|
747
|
-
mobileWebAtoms = contextCmds.mobileWebAtoms;
|
|
748
|
-
// @ts-ignore It's expected
|
|
749
|
-
suspendChromedriverProxy = contextCmds.suspendChromedriverProxy;
|
|
750
|
-
|
|
751
|
-
// @ts-ignore It's expected
|
|
752
|
-
mobilePerformEditorAction = elementCmds.mobilePerformEditorAction;
|
|
753
|
-
mobileSwipe = elementCmds.mobileSwipe;
|
|
754
|
-
mobileOpenDrawer = elementCmds.mobileOpenDrawer;
|
|
755
|
-
mobileCloseDrawer = elementCmds.mobileCloseDrawer;
|
|
756
|
-
mobileSetDate = elementCmds.mobileSetDate;
|
|
757
|
-
mobileSetTime = elementCmds.mobileSetTime;
|
|
758
|
-
mobileNavigateTo = elementCmds.mobileNavigateTo;
|
|
759
|
-
mobileScrollToPage = elementCmds.mobileScrollToPage;
|
|
760
|
-
mobileFlashElement = elementCmds.mobileFlashElement;
|
|
761
|
-
mobileClickAction = elementCmds.mobileClickAction;
|
|
762
|
-
mobileDismissAutofill = elementCmds.mobileDismissAutofill;
|
|
763
|
-
|
|
764
|
-
mobilePressKey = miscCmds.mobilePressKey;
|
|
765
|
-
mobileGetDeviceInfo = miscCmds.mobileGetDeviceInfo;
|
|
766
|
-
mobileIsToastVisible = miscCmds.mobileIsToastVisible;
|
|
767
|
-
// @ts-ignore It's expected
|
|
768
|
-
getDisplayDensity = miscCmds.getDisplayDensity;
|
|
769
|
-
mobileBackdoor = miscCmds.mobileBackdoor;
|
|
770
|
-
mobileUiautomator = miscCmds.mobileUiautomator;
|
|
771
|
-
mobileUiautomatorPageSource = miscCmds.mobileUiautomatorPageSource;
|
|
772
|
-
updateSettings = miscCmds.updateSettings;
|
|
773
|
-
getSettings = miscCmds.getSettings;
|
|
774
|
-
|
|
775
|
-
getClipboard = clipboardCmds.getClipboard;
|
|
776
|
-
mobileGetClipboard = clipboardCmds.getClipboard;
|
|
777
|
-
mobileSetClipboard = clipboardCmds.mobileSetClipboard;
|
|
778
|
-
|
|
779
|
-
// @ts-ignore It's expected
|
|
780
|
-
mobileStartService = servicesCmds.mobileStartService;
|
|
781
|
-
// @ts-ignore It's expected
|
|
782
|
-
mobileStopService = servicesCmds.mobileStopService;
|
|
783
|
-
|
|
784
|
-
getScreenshot = screenshotCmds.getScreenshot;
|
|
785
|
-
mobileScreenshots = screenshotCmds.mobileScreenshots;
|
|
786
|
-
|
|
787
|
-
mobileRegisterIdlingResources = idlingResourcesCmds.mobileRegisterIdlingResources;
|
|
788
|
-
mobileUnregisterIdlingResources = idlingResourcesCmds.mobileUnregisterIdlingResources;
|
|
789
|
-
mobileListIdlingResources = idlingResourcesCmds.mobileListIdlingResources;
|
|
790
|
-
mobileWaitForUIThread = idlingResourcesCmds.mobileWaitForUIThread;
|
|
791
786
|
}
|
|
792
787
|
|
|
793
788
|
export default EspressoDriver;
|
package/lib/espresso-runner.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import {JWProxy, errors} from 'appium/driver';
|
|
2
|
-
import {waitForCondition} from 'asyncbox';
|
|
2
|
+
import {sleep, waitForCondition} from 'asyncbox';
|
|
3
3
|
import {ServerBuilder, buildServerSigningConfig, type ServerSigningConfig} from './server-builder';
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import {fs, util, mkdirp, timing} from 'appium/support';
|
|
6
|
-
import B from 'bluebird';
|
|
7
6
|
import _ from 'lodash';
|
|
8
7
|
import {copyGradleProjectRecursively, getPackageInfoSync, getPackageInfo} from './utils';
|
|
9
8
|
import axios from 'axios';
|
|
@@ -48,6 +47,46 @@ export interface EspressoRunnerOptions {
|
|
|
48
47
|
keyPassword?: string;
|
|
49
48
|
}
|
|
50
49
|
|
|
50
|
+
interface InstrumentationState {
|
|
51
|
+
crashed: boolean;
|
|
52
|
+
exited: boolean;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
interface ServerStatus {
|
|
56
|
+
build: {
|
|
57
|
+
version: string;
|
|
58
|
+
packageName?: string;
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
interface SessionInfo {
|
|
63
|
+
id: string;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
interface SessionsResponse {
|
|
67
|
+
value: SessionInfo[];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
class EspressoProxy extends JWProxy {
|
|
71
|
+
instrumentationState: InstrumentationState;
|
|
72
|
+
|
|
73
|
+
override async proxyCommand(
|
|
74
|
+
url: string,
|
|
75
|
+
method: HTTPMethod,
|
|
76
|
+
body: HTTPBody = null,
|
|
77
|
+
): Promise<[ProxyResponse, HTTPBody]> {
|
|
78
|
+
const {crashed, exited} = this.instrumentationState;
|
|
79
|
+
if (exited) {
|
|
80
|
+
throw new errors.InvalidContextError(
|
|
81
|
+
`'${method} ${url}' cannot be proxied to Espresso server because ` +
|
|
82
|
+
`the instrumentation process has ${crashed ? 'crashed' : 'been unexpectedly terminated'}. ` +
|
|
83
|
+
`Check the Appium server log and the logcat output for more details`,
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
return await super.proxyCommand(url, method, body);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
51
90
|
export class EspressoRunner {
|
|
52
91
|
public readonly host: string;
|
|
53
92
|
public readonly systemPort: number;
|
|
@@ -66,8 +105,8 @@ export class EspressoRunner {
|
|
|
66
105
|
public readonly androidInstallTimeout?: number;
|
|
67
106
|
public readonly disableSuppressAccessibilityService?: boolean;
|
|
68
107
|
public readonly signingConfig: ServerSigningConfig | null;
|
|
69
|
-
private readonly log: AppiumLogger;
|
|
70
108
|
public instProcess: SubProcess | null = null;
|
|
109
|
+
private readonly log: AppiumLogger;
|
|
71
110
|
|
|
72
111
|
constructor(log: AppiumLogger, opts: EspressoRunnerOptions) {
|
|
73
112
|
this.adb = requireOption(opts, 'adb');
|
|
@@ -413,7 +452,7 @@ export class EspressoRunner {
|
|
|
413
452
|
`The following obsolete sessions are still running: ${JSON.stringify(activeSessionIds)}`,
|
|
414
453
|
);
|
|
415
454
|
this.log.debug('Cleaning up the obsolete sessions');
|
|
416
|
-
await
|
|
455
|
+
await Promise.all(
|
|
417
456
|
activeSessionIds.map((id) =>
|
|
418
457
|
axios({
|
|
419
458
|
url: `http://${this.host}:${this.systemPort}/session/${id}`,
|
|
@@ -422,7 +461,7 @@ export class EspressoRunner {
|
|
|
422
461
|
),
|
|
423
462
|
);
|
|
424
463
|
// Let all sessions to be properly terminated before continuing
|
|
425
|
-
await
|
|
464
|
+
await sleep(1000);
|
|
426
465
|
} else {
|
|
427
466
|
this.log.debug('No obsolete sessions have been detected');
|
|
428
467
|
}
|
|
@@ -488,49 +527,9 @@ export class EspressoRunner {
|
|
|
488
527
|
}
|
|
489
528
|
}
|
|
490
529
|
|
|
491
|
-
class EspressoProxy extends JWProxy {
|
|
492
|
-
instrumentationState: InstrumentationState;
|
|
493
|
-
|
|
494
|
-
override async proxyCommand(
|
|
495
|
-
url: string,
|
|
496
|
-
method: HTTPMethod,
|
|
497
|
-
body: HTTPBody = null,
|
|
498
|
-
): Promise<[ProxyResponse, HTTPBody]> {
|
|
499
|
-
const {crashed, exited} = this.instrumentationState;
|
|
500
|
-
if (exited) {
|
|
501
|
-
throw new errors.InvalidContextError(
|
|
502
|
-
`'${method} ${url}' cannot be proxied to Espresso server because ` +
|
|
503
|
-
`the instrumentation process has ${crashed ? 'crashed' : 'been unexpectedly terminated'}. ` +
|
|
504
|
-
`Check the Appium server log and the logcat output for more details`,
|
|
505
|
-
);
|
|
506
|
-
}
|
|
507
|
-
return await super.proxyCommand(url, method, body);
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
|
|
511
530
|
function requireOption(opts: EspressoRunnerOptions, key: string): any {
|
|
512
531
|
if (!util.hasValue(opts[key])) {
|
|
513
532
|
throw new Error(`Option '${key}' is required!`);
|
|
514
533
|
}
|
|
515
534
|
return opts[key];
|
|
516
535
|
}
|
|
517
|
-
|
|
518
|
-
interface InstrumentationState {
|
|
519
|
-
crashed: boolean;
|
|
520
|
-
exited: boolean;
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
interface ServerStatus {
|
|
524
|
-
build: {
|
|
525
|
-
version: string;
|
|
526
|
-
packageName?: string;
|
|
527
|
-
};
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
interface SessionInfo {
|
|
531
|
-
id: string;
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
interface SessionsResponse {
|
|
535
|
-
value: SessionInfo[];
|
|
536
|
-
}
|
package/lib/server-builder.ts
CHANGED
|
@@ -46,16 +46,6 @@ export interface BuildServerSigningConfigArgs {
|
|
|
46
46
|
keyPassword: string;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
export function buildServerSigningConfig(args: BuildServerSigningConfigArgs): ServerSigningConfig {
|
|
50
|
-
return {
|
|
51
|
-
zipAlign: true,
|
|
52
|
-
keystoreFile: args.keystoreFile,
|
|
53
|
-
keystorePassword: args.keystorePassword,
|
|
54
|
-
keyAlias: args.keyAlias,
|
|
55
|
-
keyPassword: args.keyPassword,
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
|
|
59
49
|
export interface EspressoBuildConfiguration {
|
|
60
50
|
toolsVersions?: Record<string, string>;
|
|
61
51
|
/**
|
|
@@ -268,3 +258,19 @@ export class ServerBuilder {
|
|
|
268
258
|
}
|
|
269
259
|
}
|
|
270
260
|
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Build keystore options for signing the built Espresso server test APK.
|
|
264
|
+
*
|
|
265
|
+
* @param args - Paths and credentials for the keystore used when signing.
|
|
266
|
+
* @returns Configuration consumed by the Gradle signing step.
|
|
267
|
+
*/
|
|
268
|
+
export function buildServerSigningConfig(args: BuildServerSigningConfigArgs): ServerSigningConfig {
|
|
269
|
+
return {
|
|
270
|
+
zipAlign: true,
|
|
271
|
+
keystoreFile: args.keystoreFile,
|
|
272
|
+
keystorePassword: args.keystorePassword,
|
|
273
|
+
keyAlias: args.keyAlias,
|
|
274
|
+
keyPassword: args.keyPassword,
|
|
275
|
+
};
|
|
276
|
+
}
|
package/lib/utils.ts
CHANGED
|
@@ -60,6 +60,14 @@ export async function copyGradleProjectRecursively(
|
|
|
60
60
|
});
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
+
/**
|
|
64
|
+
* Insert Gradle dependency lines after a `// placeholder` marker in a Gradle file.
|
|
65
|
+
*
|
|
66
|
+
* @param originalContent - Full text of the Gradle configuration file.
|
|
67
|
+
* @param dependencyPlaceholder - Placeholder comment label to find (e.g. from build.gradle).
|
|
68
|
+
* @param dependencyLines - Dependency lines to insert (e.g. `implementation "..."`).
|
|
69
|
+
* @returns Updated file content, or the original string if the placeholder is missing.
|
|
70
|
+
*/
|
|
63
71
|
export function updateDependencyLines(
|
|
64
72
|
originalContent: string,
|
|
65
73
|
dependencyPlaceholder: string,
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "appium-espresso-driver",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.3.0",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "appium-espresso-driver",
|
|
9
|
-
"version": "8.
|
|
9
|
+
"version": "8.3.0",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"appium-adb": "^14.0.0",
|
|
13
13
|
"appium-android-driver": "^13.1.0",
|
|
14
14
|
"asyncbox": "^6.1.0",
|
|
15
15
|
"axios": "^1.12.2",
|
|
16
|
-
"bluebird": "^3.5.0",
|
|
17
16
|
"commander": "^14.0.1",
|
|
18
17
|
"io.appium.settings": "^7.0.1",
|
|
19
18
|
"lodash": "^4.17.11",
|
|
@@ -27,7 +26,6 @@
|
|
|
27
26
|
"@appium/types": "^1.0.0-rc.1",
|
|
28
27
|
"@semantic-release/changelog": "^6.0.1",
|
|
29
28
|
"@semantic-release/git": "^10.0.1",
|
|
30
|
-
"@types/bluebird": "^3.5.38",
|
|
31
29
|
"@types/chai": "^5.2.3",
|
|
32
30
|
"@types/chai-as-promised": "^8.0.2",
|
|
33
31
|
"@types/lodash": "^4.14.196",
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"automated testing",
|
|
8
8
|
"android"
|
|
9
9
|
],
|
|
10
|
-
"version": "8.
|
|
10
|
+
"version": "8.3.0",
|
|
11
11
|
"author": "Appium Contributors",
|
|
12
12
|
"license": "Apache-2.0",
|
|
13
13
|
"repository": {
|
|
@@ -78,7 +78,6 @@
|
|
|
78
78
|
"appium-android-driver": "^13.1.0",
|
|
79
79
|
"asyncbox": "^6.1.0",
|
|
80
80
|
"axios": "^1.12.2",
|
|
81
|
-
"bluebird": "^3.5.0",
|
|
82
81
|
"commander": "^14.0.1",
|
|
83
82
|
"io.appium.settings": "^7.0.1",
|
|
84
83
|
"lodash": "^4.17.11",
|
|
@@ -119,7 +118,6 @@
|
|
|
119
118
|
"@appium/types": "^1.0.0-rc.1",
|
|
120
119
|
"@semantic-release/changelog": "^6.0.1",
|
|
121
120
|
"@semantic-release/git": "^10.0.1",
|
|
122
|
-
"@types/bluebird": "^3.5.38",
|
|
123
121
|
"@types/chai": "^5.2.3",
|
|
124
122
|
"@types/chai-as-promised": "^8.0.2",
|
|
125
123
|
"@types/lodash": "^4.14.196",
|