appium-espresso-driver 1.46.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 +23 -0
- package/LICENSE +201 -0
- package/README.md +864 -0
- package/build/index.js +48 -0
- package/build/lib/commands/execute.js +67 -0
- package/build/lib/commands/general.js +337 -0
- package/build/lib/commands/idling-resources.js +31 -0
- package/build/lib/commands/index.js +26 -0
- package/build/lib/commands/services.js +27 -0
- package/build/lib/desired-caps.js +65 -0
- package/build/lib/driver.js +475 -0
- package/build/lib/espresso-runner.js +381 -0
- package/build/lib/logger.js +18 -0
- package/build/lib/server-builder.js +213 -0
- package/build/lib/server.js +39 -0
- package/build/lib/utils.js +85 -0
- package/espresso-server/app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk +0 -0
- package/espresso-server/app/build/outputs/apk/androidTest/debug/output-metadata.json +18 -0
- package/espresso-server/app/build.gradle.kts +153 -0
- package/espresso-server/app/proguard-rules.pro +25 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/EspressoServerRunnerTest.kt +93 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/drivers/AppDriver.kt +29 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/drivers/ComposeDriver.kt +73 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/drivers/DriverContext.kt +35 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/drivers/EspressoDriver.kt +70 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/AcceptAlert.kt +32 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/Back.kt +31 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/Clear.kt +40 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/Click.kt +27 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/CreateSession.kt +58 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/DeleteSession.kt +33 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/DismissAlert.kt +32 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/DrawerActionHandler.kt +45 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/ElementEquals.kt +19 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/ElementScreenshot.kt +31 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/ElementValue.kt +85 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/FindActive.kt +32 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/FindElement.kt +29 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/FindElements.kt +43 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetAlertText.kt +31 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetAttribute.kt +101 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetClipboard.kt +65 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetDeviceInfo.kt +44 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetDisplayed.kt +28 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetEnabled.kt +30 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetLocation.kt +32 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetLocationInView.kt +33 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetName.kt +31 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetOrientation.kt +44 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetRect.kt +38 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetRotation.kt +33 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetSelected.kt +30 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetSession.kt +34 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetSessions.kt +41 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetSettings.kt +25 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetSize.kt +32 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetToastVisibility.kt +34 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetWindowRect.kt +43 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetWindowSize.kt +42 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/HideKeyboard.kt +29 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/Keys.kt +82 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/ListIdlingResources.kt +30 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/MobileBackdoor.kt +42 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/MobileClickAction.kt +49 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/MobileSwipe.kt +71 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/MobileViewFlash.kt +50 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/MoveTo.kt +50 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/MultiTouchAction.kt +50 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/NavigateTo.kt +42 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/NoSessionCommandHandler.kt +4 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/NotYetImplemented.kt +28 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/OpenNotifications.kt +28 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/PerformAction.kt +42 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/PerformAutofillDismissal.kt +31 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/PerformEditorAction.kt +30 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/PointerEventHandler.kt +281 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/PressKeyCode.kt +90 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/RegisterIdlingResources.kt +33 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/ReleaseActions.kt +41 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/RequestHandler.kt +43 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/ScreenshotHandler.kt +29 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/ScrollToPage.kt +60 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/SetClipboard.kt +64 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/SetDate.kt +41 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/SetOrientation.kt +61 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/SetRotation.kt +46 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/SetTime.kt +41 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/Source.kt +29 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/StartActivity.kt +30 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/StartService.kt +40 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/Status.kt +26 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/StopService.kt +37 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/Text.kt +28 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/TouchAction.kt +49 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/Uiautomator.kt +68 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/UiautomatorPageSource.kt +35 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/UnregisterIdlingResources.kt +33 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/UpdateSettings.kt +35 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/WebAtoms.kt +69 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/exceptions/AppiumException.kt +40 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/exceptions/DuplicateRouteException.kt +22 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/exceptions/ElementNotVisibleException.kt +30 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/exceptions/InvalidArgumentException.kt +35 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/exceptions/InvalidElementStateException.kt +41 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/exceptions/InvalidSelectorException.kt +35 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/exceptions/MoveTargetOutOfBoundsException.kt +39 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/exceptions/NoAlertOpenException.kt +33 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/exceptions/NoSuchDriverException.kt +31 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/exceptions/NoSuchElementException.kt +34 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/exceptions/NotYetImplementedException.kt +33 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/exceptions/ScreenCaptureException.kt +30 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/exceptions/SessionNotCreatedException.kt +34 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/exceptions/StaleElementException.kt +30 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/exceptions/XPathLookupException.kt +31 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/AccessibilityServiceState.kt +15 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/ActivityHelpers.kt +125 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/ActivityOptionsHelpers.kt +60 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/AlertHelpers.kt +170 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/AndroidLogger.kt +45 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/AssertHelpers.kt +17 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/AutofillHelpers.kt +44 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/BackdoorUtils.java +49 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/ClipboardHelper.kt +51 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/ComposeNodeFinder.kt +59 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/DeviceInfoHelper.kt +148 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/EspressoViewsCache.kt +57 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/GsonParserHelpers.kt +72 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/IMEHelpers.kt +88 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/IntentHelpers.kt +336 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/InteractionHelper.kt +40 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/InvocationOperation.java +80 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/LocaleHelpers.kt +46 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/Logger.kt +25 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/NotificationListener.kt +87 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/Rect.kt +22 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/ReflectionUtils.kt +64 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/ScreenshotsHelper.kt +59 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/StringHelpers.kt +42 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/ThreadHelpers.kt +15 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/UiAutomationWrapper.kt +48 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/ViewFinder.kt +316 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/XMLHelpers.kt +56 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/extensions/Semaphore.kt +22 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/reflection/ArrayUtils.java +110 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/reflection/ClassUtils.java +180 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/reflection/MethodUtils.java +155 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/reflection/Validate.java +34 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/adapter/BaseW3CActionAdapter.kt +71 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/adapter/DummyW3CActionAdapter.kt +133 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/adapter/W3CActionAdapter.kt +71 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/adapter/espresso/AndroidKeyEvent.kt +271 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/adapter/espresso/AndroidMotionEvent.kt +90 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/adapter/espresso/EspressoW3CActionAdapter.kt +147 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/adapter/espresso/Helpers.kt +71 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/adapter/espresso/MotionEventBuilder.kt +153 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/adapter/espresso/MultiTouchState.kt +132 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/adapter/espresso/TouchState.kt +7 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/caps/CapsUtils.kt +96 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/dispatcher/BaseDispatchResult.kt +14 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/dispatcher/DispatchPointerMoveResult.kt +22 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/dispatcher/KeyDispatch.kt +151 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/dispatcher/PointerDispatch.kt +286 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/dispatcher/W3CKeyEvent.kt +21 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/dispatcher/constants/KeyCodeMapper.kt +169 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/dispatcher/constants/KeyLocationMapper.kt +50 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/dispatcher/constants/KeyNormalizer.kt +84 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/dispatcher/constants/NormalizedKeys.kt +60 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/models/ActionObject.kt +138 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/models/ActionSequence.kt +112 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/models/Actions.kt +89 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/models/InputSource.kt +173 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/models/Origin.kt +24 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/models/OriginDeserializer.kt +25 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/models/Tick.kt +62 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/processor/ActionsProcessor.kt +93 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/processor/KeyProcessor.kt +57 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/processor/PauseProcessor.kt +59 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/processor/PointerProcessor.kt +115 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/processor/ProcessorHelpers.kt +35 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/state/ActiveInputSources.kt +62 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/state/InputState.kt +6 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/state/InputStateTable.kt +95 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/state/KeyInputState.kt +82 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/state/PointerInputState.kt +45 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/http/RouteDefinition.kt +67 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/http/RouteMap.kt +51 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/http/Router.kt +250 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/http/Server.kt +109 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/http/response/AppiumResponse.kt +61 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/http/response/BaseResponse.kt +25 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/AlertParams.kt +21 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/AppiumParams.kt +55 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/BackdoorMethodArg.kt +3 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/ClipboardDataType.kt +18 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/DrawerActionParams.kt +21 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/EditorActionParams.kt +21 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/Element.kt +169 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/GetClipboardParams.kt +27 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/GlobalSession.kt +64 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/HamcrestMatcher.kt +144 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/IdlingResourcesParams.kt +66 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/KeyEventParams.kt +23 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/LocaleParams.kt +34 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/Location.kt +19 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/Locator.kt +22 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/MatcherJson.kt +37 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/MobileBackdoorMethod.kt +22 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/MobileBackdoorParams.kt +20 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/MobileClickActionParams.kt +81 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/MobileSwipeParams.kt +106 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/MotionEventParams.kt +37 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/MoveToParams.kt +26 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/MultiTouchActionsParams.kt +5 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/NavigateToParams.kt +21 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/OrientationParams.kt +21 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/OrientationType.kt +6 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/Rect.kt +24 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/RotationParams.kt +38 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/ScrollToPageParams.kt +36 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/SessionParams.kt +23 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/SetClipboardParams.kt +29 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/SetDateParams.kt +23 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/SetTimeParams.kt +22 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/SettingsParams.kt +19 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/Size.kt +22 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/SourceDocument.kt +286 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/StartActivityParams.kt +9 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/StartServiceParams.kt +22 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/StopServiceParams.kt +21 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/Strategy.kt +49 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/TextValueParams.kt +6 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/ToastLookupParams.kt +22 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/TouchAction.kt +178 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/TouchActionsParams.kt +5 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/UiautomatorParams.kt +123 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/ViewAttributesEnum.kt +51 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/ViewElement.kt +204 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/ViewFlashParams.kt +9 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/ViewText.kt +12 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/WindowRect.kt +24 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/WindowSize.kt +22 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/settings/AbstractSetting.kt +23 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/settings/DriverSetting.kt +40 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/settings/SettingType.kt +21 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/web/WebAtom.kt +26 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/web/WebAtomDeserializer.kt +99 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/web/WebAtomsMethods.kt +4 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/web/WebAtomsParams.kt +9 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/viewaction/OrientationChange.kt +47 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/viewaction/ScrollTo.kt +48 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/viewaction/UiControllerPerformer.kt +67 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/viewaction/UiControllerRunnable.kt +25 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/viewaction/ViewGetter.kt +79 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/viewaction/ViewTextGetter.kt +31 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/viewmatcher/RegexpTextMatcher.kt +38 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/viewmatcher/WithView.kt +33 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/viewmatcher/WithXPath.kt +55 -0
- package/espresso-server/app/src/main/AndroidManifest.xml +7 -0
- package/espresso-server/app/src/test/java/io/appium/espressoserver/test/assets/Helpers.kt +20 -0
- package/espresso-server/app/src/test/java/io/appium/espressoserver/test/assets/backdoor-methods.json +51 -0
- package/espresso-server/app/src/test/java/io/appium/espressoserver/test/assets/key-actions.json +15 -0
- package/espresso-server/app/src/test/java/io/appium/espressoserver/test/assets/multi-touch-actions.json +28 -0
- package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/GsonParserHelpersTest.kt +41 -0
- package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/IntentCreationTests.kt +115 -0
- package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/InvocationOperationTest.java +97 -0
- package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/KReflectionUtilsTest.kt +108 -0
- package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/XpathQueryParserTests.kt +42 -0
- package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/w3c/ActionSequenceTest.kt +220 -0
- package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/w3c/ActionsTest.kt +76 -0
- package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/w3c/CapsUtilsTest.kt +76 -0
- package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/w3c/Helpers.kt +7 -0
- package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/w3c/InputSourceTest.kt +153 -0
- package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/w3c/InputStateTableTest.kt +72 -0
- package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/w3c/KeyDispatchTest.kt +133 -0
- package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/w3c/KeyInputStateTest.kt +74 -0
- package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/w3c/PointerDispatchTest.kt +370 -0
- package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/w3c/ProcessorTest.kt +320 -0
- package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/w3c/TickTest.kt +265 -0
- package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/w3c/adapter/AndroidKeyEventTest.kt +114 -0
- package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/w3c/adapter/HelpersTest.kt +31 -0
- package/espresso-server/app/src/test/java/io/appium/espressoserver/test/http/RouteDefinitionTest.kt +74 -0
- package/espresso-server/app/src/test/java/io/appium/espressoserver/test/model/HamcrestMatcherTest.kt +112 -0
- package/espresso-server/app/src/test/java/io/appium/espressoserver/test/model/MatcherJsonTest.kt +20 -0
- package/espresso-server/app/src/test/java/io/appium/espressoserver/test/model/MobileBackdoorMethodTest.java +110 -0
- package/espresso-server/app/src/test/java/io/appium/espressoserver/test/model/MobileClickTest.kt +46 -0
- package/espresso-server/app/src/test/java/io/appium/espressoserver/test/model/MobileSwipeTest.kt +68 -0
- package/espresso-server/app/src/test/java/io/appium/espressoserver/test/model/TouchActionTest.kt +56 -0
- package/espresso-server/app/src/test/java/io/appium/espressoserver/test/model/web/WebAtomTest.kt +68 -0
- package/espresso-server/app/src/test/java/io/appium/espressoserver/test/model/web/WebAtomsTest.kt +96 -0
- package/espresso-server/build.gradle.kts +33 -0
- package/espresso-server/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/espresso-server/gradle/wrapper/gradle-wrapper.properties +5 -0
- package/espresso-server/gradle.properties +26 -0
- package/espresso-server/gradlew +185 -0
- package/espresso-server/gradlew.bat +89 -0
- package/espresso-server/lint.xml +4 -0
- package/espresso-server/settings.gradle.kts +1 -0
- package/index.js +29 -0
- package/lib/commands/execute.js +72 -0
- package/lib/commands/general.js +321 -0
- package/lib/commands/idling-resources.js +52 -0
- package/lib/commands/index.js +16 -0
- package/lib/commands/services.js +50 -0
- package/lib/desired-caps.js +55 -0
- package/lib/driver.js +566 -0
- package/lib/espresso-runner.js +340 -0
- package/lib/logger.js +6 -0
- package/lib/server-builder.js +194 -0
- package/lib/server.js +18 -0
- package/lib/utils.js +74 -0
- package/package.json +105 -0
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
import { JWProxy, errors } from 'appium-base-driver';
|
|
2
|
+
import { waitForCondition } from 'asyncbox';
|
|
3
|
+
import logger from './logger';
|
|
4
|
+
import { ServerBuilder, buildServerSigningConfig } from './server-builder';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import { fs, util, mkdirp, timing } from 'appium-support';
|
|
7
|
+
import { version } from '../../package.json'; // eslint-disable-line import/no-unresolved
|
|
8
|
+
import B from 'bluebird';
|
|
9
|
+
import _ from 'lodash';
|
|
10
|
+
import { copyGradleProjectRecursively } from './utils';
|
|
11
|
+
import axios from 'axios';
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
const TEST_SERVER_ROOT = path.resolve(__dirname, '..', '..', 'espresso-server');
|
|
15
|
+
const TEST_APK_PKG = 'io.appium.espressoserver.test';
|
|
16
|
+
const REQUIRED_PARAMS = [
|
|
17
|
+
'adb',
|
|
18
|
+
'tmpDir',
|
|
19
|
+
'host',
|
|
20
|
+
'systemPort',
|
|
21
|
+
'devicePort',
|
|
22
|
+
'appPackage',
|
|
23
|
+
'forceEspressoRebuild',
|
|
24
|
+
];
|
|
25
|
+
const ESPRESSO_SERVER_LAUNCH_TIMEOUT_MS = 45000;
|
|
26
|
+
const TARGET_PACKAGE_CONTAINER = '/data/local/tmp/espresso.apppackage';
|
|
27
|
+
|
|
28
|
+
class EspressoProxy extends JWProxy {
|
|
29
|
+
async proxyCommand (url, method, body = null) {
|
|
30
|
+
const {crashed, exited} = this.instrumentationState;
|
|
31
|
+
if (exited) {
|
|
32
|
+
throw new errors.InvalidContextError(`'${method} ${url}' cannot be proxied to Espresso server because ` +
|
|
33
|
+
`the instrumentation process has ${crashed ? 'crashed' : 'been unexpectedly terminated'}. ` +
|
|
34
|
+
`Check the Appium server log and the logcat output for more details`);
|
|
35
|
+
}
|
|
36
|
+
return await super.proxyCommand(url, method, body);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
class EspressoRunner {
|
|
41
|
+
constructor (opts = {}) {
|
|
42
|
+
for (let req of REQUIRED_PARAMS) {
|
|
43
|
+
if (!opts || !util.hasValue(opts[req])) {
|
|
44
|
+
throw new Error(`Option '${req}' is required!`);
|
|
45
|
+
}
|
|
46
|
+
this[req] = opts[req];
|
|
47
|
+
}
|
|
48
|
+
this.jwproxy = new EspressoProxy({
|
|
49
|
+
server: this.host,
|
|
50
|
+
port: this.systemPort,
|
|
51
|
+
base: '',
|
|
52
|
+
keepAlive: true,
|
|
53
|
+
});
|
|
54
|
+
this.proxyReqRes = this.jwproxy.proxyReqRes.bind(this.jwproxy);
|
|
55
|
+
this.jwproxy.instrumentationState = {
|
|
56
|
+
exited: false,
|
|
57
|
+
crashed: false,
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const modServerName = fs.sanitizeName(`${TEST_APK_PKG}_${version}_${this.appPackage}_${this.adb.curDeviceId}.apk`, {
|
|
61
|
+
replacement: '-',
|
|
62
|
+
});
|
|
63
|
+
this.modServerPath = path.resolve(this.tmpDir, modServerName);
|
|
64
|
+
this.showGradleLog = opts.showGradleLog;
|
|
65
|
+
this.espressoBuildConfig = opts.espressoBuildConfig;
|
|
66
|
+
|
|
67
|
+
this.serverLaunchTimeout = opts.serverLaunchTimeout || ESPRESSO_SERVER_LAUNCH_TIMEOUT_MS;
|
|
68
|
+
this.androidInstallTimeout = opts.androidInstallTimeout;
|
|
69
|
+
|
|
70
|
+
this.disableSuppressAccessibilityService = opts.disableSuppressAccessibilityService;
|
|
71
|
+
|
|
72
|
+
// Espresso Server app needs to be signed with same keyStore as appPackage
|
|
73
|
+
if (opts.useKeystore && opts.keystorePath && opts.keystorePassword && opts.keyAlias && opts.keyPassword) {
|
|
74
|
+
this.signingConfig = buildServerSigningConfig({
|
|
75
|
+
keystoreFile: opts.keystorePath,
|
|
76
|
+
keystorePassword: opts.keystorePassword,
|
|
77
|
+
keyAlias: opts.keyAlias,
|
|
78
|
+
keyPassword: opts.keyPassword
|
|
79
|
+
});
|
|
80
|
+
} else {
|
|
81
|
+
this.signingConfig = null;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async isAppPackageChanged () {
|
|
86
|
+
if (!await this.adb.fileExists(TARGET_PACKAGE_CONTAINER)) {
|
|
87
|
+
logger.debug('The previous target application package is unknown');
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
const previousAppPackage = (await this.adb.shell(['cat', TARGET_PACKAGE_CONTAINER])).trim();
|
|
91
|
+
logger.debug(`The previous target application package was '${previousAppPackage}'. ` +
|
|
92
|
+
`The current package is '${this.appPackage}'`);
|
|
93
|
+
return previousAppPackage !== this.appPackage;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Installs Espresso server apk on to the device or emulator.
|
|
98
|
+
* Each adb command uses default timeout by them.
|
|
99
|
+
*/
|
|
100
|
+
async installServer () {
|
|
101
|
+
const appState = await this.adb.getApplicationInstallState(this.modServerPath, TEST_APK_PKG);
|
|
102
|
+
|
|
103
|
+
const shouldUninstallApp = [
|
|
104
|
+
this.adb.APP_INSTALL_STATE.OLDER_VERSION_INSTALLED,
|
|
105
|
+
this.adb.APP_INSTALL_STATE.NEWER_VERSION_INSTALLED
|
|
106
|
+
].includes(appState);
|
|
107
|
+
const shouldInstallApp = shouldUninstallApp || [
|
|
108
|
+
this.adb.APP_INSTALL_STATE.NOT_INSTALLED
|
|
109
|
+
].includes(appState);
|
|
110
|
+
|
|
111
|
+
if (shouldUninstallApp) {
|
|
112
|
+
logger.info(`Uninstalling Espresso Test Server apk from the target device (pkg: '${TEST_APK_PKG}')`);
|
|
113
|
+
try {
|
|
114
|
+
await this.adb.uninstallApk(TEST_APK_PKG);
|
|
115
|
+
} catch (err) {
|
|
116
|
+
logger.warn(`Error uninstalling '${TEST_APK_PKG}': ${err.message}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (shouldInstallApp) {
|
|
121
|
+
logger.info(`Installing Espresso Test Server apk from the target device (path: '${this.modServerPath}')`);
|
|
122
|
+
try {
|
|
123
|
+
await this.adb.install(this.modServerPath, { replace: false, timeout: this.androidInstallTimeout });
|
|
124
|
+
logger.info(`Installed Espresso Test Server apk '${this.modServerPath}' (pkg: '${TEST_APK_PKG}')`);
|
|
125
|
+
} catch (err) {
|
|
126
|
+
logger.errorAndThrow(`Cannot install '${this.modServerPath}' because of '${err.message}'`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
async installTestApk () {
|
|
132
|
+
let rebuild = this.forceEspressoRebuild;
|
|
133
|
+
if (rebuild) {
|
|
134
|
+
logger.debug(`'forceEspressoRebuild' capability is enabled`);
|
|
135
|
+
} else if (await this.isAppPackageChanged()) {
|
|
136
|
+
logger.info(`Forcing Espresso server rebuild because of changed application package`);
|
|
137
|
+
rebuild = true;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (rebuild && await fs.exists(this.modServerPath)) {
|
|
141
|
+
logger.debug(`Deleting the obsolete Espresso server package '${this.modServerPath}'`);
|
|
142
|
+
await fs.unlink(this.modServerPath);
|
|
143
|
+
}
|
|
144
|
+
if (!(await fs.exists(this.modServerPath))) {
|
|
145
|
+
await this.buildNewModServer();
|
|
146
|
+
}
|
|
147
|
+
const isSigned = await this.adb.checkApkCert(this.modServerPath, TEST_APK_PKG);
|
|
148
|
+
if (!isSigned) {
|
|
149
|
+
await this.adb.sign(this.modServerPath);
|
|
150
|
+
}
|
|
151
|
+
if ((rebuild || !isSigned) && await this.adb.uninstallApk(TEST_APK_PKG)) {
|
|
152
|
+
logger.info('Uninstalled the obsolete Espresso server package from the device under test');
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
await this.installServer();
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
async buildNewModServer () {
|
|
159
|
+
let buildConfiguration = {};
|
|
160
|
+
if (this.espressoBuildConfig) {
|
|
161
|
+
let buildConfigurationStr;
|
|
162
|
+
if (await fs.exists(this.espressoBuildConfig)) {
|
|
163
|
+
logger.info(`Loading the build configuration from '${this.espressoBuildConfig}'`);
|
|
164
|
+
buildConfigurationStr = await fs.readFile(this.espressoBuildConfig, 'utf8');
|
|
165
|
+
} else {
|
|
166
|
+
logger.info(`Loading the build configuration from 'espressoBuildConfig' capability`);
|
|
167
|
+
buildConfigurationStr = this.espressoBuildConfig;
|
|
168
|
+
}
|
|
169
|
+
try {
|
|
170
|
+
buildConfiguration = JSON.parse(buildConfigurationStr);
|
|
171
|
+
} catch (e) {
|
|
172
|
+
logger.error('Cannot parse the build configuration JSON', e);
|
|
173
|
+
throw e;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
const dirName = fs.sanitizeName(`espresso-server-${this.adb.curDeviceId}`, {
|
|
177
|
+
replacement: '-',
|
|
178
|
+
});
|
|
179
|
+
const serverPath = path.resolve(this.tmpDir, dirName);
|
|
180
|
+
logger.info(`Building espresso server in '${serverPath}'`);
|
|
181
|
+
logger.debug(`The build folder root could be customized by changing the 'tmpDir' capability`);
|
|
182
|
+
await fs.rimraf(serverPath);
|
|
183
|
+
await mkdirp(serverPath);
|
|
184
|
+
logger.debug(`Copying espresso server template from ('${TEST_SERVER_ROOT}' to '${serverPath}')`);
|
|
185
|
+
await copyGradleProjectRecursively(TEST_SERVER_ROOT, serverPath);
|
|
186
|
+
logger.debug('Bulding espresso server');
|
|
187
|
+
await new ServerBuilder({
|
|
188
|
+
serverPath, buildConfiguration,
|
|
189
|
+
showGradleLog: this.showGradleLog,
|
|
190
|
+
testAppPackage: this.appPackage,
|
|
191
|
+
signingConfig: this.signingConfig
|
|
192
|
+
}).build();
|
|
193
|
+
const apkPath = path.resolve(serverPath, 'app', 'build', 'outputs', 'apk', 'androidTest', 'debug', 'app-debug-androidTest.apk');
|
|
194
|
+
logger.debug(`Copying built apk from '${apkPath}' to '${this.modServerPath}'`);
|
|
195
|
+
await fs.copyFile(apkPath, this.modServerPath);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
async cleanupSessionLeftovers () {
|
|
199
|
+
logger.debug('Performing cleanup of automation leftovers');
|
|
200
|
+
|
|
201
|
+
try {
|
|
202
|
+
const {value} = (await axios({
|
|
203
|
+
url: `http://${this.host}:${this.systemPort}/sessions`,
|
|
204
|
+
timeout: 500,
|
|
205
|
+
})).data;
|
|
206
|
+
const activeSessionIds = value.map((sess) => sess.id);
|
|
207
|
+
if (activeSessionIds.length) {
|
|
208
|
+
logger.debug(`The following obsolete sessions are still running: ${JSON.stringify(activeSessionIds)}`);
|
|
209
|
+
logger.debug('Cleaning up the obsolete sessions');
|
|
210
|
+
await B.all(activeSessionIds.map((id) =>
|
|
211
|
+
axios({
|
|
212
|
+
url: `http://${this.host}:${this.systemPort}/session/${id}`,
|
|
213
|
+
method: 'DELETE',
|
|
214
|
+
})
|
|
215
|
+
));
|
|
216
|
+
// Let all sessions to be properly terminated before continuing
|
|
217
|
+
await B.delay(1000);
|
|
218
|
+
} else {
|
|
219
|
+
logger.debug('No obsolete sessions have been detected');
|
|
220
|
+
}
|
|
221
|
+
} catch (e) {
|
|
222
|
+
logger.debug(`No obsolete sessions have been detected (${e.message})`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
async startSession (caps) {
|
|
227
|
+
await this.cleanupSessionLeftovers();
|
|
228
|
+
|
|
229
|
+
const cmd = [
|
|
230
|
+
'shell',
|
|
231
|
+
'am', 'instrument',
|
|
232
|
+
'-w',
|
|
233
|
+
'-e', 'debug', process.env.ESPRESSO_JAVA_DEBUG === 'true',
|
|
234
|
+
'-e', 'disableAnalytics', true, // To avoid unexpected error by google analytics
|
|
235
|
+
];
|
|
236
|
+
|
|
237
|
+
if (_.isBoolean(this.disableSuppressAccessibilityService)) {
|
|
238
|
+
cmd.push('-e', 'DISABLE_SUPPRESS_ACCESSIBILITY_SERVICES', this.disableSuppressAccessibilityService);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
cmd.push(`${TEST_APK_PKG}/androidx.test.runner.AndroidJUnitRunner`);
|
|
242
|
+
|
|
243
|
+
logger.info(`Starting Espresso Server v${version} with cmd: adb ${cmd.join(' ')}`);
|
|
244
|
+
|
|
245
|
+
let hasSocketError = false;
|
|
246
|
+
// start the instrumentation process
|
|
247
|
+
this.jwproxy.instrumentationState = {
|
|
248
|
+
exited: false,
|
|
249
|
+
crashed: false,
|
|
250
|
+
};
|
|
251
|
+
this.instProcess = this.adb.createSubProcess(cmd);
|
|
252
|
+
this.instProcess.on('exit', (code, signal) => {
|
|
253
|
+
logger.info(`Instrumentation process exited with code ${code} from signal ${signal}`);
|
|
254
|
+
this.jwproxy.instrumentationState.exited = true;
|
|
255
|
+
});
|
|
256
|
+
this.instProcess.on('output', (stdout, stderr) => {
|
|
257
|
+
const line = stdout || stderr;
|
|
258
|
+
if (_.isEmpty(line.trim())) {
|
|
259
|
+
// Do not print empty lines into the system log
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
logger.debug(`[Instrumentation] ${line.trim()}`);
|
|
264
|
+
// A 'SocketException' indicates that we couldn't connect to the Espresso server,
|
|
265
|
+
// because the INTERNET permission is not set
|
|
266
|
+
if (line.toLowerCase().includes('java.net.socketexception')) {
|
|
267
|
+
hasSocketError = true;
|
|
268
|
+
} else if (line.includes('Process crashed')) {
|
|
269
|
+
this.jwproxy.instrumentationState.crashed = true;
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
const timer = new timing.Timer().start();
|
|
274
|
+
await this.instProcess.start(0);
|
|
275
|
+
logger.info(`Waiting up to ${this.serverLaunchTimeout}ms for Espresso server to be online`);
|
|
276
|
+
try {
|
|
277
|
+
await waitForCondition(async () => {
|
|
278
|
+
if (hasSocketError) {
|
|
279
|
+
logger.errorAndThrow(`Espresso server has failed to start due to an unexpected exception. ` +
|
|
280
|
+
`Make sure the 'INTERNET' permission is requested in the Android manifest of your ` +
|
|
281
|
+
`application under test (<uses-permission android:name="android.permission.INTERNET" />)`);
|
|
282
|
+
} else if (this.jwproxy.instrumentationState.exited) {
|
|
283
|
+
logger.errorAndThrow(`Espresso server process has been unexpectedly terminated. ` +
|
|
284
|
+
`Check the Appium server log and the logcat output for more details`);
|
|
285
|
+
}
|
|
286
|
+
try {
|
|
287
|
+
await this.jwproxy.command('/status', 'GET');
|
|
288
|
+
return true;
|
|
289
|
+
} catch (e) {
|
|
290
|
+
return false;
|
|
291
|
+
}
|
|
292
|
+
}, {
|
|
293
|
+
waitMs: this.serverLaunchTimeout,
|
|
294
|
+
intervalMs: 500,
|
|
295
|
+
});
|
|
296
|
+
} catch (e) {
|
|
297
|
+
if (/Condition unmet/.test(e.message)) {
|
|
298
|
+
logger.errorAndThrow(`Timed out waiting for Espresso server to be ` +
|
|
299
|
+
`online within ${this.serverLaunchTimeout}ms. The timeout value could be ` +
|
|
300
|
+
`customized using 'espressoServerLaunchTimeout' capability`);
|
|
301
|
+
}
|
|
302
|
+
throw e;
|
|
303
|
+
}
|
|
304
|
+
logger.info(`Espresso server is online. ` +
|
|
305
|
+
`The initialization process took ${timer.getDuration().asMilliSeconds.toFixed(0)}ms`);
|
|
306
|
+
logger.info('Starting the session');
|
|
307
|
+
|
|
308
|
+
await this.jwproxy.command('/session', 'POST', {
|
|
309
|
+
capabilities: {
|
|
310
|
+
firstMatch: [caps],
|
|
311
|
+
alwaysMatch: {}
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
await this.recordTargetAppPackage();
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
async recordTargetAppPackage () {
|
|
318
|
+
await this.adb.shell([`echo "${this.appPackage}" > "${TARGET_PACKAGE_CONTAINER}"`]);
|
|
319
|
+
logger.info(`Recorded the target application package '${this.appPackage}' to ${TARGET_PACKAGE_CONTAINER}`);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
async deleteSession () {
|
|
323
|
+
logger.debug('Deleting Espresso server session');
|
|
324
|
+
// rely on jwproxy's intelligence to know what we're talking about and
|
|
325
|
+
// delete the current session
|
|
326
|
+
try {
|
|
327
|
+
await this.jwproxy.command('/', 'DELETE');
|
|
328
|
+
} catch (err) {
|
|
329
|
+
logger.warn(`Did not get confirmation Espresso deleteSession worked; ` +
|
|
330
|
+
`Error was: ${err}`);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
if (this.instProcess && this.instProcess.isRunning) {
|
|
334
|
+
await this.instProcess.stop();
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
export { EspressoRunner, REQUIRED_PARAMS, TEST_APK_PKG };
|
|
340
|
+
export default EspressoRunner;
|
package/lib/logger.js
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { SubProcess } from 'teen_process';
|
|
2
|
+
import { fs, logger, system } from 'appium-support';
|
|
3
|
+
import _ from 'lodash';
|
|
4
|
+
import log from './logger';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import { EOL } from 'os';
|
|
7
|
+
import { updateDependencyLines } from './utils';
|
|
8
|
+
|
|
9
|
+
const GRADLE_VERSION_KEY = 'gradle';
|
|
10
|
+
const GRADLE_URL_PREFIX = 'distributionUrl=';
|
|
11
|
+
const GRADLE_URL_TEMPLATE = 'https\\://services.gradle.org/distributions/gradle-VERSION-all.zip';
|
|
12
|
+
const GRADLE_MAX_ERROR_LOG_LINES = 15;
|
|
13
|
+
const DEPENDENCY_PROP_NAMES = ['additionalAppDependencies', 'additionalAndroidTestDependencies'];
|
|
14
|
+
|
|
15
|
+
const VERSION_KEYS = [
|
|
16
|
+
GRADLE_VERSION_KEY,
|
|
17
|
+
'androidGradlePlugin',
|
|
18
|
+
'compileSdk',
|
|
19
|
+
'buildTools',
|
|
20
|
+
'minSdk',
|
|
21
|
+
'targetSdk',
|
|
22
|
+
'kotlin'
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
const gradleLog = logger.getLogger('Gradle');
|
|
26
|
+
|
|
27
|
+
function buildServerSigningConfig (args) {
|
|
28
|
+
return {
|
|
29
|
+
zipAlign: true,
|
|
30
|
+
keystoreFile: args.keystoreFile,
|
|
31
|
+
keystorePassword: args.keystorePassword,
|
|
32
|
+
keyAlias: args.keyAlias,
|
|
33
|
+
keyPassword: args.keyPassword
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
class ServerBuilder {
|
|
38
|
+
constructor (args = {}) {
|
|
39
|
+
this.serverPath = args.serverPath;
|
|
40
|
+
this.showGradleLog = args.showGradleLog;
|
|
41
|
+
|
|
42
|
+
const buildConfiguration = args.buildConfiguration || {};
|
|
43
|
+
|
|
44
|
+
const versionConfiguration = buildConfiguration.toolsVersions || {};
|
|
45
|
+
this.serverVersions = _.reduce(versionConfiguration, (acc, value, key) => {
|
|
46
|
+
if (VERSION_KEYS.includes(key)) {
|
|
47
|
+
acc[key] = value;
|
|
48
|
+
} else {
|
|
49
|
+
log.warn(`Got unexpected '${key}' in toolsVersion block of the build configuration`);
|
|
50
|
+
}
|
|
51
|
+
return acc;
|
|
52
|
+
}, {});
|
|
53
|
+
|
|
54
|
+
this.testAppPackage = args.testAppPackage;
|
|
55
|
+
this.signingConfig = args.signingConfig;
|
|
56
|
+
|
|
57
|
+
for (const propName of DEPENDENCY_PROP_NAMES) {
|
|
58
|
+
this[propName] = buildConfiguration[propName] || [];
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async build () {
|
|
63
|
+
if (this.serverVersions[GRADLE_VERSION_KEY]) {
|
|
64
|
+
await this.setGradleWrapperVersion(this.serverVersions[GRADLE_VERSION_KEY]);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
await this.insertAdditionalDependencies();
|
|
68
|
+
|
|
69
|
+
await this.runBuildProcess();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
getCommand () {
|
|
73
|
+
const cmd = system.isWindows() ? 'gradlew.bat' : './gradlew';
|
|
74
|
+
const buildProperty = (key, value) => value ? `-P${key}=${value}` : null;
|
|
75
|
+
let args = VERSION_KEYS
|
|
76
|
+
.filter((key) => key !== GRADLE_VERSION_KEY)
|
|
77
|
+
.map((key) => {
|
|
78
|
+
const serverVersion = this.serverVersions[key];
|
|
79
|
+
const gradleProperty = `appium${key.charAt(0).toUpperCase()}${key.slice(1)}`;
|
|
80
|
+
return buildProperty(gradleProperty, serverVersion);
|
|
81
|
+
})
|
|
82
|
+
.filter(Boolean);
|
|
83
|
+
|
|
84
|
+
if (this.signingConfig) {
|
|
85
|
+
args.push(...(
|
|
86
|
+
_.keys(this.signingConfig)
|
|
87
|
+
.map((key) => [`appium${_.upperFirst(key)}`, this.signingConfig[key]])
|
|
88
|
+
.map(([k, v]) => buildProperty(k, v))
|
|
89
|
+
.filter(Boolean)
|
|
90
|
+
));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (this.testAppPackage) {
|
|
94
|
+
args.push(buildProperty('appiumTargetPackage', this.testAppPackage));
|
|
95
|
+
}
|
|
96
|
+
args.push('app:assembleAndroidTest');
|
|
97
|
+
|
|
98
|
+
return {cmd, args};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async setGradleWrapperVersion (version) {
|
|
102
|
+
const propertiesPath = path.resolve(this.serverPath, 'gradle', 'wrapper', 'gradle-wrapper.properties');
|
|
103
|
+
const originalProperties = await fs.readFile(propertiesPath, 'utf8');
|
|
104
|
+
const newProperties = this.updateGradleDistUrl(originalProperties, version);
|
|
105
|
+
await fs.writeFile(propertiesPath, newProperties, 'utf8');
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
updateGradleDistUrl (propertiesContent, version) {
|
|
109
|
+
return propertiesContent.replace(
|
|
110
|
+
new RegExp(`^(${_.escapeRegExp(GRADLE_URL_PREFIX)}).+$`, 'gm'),
|
|
111
|
+
`$1${GRADLE_URL_TEMPLATE.replace('VERSION', version)}`
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async insertAdditionalDependencies () {
|
|
116
|
+
let hasAdditionalDeps = false;
|
|
117
|
+
for (const propName of DEPENDENCY_PROP_NAMES) {
|
|
118
|
+
if (!_.isArray(this[propName])) {
|
|
119
|
+
throw new Error(`'${propName}' must be an array`);
|
|
120
|
+
}
|
|
121
|
+
if (_.isEmpty(this[propName].filter((line) => _.trim(line)))) {
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
for (const dep of this[propName]) {
|
|
126
|
+
if (/[\s'\\$]/.test(dep)) {
|
|
127
|
+
throw new Error('Single quotes, dollar characters and whitespace characters' +
|
|
128
|
+
` are disallowed in additional dependencies: ${dep}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
hasAdditionalDeps = true;
|
|
132
|
+
}
|
|
133
|
+
if (!hasAdditionalDeps) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const buildPath = path.resolve(this.serverPath, 'app', 'build.gradle.kts');
|
|
138
|
+
let configuration = await fs.readFile(buildPath, 'utf8');
|
|
139
|
+
for (const propName of DEPENDENCY_PROP_NAMES) {
|
|
140
|
+
const prefix = propName === DEPENDENCY_PROP_NAMES[0]
|
|
141
|
+
? 'implementation'
|
|
142
|
+
: 'androidTestImplementation';
|
|
143
|
+
const deps = this[propName]
|
|
144
|
+
.filter((line) => _.trim(line))
|
|
145
|
+
.map((line) => `${prefix}("${line}")`);
|
|
146
|
+
if (_.isEmpty(deps)) {
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
log.info(`Adding the following ${propName} to build.gradle.kts: ${deps}`);
|
|
151
|
+
configuration = updateDependencyLines(configuration, propName, deps);
|
|
152
|
+
}
|
|
153
|
+
await fs.writeFile(buildPath, configuration, 'utf8');
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
async runBuildProcess () {
|
|
157
|
+
const {cmd, args} = this.getCommand();
|
|
158
|
+
log.debug(`Beginning build with command '${cmd} ${args.join(' ')}' ` +
|
|
159
|
+
`in directory '${this.serverPath}'`);
|
|
160
|
+
const gradlebuild = new SubProcess(cmd, args, {
|
|
161
|
+
cwd: this.serverPath,
|
|
162
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
163
|
+
});
|
|
164
|
+
let buildLastLines = [];
|
|
165
|
+
|
|
166
|
+
const logMsg = `Output from Gradle ${this.showGradleLog ? 'will' : 'will not'} be logged`;
|
|
167
|
+
log.debug(`${logMsg}. To change this, use 'showGradleLog' desired capability`);
|
|
168
|
+
gradlebuild.on('stream-line', (line) => {
|
|
169
|
+
if (this.showGradleLog) {
|
|
170
|
+
if (line.startsWith('[STDERR]')) {
|
|
171
|
+
gradleLog.warn(line);
|
|
172
|
+
} else {
|
|
173
|
+
gradleLog.info(line);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
buildLastLines.push(`${EOL}${line}`);
|
|
177
|
+
if (buildLastLines.length > GRADLE_MAX_ERROR_LOG_LINES) {
|
|
178
|
+
buildLastLines = buildLastLines.slice(-GRADLE_MAX_ERROR_LOG_LINES);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
try {
|
|
183
|
+
await gradlebuild.start();
|
|
184
|
+
await gradlebuild.join();
|
|
185
|
+
} catch (err) {
|
|
186
|
+
let msg = `Unable to build Espresso server - ${err.message}\n` +
|
|
187
|
+
`Gradle error message:${EOL}${buildLastLines}`;
|
|
188
|
+
log.errorAndThrow(msg);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export { ServerBuilder, VERSION_KEYS, GRADLE_URL_TEMPLATE, buildServerSigningConfig };
|
|
194
|
+
export default ServerBuilder;
|
package/lib/server.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import log from './logger';
|
|
2
|
+
import { server as baseServer, routeConfiguringFunction } from 'appium-base-driver';
|
|
3
|
+
import EspressoDriver from './driver';
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
async function startServer (port, host) {
|
|
7
|
+
const d = new EspressoDriver({port, host});
|
|
8
|
+
const server = baseServer({
|
|
9
|
+
routeConfiguringFunction: routeConfiguringFunction(d),
|
|
10
|
+
port,
|
|
11
|
+
hostname: host,
|
|
12
|
+
});
|
|
13
|
+
log.info(`Android Espresso Driver listening on http://${host}:${port}`);
|
|
14
|
+
return await server;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export { startServer };
|
|
18
|
+
export default startServer;
|
package/lib/utils.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { fs, mkdirp } from 'appium-support';
|
|
2
|
+
import _ from 'lodash';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* https://android.googlesource.com/platform/frameworks/base/+/master/tools/aapt/Resource.cpp#755
|
|
7
|
+
*
|
|
8
|
+
* @param {string} activityName
|
|
9
|
+
* @param {string} packageName
|
|
10
|
+
* @returns {string} The qualified activity name
|
|
11
|
+
*/
|
|
12
|
+
function qualifyActivityName (activityName, packageName) {
|
|
13
|
+
// if either activity or package name is not set
|
|
14
|
+
// or any of these contain wildcards then there is
|
|
15
|
+
// no point in qualifying the activity name
|
|
16
|
+
if ([activityName, packageName].some((name) => !name || _.includes(name, '*'))) {
|
|
17
|
+
return activityName;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const dotPos = activityName.indexOf('.');
|
|
21
|
+
if (dotPos > 0) {
|
|
22
|
+
return activityName;
|
|
23
|
+
}
|
|
24
|
+
return `${packageName}${dotPos === 0 ? '' : '.'}${activityName}`;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Recursively copy all files except build directories contents
|
|
29
|
+
* @param sourceBaseDir {string} directory to copy files from
|
|
30
|
+
* @param targetBaseDir {string} directory to copy files to
|
|
31
|
+
*/
|
|
32
|
+
async function copyGradleProjectRecursively (sourceBaseDir, targetBaseDir) {
|
|
33
|
+
await fs.walkDir(sourceBaseDir, true, async (itemPath, isDirectory) => {
|
|
34
|
+
const relativePath = path.relative(sourceBaseDir, itemPath);
|
|
35
|
+
const targetPath = path.resolve(targetBaseDir, relativePath);
|
|
36
|
+
|
|
37
|
+
const isInGradleBuildDir = `${path.sep}${itemPath}`.includes(`${path.sep}build${path.sep}`);
|
|
38
|
+
if (isInGradleBuildDir) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (isDirectory) {
|
|
43
|
+
await mkdirp(targetPath);
|
|
44
|
+
} else {
|
|
45
|
+
await fs.copyFile(itemPath, targetPath);
|
|
46
|
+
}
|
|
47
|
+
return false;
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function requireOptions (opts, requiredKeys = []) {
|
|
52
|
+
const missingKeys = _.difference(requiredKeys, _.keys(opts));
|
|
53
|
+
if (!_.isEmpty(missingKeys)) {
|
|
54
|
+
throw new Error(`The following options are required: ${missingKeys}`);
|
|
55
|
+
}
|
|
56
|
+
return opts;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function updateDependencyLines (originalContent, dependencyPlaceholder, dependencyLines) {
|
|
60
|
+
const configurationLines = originalContent.split('\n');
|
|
61
|
+
const searchRe = new RegExp(`^\\s*//\\s*\\b${_.escapeRegExp(dependencyPlaceholder)}\\b`, 'm');
|
|
62
|
+
const placeholderIndex = configurationLines.findIndex((line) => searchRe.test(line));
|
|
63
|
+
if (placeholderIndex < 0) {
|
|
64
|
+
return originalContent;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const placeholderLine = configurationLines[placeholderIndex];
|
|
68
|
+
const indentLen = placeholderLine.length - _.trimStart(placeholderLine).length;
|
|
69
|
+
configurationLines.splice(placeholderIndex + 1, 0, ...(dependencyLines
|
|
70
|
+
.map((line) => `${' '.repeat(indentLen)}${line}`)));
|
|
71
|
+
return configurationLines.join('\n');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export { qualifyActivityName, copyGradleProjectRecursively, requireOptions, updateDependencyLines };
|