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,64 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
* you may not use this file except in compliance with the License.
|
|
4
|
+
* See the NOTICE file distributed with this work for additional
|
|
5
|
+
* information regarding copyright ownership.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
package io.appium.espressoserver.lib.helpers
|
|
18
|
+
|
|
19
|
+
import io.appium.espressoserver.lib.handlers.exceptions.AppiumException
|
|
20
|
+
import io.appium.espressoserver.lib.helpers.reflection.MethodUtils
|
|
21
|
+
import java.lang.reflect.Field
|
|
22
|
+
import java.lang.reflect.Method
|
|
23
|
+
import kotlin.reflect.KProperty1
|
|
24
|
+
import kotlin.reflect.full.declaredMemberProperties
|
|
25
|
+
|
|
26
|
+
object ReflectionUtils {
|
|
27
|
+
|
|
28
|
+
fun extractMethod(clazz: Class<*>, methodName: String, vararg parameterTypes: Class<*>): Method {
|
|
29
|
+
try {
|
|
30
|
+
val result = clazz.getDeclaredMethod(methodName, *parameterTypes)
|
|
31
|
+
result.isAccessible = true
|
|
32
|
+
return result
|
|
33
|
+
} catch (e: NoSuchMethodException) {
|
|
34
|
+
throw AppiumException("Method '${methodName}' is not defined for class ${clazz.canonicalName}", e)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
fun invokeStaticMethod(clazz: Class<*>, methodName: String, vararg providedParams: Any?): Any? =
|
|
39
|
+
MethodUtils.invokeStaticMethod(clazz, methodName, *providedParams)
|
|
40
|
+
|
|
41
|
+
fun invokeInstanceMethod(instance: Any, methodName: String, vararg providedParams: Any?): Any? =
|
|
42
|
+
MethodUtils.invokeMethod(instance, methodName, *providedParams)
|
|
43
|
+
|
|
44
|
+
fun invokeMethod(instance: Any?, method: Method, vararg providedParams: Any?): Any? =
|
|
45
|
+
method.invoke(instance, *providedParams)
|
|
46
|
+
|
|
47
|
+
fun extractField(clazz: Class<*>, fieldName: String, instance: Any?): Any? {
|
|
48
|
+
val field: Field = clazz.getDeclaredField(fieldName)
|
|
49
|
+
field.isAccessible = true
|
|
50
|
+
return field.get(instance)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
fun extractDeclaredProperties(instance: Any): Map<String, Any?> {
|
|
54
|
+
return instance::class.declaredMemberProperties
|
|
55
|
+
.fold(mutableMapOf<String, Any?>()) { acc, prop ->
|
|
56
|
+
try {
|
|
57
|
+
@Suppress("UNCHECKED_CAST")
|
|
58
|
+
acc[prop.name] = (prop as KProperty1<Any, Any?>).get(instance)
|
|
59
|
+
} catch (ign: Exception) {
|
|
60
|
+
}
|
|
61
|
+
acc
|
|
62
|
+
}.toMap()
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
* you may not use this file except in compliance with the License.
|
|
4
|
+
* See the NOTICE file distributed with this work for additional
|
|
5
|
+
* information regarding copyright ownership.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
package io.appium.espressoserver.lib.helpers
|
|
18
|
+
|
|
19
|
+
import android.graphics.Bitmap
|
|
20
|
+
import android.util.Base64
|
|
21
|
+
import android.view.View
|
|
22
|
+
|
|
23
|
+
import java.io.ByteArrayOutputStream
|
|
24
|
+
import androidx.test.runner.screenshot.Screenshot
|
|
25
|
+
import io.appium.espressoserver.lib.handlers.exceptions.AppiumException
|
|
26
|
+
import io.appium.espressoserver.lib.handlers.exceptions.ElementNotVisibleException
|
|
27
|
+
import io.appium.espressoserver.lib.handlers.exceptions.ScreenCaptureException
|
|
28
|
+
import io.appium.espressoserver.lib.model.ViewElement
|
|
29
|
+
|
|
30
|
+
class ScreenshotsHelper @JvmOverloads constructor(private val view: View? = null) {
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Makes a screenshot of the particular view.
|
|
34
|
+
*
|
|
35
|
+
* @return the screenshot of the view as base-64 encoded string.
|
|
36
|
+
* @throws ElementNotVisibleException if the view has no visible area.
|
|
37
|
+
* @throws ScreenCaptureException if it is impossible to take a screenshot.
|
|
38
|
+
*/
|
|
39
|
+
val screenshot: String
|
|
40
|
+
@Throws(AppiumException::class)
|
|
41
|
+
get() {
|
|
42
|
+
if (view != null && ViewElement(view).bounds.isEmpty) {
|
|
43
|
+
throw ElementNotVisibleException(
|
|
44
|
+
String.format("Cannot get a screenshot of the invisible %s", view.javaClass.name))
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
val screenCap = if (view == null) Screenshot.capture() else Screenshot.capture(view)
|
|
48
|
+
val bitmapScreenCap = screenCap.bitmap
|
|
49
|
+
if (bitmapScreenCap == null || bitmapScreenCap.height == 0 || bitmapScreenCap.width == 0) {
|
|
50
|
+
throw ScreenCaptureException("Cannot capture a shot of the " +
|
|
51
|
+
"${if (view == null) "current screen" else view.javaClass.name}. " +
|
|
52
|
+
"Make sure none of the currently visible " +
|
|
53
|
+
"views have FLAG_SECURE set and that it is possible to take a screenshot manually")
|
|
54
|
+
}
|
|
55
|
+
val outputStream = ByteArrayOutputStream()
|
|
56
|
+
bitmapScreenCap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
|
|
57
|
+
return Base64.encodeToString(outputStream.toByteArray(), Base64.DEFAULT)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
* you may not use this file except in compliance with the License.
|
|
4
|
+
* See the NOTICE file distributed with this work for additional
|
|
5
|
+
* information regarding copyright ownership.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
package io.appium.espressoserver.lib.helpers
|
|
18
|
+
|
|
19
|
+
object StringHelpers {
|
|
20
|
+
|
|
21
|
+
@JvmStatic
|
|
22
|
+
fun abbreviate(str: String?, len: Int): String? {
|
|
23
|
+
return if (str != null && str.length > len) str.substring(0, len) + "\u2026" else str
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
fun isBlank(str: String?): Boolean {
|
|
27
|
+
return str == null || str.trim { it <= ' ' } == ""
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
private fun charSequenceToString(input: CharSequence?, replaceNull: Boolean): String? {
|
|
31
|
+
return input?.toString() ?: if (replaceNull) "" else null
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
fun charSequenceToNullableString(input: CharSequence?): String? {
|
|
35
|
+
return charSequenceToString(input, false)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
fun charSequenceToNonNullString(input: CharSequence?): String {
|
|
39
|
+
return charSequenceToString(input, true)!!.toString()
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
package io.appium.espressoserver.lib.helpers
|
|
2
|
+
|
|
3
|
+
fun getThreadDump() : String {
|
|
4
|
+
val threadDetails = StringBuilder()
|
|
5
|
+
val activeCount = Thread.activeCount()
|
|
6
|
+
val threads = arrayOfNulls<Thread>(activeCount)
|
|
7
|
+
Thread.enumerate(threads)
|
|
8
|
+
for (thread in threads.filterNotNull()) {
|
|
9
|
+
threadDetails.append("\n\n ThreadName: ${thread.name}: State: ${thread.state}")
|
|
10
|
+
for (stackTraceElement in thread.stackTrace) {
|
|
11
|
+
threadDetails.append("\n\t\t$stackTraceElement")
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return threadDetails.toString();
|
|
15
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
* you may not use this file except in compliance with the License.
|
|
4
|
+
* See the NOTICE file distributed with this work for additional
|
|
5
|
+
* information regarding copyright ownership.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
package io.appium.espressoserver.lib.helpers
|
|
17
|
+
|
|
18
|
+
import android.app.UiAutomation
|
|
19
|
+
import android.app.UiAutomation.OnAccessibilityEventListener
|
|
20
|
+
import androidx.test.platform.app.InstrumentationRegistry
|
|
21
|
+
import androidx.test.uiautomator.UiDevice
|
|
22
|
+
import io.appium.espressoserver.lib.helpers.ReflectionUtils.extractField
|
|
23
|
+
import io.appium.espressoserver.lib.helpers.ReflectionUtils.extractMethod
|
|
24
|
+
import io.appium.espressoserver.lib.helpers.ReflectionUtils.invokeMethod
|
|
25
|
+
|
|
26
|
+
const val FIELD_ON_ACCESSIBILITY_EVENT_LISTENER = "mOnAccessibilityEventListener"
|
|
27
|
+
|
|
28
|
+
object UiAutomationWrapper {
|
|
29
|
+
private val uia: UiAutomation
|
|
30
|
+
private val uiDevice: UiDevice
|
|
31
|
+
get() = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
|
32
|
+
|
|
33
|
+
init {
|
|
34
|
+
uia = invokeMethod(uiDevice, extractMethod(UiDevice::class.java, "getUiAutomation")) as UiAutomation
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
var onAccessibilityEventListener: OnAccessibilityEventListener?
|
|
38
|
+
get() = try {
|
|
39
|
+
extractField(UiAutomationWrapper::class.java,
|
|
40
|
+
FIELD_ON_ACCESSIBILITY_EVENT_LISTENER, uia) as OnAccessibilityEventListener?
|
|
41
|
+
} catch (e: Exception) {
|
|
42
|
+
/* mOnAccessibilityEventListener is no longer accessible on Android P */
|
|
43
|
+
null
|
|
44
|
+
}
|
|
45
|
+
set(listener) {
|
|
46
|
+
uia.setOnAccessibilityEventListener(listener)
|
|
47
|
+
}
|
|
48
|
+
}
|
package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/ViewFinder.kt
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
* you may not use this file except in compliance with the License.
|
|
4
|
+
* See the NOTICE file distributed with this work for additional
|
|
5
|
+
* information regarding copyright ownership.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
package io.appium.espressoserver.lib.helpers
|
|
18
|
+
|
|
19
|
+
import android.content.Context
|
|
20
|
+
|
|
21
|
+
import androidx.test.espresso.DataInteraction
|
|
22
|
+
import androidx.test.espresso.EspressoException
|
|
23
|
+
import androidx.test.espresso.PerformException
|
|
24
|
+
import android.view.View
|
|
25
|
+
import android.widget.AdapterView
|
|
26
|
+
|
|
27
|
+
import org.hamcrest.Description
|
|
28
|
+
import org.hamcrest.Matcher
|
|
29
|
+
import org.hamcrest.Matchers
|
|
30
|
+
import org.hamcrest.TypeSafeMatcher
|
|
31
|
+
|
|
32
|
+
import java.util.ArrayList
|
|
33
|
+
|
|
34
|
+
import io.appium.espressoserver.lib.handlers.exceptions.AppiumException
|
|
35
|
+
import io.appium.espressoserver.lib.handlers.exceptions.InvalidSelectorException
|
|
36
|
+
import io.appium.espressoserver.lib.handlers.exceptions.XPathLookupException
|
|
37
|
+
import io.appium.espressoserver.lib.model.Strategy
|
|
38
|
+
import io.appium.espressoserver.lib.viewaction.ViewGetter
|
|
39
|
+
|
|
40
|
+
import androidx.test.core.app.ApplicationProvider.getApplicationContext
|
|
41
|
+
import androidx.test.espresso.AppNotIdleException
|
|
42
|
+
import androidx.test.espresso.Espresso.onData
|
|
43
|
+
import androidx.test.espresso.Espresso.onView
|
|
44
|
+
import androidx.test.espresso.assertion.ViewAssertions.matches
|
|
45
|
+
import androidx.test.espresso.matcher.ViewMatchers.isDescendantOfA
|
|
46
|
+
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
|
|
47
|
+
import androidx.test.espresso.matcher.ViewMatchers.withClassName
|
|
48
|
+
import androidx.test.espresso.matcher.ViewMatchers.withContentDescription
|
|
49
|
+
import androidx.test.espresso.matcher.ViewMatchers.withId
|
|
50
|
+
import androidx.test.espresso.matcher.ViewMatchers.withTagValue
|
|
51
|
+
import androidx.test.espresso.matcher.ViewMatchers.withText
|
|
52
|
+
import io.appium.espressoserver.lib.handlers.exceptions.InvalidElementStateException
|
|
53
|
+
import io.appium.espressoserver.lib.model.toJsonMatcher
|
|
54
|
+
import io.appium.espressoserver.lib.viewmatcher.withView
|
|
55
|
+
import io.appium.espressoserver.lib.viewmatcher.withXPath
|
|
56
|
+
import org.hamcrest.CoreMatchers.allOf
|
|
57
|
+
import org.hamcrest.CoreMatchers.equalTo
|
|
58
|
+
import org.hamcrest.CoreMatchers.`is`
|
|
59
|
+
import org.hamcrest.Matchers.endsWith
|
|
60
|
+
import org.hamcrest.Matchers.hasEntry
|
|
61
|
+
import org.hamcrest.Matchers.instanceOf
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Helper methods to find elements based on locator strategies and selectors
|
|
65
|
+
*/
|
|
66
|
+
object ViewFinder {
|
|
67
|
+
private const val ID_PATTERN = "[\\S]+:id/[\\S]+"
|
|
68
|
+
private const val APP_NOT_IDLE_MESSAGE = "The application is expected to be in idle state in order for Espresso to interact with it. " +
|
|
69
|
+
"Review the threads dump below to know more on which entity is hogging the events loop "
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Find one instance of an element that matches the locator criteria
|
|
73
|
+
*
|
|
74
|
+
* @param root Parent view instance or null if the search is executed against the
|
|
75
|
+
* full hierarchy
|
|
76
|
+
* @param strategy Locator strategy (xpath, class name, etc...)
|
|
77
|
+
* @param selector Selector string
|
|
78
|
+
* @return
|
|
79
|
+
* @throws InvalidSelectorException
|
|
80
|
+
* @throws XPathLookupException
|
|
81
|
+
*/
|
|
82
|
+
@Throws(AppiumException::class)
|
|
83
|
+
fun findBy(
|
|
84
|
+
root: View?, strategy: Strategy, selector: String): View? {
|
|
85
|
+
val viewInteractions = findAllBy(root, strategy, selector, true)
|
|
86
|
+
return if (viewInteractions.isEmpty()) {
|
|
87
|
+
null
|
|
88
|
+
} else viewInteractions[0]
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Find all instances of an element that matches the locator criteria
|
|
93
|
+
*
|
|
94
|
+
* @param root Parent view instance or null if the search is executed against the
|
|
95
|
+
* full hierarchy
|
|
96
|
+
* @param strategy Locator strategy (xpath, class name, etc...)
|
|
97
|
+
* @param selector Selector string
|
|
98
|
+
* @return
|
|
99
|
+
* @throws InvalidSelectorException
|
|
100
|
+
* @throws XPathLookupException
|
|
101
|
+
*/
|
|
102
|
+
@Throws(AppiumException::class)
|
|
103
|
+
fun findAllBy(root: View?,
|
|
104
|
+
strategy: Strategy, selector: String): List<View> {
|
|
105
|
+
return findAllBy(root, strategy, selector, false)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Returns the currently focused element or null if
|
|
110
|
+
* there is no such element
|
|
111
|
+
*
|
|
112
|
+
* @return focused element instance or null
|
|
113
|
+
*/
|
|
114
|
+
fun findActive(): View? {
|
|
115
|
+
val views = getViews(null,
|
|
116
|
+
object : TypeSafeMatcher<View>() {
|
|
117
|
+
override fun matchesSafely(item: View): Boolean {
|
|
118
|
+
return item.isFocused
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
override fun describeTo(description: Description) {
|
|
122
|
+
description.appendText("is focused")
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
true)
|
|
126
|
+
return if (views.isEmpty()) {
|
|
127
|
+
null
|
|
128
|
+
} else views[0]
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
///Find By different strategies
|
|
132
|
+
@Throws(AppiumException::class)
|
|
133
|
+
private fun findAllBy(root: View?, strategy: Strategy,
|
|
134
|
+
selector: String, findOne: Boolean): List<View> {
|
|
135
|
+
@Suppress("NAME_SHADOWING") var selector = selector
|
|
136
|
+
var views: List<View>
|
|
137
|
+
when (strategy) {
|
|
138
|
+
Strategy.ID // with ID
|
|
139
|
+
-> {
|
|
140
|
+
|
|
141
|
+
// find id from target context
|
|
142
|
+
val context = getApplicationContext<Context>()
|
|
143
|
+
if (!selector.matches(ID_PATTERN.toRegex())) {
|
|
144
|
+
selector = "${context.packageName}:id/$selector"
|
|
145
|
+
AndroidLogger.info("Rewrote Id selector to '$selector'")
|
|
146
|
+
}
|
|
147
|
+
val id = context.resources.getIdentifier(selector, "Id", context.packageName)
|
|
148
|
+
|
|
149
|
+
views = getViews(root, withId(id), findOne)
|
|
150
|
+
}
|
|
151
|
+
Strategy.CLASS_NAME ->
|
|
152
|
+
// with class name
|
|
153
|
+
// TODO: improve this finder with instanceOf
|
|
154
|
+
views = getViews(root, withClassName(endsWith(selector)), findOne)
|
|
155
|
+
Strategy.TEXT ->
|
|
156
|
+
// with text
|
|
157
|
+
views = getViews(root, withText(selector), findOne)
|
|
158
|
+
Strategy.ACCESSIBILITY_ID -> {
|
|
159
|
+
views = getViews(root, withContentDescription(selector), findOne)
|
|
160
|
+
|
|
161
|
+
// If the item is not found on the screen, use 'onData' to try
|
|
162
|
+
// to scroll it into view and then locate it again
|
|
163
|
+
if (views.isEmpty() && canScrollToViewWithContentDescription(root, selector)) {
|
|
164
|
+
views = getViews(root, withContentDescription(selector), findOne)
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
Strategy.XPATH ->
|
|
168
|
+
// If we're only looking for one item that matches xpath, pass it index 0 or else
|
|
169
|
+
// Espresso throws an AmbiguousMatcherException
|
|
170
|
+
views = if (findOne) {
|
|
171
|
+
getViews(root, withXPath(root, selector, 0), true)
|
|
172
|
+
} else {
|
|
173
|
+
getViews(root, withXPath(root, selector), false)
|
|
174
|
+
}
|
|
175
|
+
Strategy.VIEW_TAG -> views = getViews(root, withTagValue(allOf(instanceOf(String::class.java),
|
|
176
|
+
equalTo(selector as Any))), findOne)
|
|
177
|
+
Strategy.DATAMATCHER -> {
|
|
178
|
+
val matcher = selector.toJsonMatcher()
|
|
179
|
+
views = try {
|
|
180
|
+
getViewsFromDataInteraction(root, onData(matcher.matcher))
|
|
181
|
+
} catch (e: PerformException) {
|
|
182
|
+
// Perform Exception means nothing was found. Return empty list
|
|
183
|
+
emptyList()
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
Strategy.VIEWMATCHER -> {
|
|
187
|
+
val matcherJson = selector.toJsonMatcher()
|
|
188
|
+
views = try {
|
|
189
|
+
@Suppress("UNCHECKED_CAST")
|
|
190
|
+
getViewsFromViewMatcher(root, matcherJson.matcher as Matcher<View>)
|
|
191
|
+
} catch (e: PerformException) {
|
|
192
|
+
// Perform Exception means nothing was found. Return empty list
|
|
193
|
+
emptyList()
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
else -> throw InvalidSelectorException("Strategy is not implemented: ${strategy.strategyName}")
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return views
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Attempts to scroll to a view with the content description using onData
|
|
204
|
+
*
|
|
205
|
+
* @param contentDesc Content description
|
|
206
|
+
* @return
|
|
207
|
+
*/
|
|
208
|
+
private fun canScrollToViewWithContentDescription(parentView: View?,
|
|
209
|
+
contentDesc: String): Boolean {
|
|
210
|
+
try {
|
|
211
|
+
val dataInteraction = onData(
|
|
212
|
+
hasEntry(Matchers.equalTo("contentDescription"), `is`(contentDesc))
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
// If the parentView provided is an AdapterView, set 'inAdapterView' so that the
|
|
216
|
+
// selector is restricted to the adapter subtree
|
|
217
|
+
if (parentView is AdapterView<*>) {
|
|
218
|
+
dataInteraction.inAdapterView(withView(parentView))
|
|
219
|
+
}
|
|
220
|
+
dataInteraction.check(matches(isDisplayed()))
|
|
221
|
+
} catch (e: Exception) {
|
|
222
|
+
return false
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return true
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
private fun getViewsFromDataInteraction(
|
|
229
|
+
root: View?, dataInteraction: DataInteraction
|
|
230
|
+
): List<View> {
|
|
231
|
+
// Defensive copy
|
|
232
|
+
var dataInteractionCopy = dataInteraction
|
|
233
|
+
|
|
234
|
+
// Look up the view hierarchy to find the closest ancestor AdapterView
|
|
235
|
+
var ancestorAdapterView = root
|
|
236
|
+
while (ancestorAdapterView != null && ancestorAdapterView !is AdapterView<*>) {
|
|
237
|
+
val parent = ancestorAdapterView.parent
|
|
238
|
+
ancestorAdapterView = parent as? View
|
|
239
|
+
}
|
|
240
|
+
ancestorAdapterView?.let {
|
|
241
|
+
dataInteractionCopy = dataInteractionCopy.inAdapterView(withView(it))
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
return listOf(ViewGetter().getView(dataInteractionCopy))
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
private fun getViewsFromViewMatcher(root: View?, matcher: Matcher<View>): List<View> {
|
|
248
|
+
val viewInteraction = if (root == null)
|
|
249
|
+
onView(matcher)
|
|
250
|
+
else
|
|
251
|
+
onView(allOf(isDescendantOfA(`is`(root)), matcher))
|
|
252
|
+
return listOf(ViewGetter().getView(viewInteraction))
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
private fun getViews(
|
|
256
|
+
root: View?, matcher: Matcher<View>, findOne: Boolean): List<View> {
|
|
257
|
+
// If it's just one view we want, return a singleton list
|
|
258
|
+
if (findOne) {
|
|
259
|
+
try {
|
|
260
|
+
val viewInteraction = if (root == null)
|
|
261
|
+
onView(withIndex(matcher, 0))
|
|
262
|
+
else
|
|
263
|
+
onView(allOf(isDescendantOfA(`is`(root)), withIndex(matcher, 0)))
|
|
264
|
+
return listOf(ViewGetter().getView(viewInteraction))
|
|
265
|
+
} catch (e: AppNotIdleException){
|
|
266
|
+
throw InvalidElementStateException(APP_NOT_IDLE_MESSAGE + getThreadDump(), e)
|
|
267
|
+
} catch (e: Exception) {
|
|
268
|
+
if (e is EspressoException) {
|
|
269
|
+
return emptyList()
|
|
270
|
+
}
|
|
271
|
+
throw e
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// If we want all views that match the criteria, start looking for ViewInteractions by
|
|
276
|
+
// index and add each match to the List. As soon as we find no match, break the loop
|
|
277
|
+
// and return the list
|
|
278
|
+
val viewInteractions = ArrayList<View>()
|
|
279
|
+
var i = 0
|
|
280
|
+
do {
|
|
281
|
+
try {
|
|
282
|
+
val viewInteraction = if (root == null)
|
|
283
|
+
onView(withIndex(matcher, i++))
|
|
284
|
+
else
|
|
285
|
+
onView(allOf(isDescendantOfA(`is`(root)), withIndex(matcher, i++)))
|
|
286
|
+
val view = ViewGetter().getView(viewInteraction)
|
|
287
|
+
viewInteractions.add(view)
|
|
288
|
+
} catch (e: AppNotIdleException){
|
|
289
|
+
throw InvalidElementStateException(APP_NOT_IDLE_MESSAGE + getThreadDump(), e)
|
|
290
|
+
} catch (e: Exception) {
|
|
291
|
+
if (e is EspressoException) {
|
|
292
|
+
return viewInteractions
|
|
293
|
+
}
|
|
294
|
+
throw e
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
} while (i < Integer.MAX_VALUE)
|
|
298
|
+
return viewInteractions
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
private fun withIndex(matcher: Matcher<View>, index: Int): Matcher<View> {
|
|
302
|
+
return object : TypeSafeMatcher<View>() {
|
|
303
|
+
var currentIndex = 0
|
|
304
|
+
|
|
305
|
+
override fun describeTo(description: Description) {
|
|
306
|
+
description.appendText("with index: ")
|
|
307
|
+
description.appendValue(index)
|
|
308
|
+
matcher.describeTo(description)
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
public override fun matchesSafely(view: View): Boolean {
|
|
312
|
+
return matcher.matches(view) && currentIndex++ == index
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/XMLHelpers.kt
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
* you may not use this file except in compliance with the License.
|
|
4
|
+
* See the NOTICE file distributed with this work for additional
|
|
5
|
+
* information regarding copyright ownership.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
package io.appium.espressoserver.lib.helpers
|
|
18
|
+
|
|
19
|
+
import java.util.regex.Pattern
|
|
20
|
+
|
|
21
|
+
object XMLHelpers {
|
|
22
|
+
// XML 1.0 Legal Characters (http://stackoverflow.com/a/4237934/347155)
|
|
23
|
+
// #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
|
|
24
|
+
private val XML10_PATTERN = Pattern.compile("[^" + "\u0009\r\n" +
|
|
25
|
+
"\u0020-\uD7FF" + "\uE000-\uFFFD" + "\ud800\udc00-\udbff\udfff" + "]")
|
|
26
|
+
// https://stackoverflow.com/questions/3158274/what-would-be-a-regex-for-valid-xml-names
|
|
27
|
+
private val XML10_START_TAG_PATTERN = Pattern.compile("^[^" + "_" +
|
|
28
|
+
"A-Z" + "a-z" + "\u00C0-\u00D6" + "\u00F8-\u02FF" +
|
|
29
|
+
"\u200C-\u200D" + "\u2070-\u218F" + "\u2C00-\u2FEF" +
|
|
30
|
+
"\u3001-\uD7FF" + "\uF900-\uFDCF" + "\uFDF0-\uFFFD" +
|
|
31
|
+
"\ud800\udc00-\udbff\udfff" + "]+")
|
|
32
|
+
private val XML10_TAG_PATTERN = Pattern.compile("[^" + "\\-._" +
|
|
33
|
+
"0-9" + "\u00B7" + "\u0300-\u036F" + "\u203F-\u2040" +
|
|
34
|
+
"A-Z" + "a-z" + "\u00C0-\u00D6" + "\u00F8-\u02FF" +
|
|
35
|
+
"\u200C-\u200D" + "\u2070-\u218F" + "\u2C00-\u2FEF" +
|
|
36
|
+
"\u3001-\uD7FF" + "\uF900-\uFDCF" + "\uFDF0-\uFFFD" +
|
|
37
|
+
"\ud800\udc00-\udbff\udfff" + "]")
|
|
38
|
+
|
|
39
|
+
fun toNodeName(str: String): String {
|
|
40
|
+
val nodeName = XML10_START_TAG_PATTERN
|
|
41
|
+
.matcher(str)
|
|
42
|
+
.replaceAll("")
|
|
43
|
+
return XML10_TAG_PATTERN
|
|
44
|
+
.matcher(nodeName)
|
|
45
|
+
.replaceAll("_")
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
fun toSafeString(source: Any?, replacement: String): String? {
|
|
49
|
+
return if (source == null)
|
|
50
|
+
null
|
|
51
|
+
else
|
|
52
|
+
XML10_PATTERN
|
|
53
|
+
.matcher(source.toString())
|
|
54
|
+
.replaceAll(replacement)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
package io.appium.espressoserver.lib.helpers.extensions
|
|
2
|
+
|
|
3
|
+
import java.util.concurrent.Semaphore
|
|
4
|
+
|
|
5
|
+
fun <R> Semaphore.withPermit(block: () -> R): R {
|
|
6
|
+
this.acquire()
|
|
7
|
+
try {
|
|
8
|
+
return block()
|
|
9
|
+
} finally {
|
|
10
|
+
this.release()
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
fun <R> Semaphore.withPermit(block: () -> R, finalBlock: () -> Unit): R {
|
|
15
|
+
this.acquire()
|
|
16
|
+
try {
|
|
17
|
+
return block()
|
|
18
|
+
} finally {
|
|
19
|
+
finalBlock()
|
|
20
|
+
this.release()
|
|
21
|
+
}
|
|
22
|
+
}
|