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.
Files changed (311) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/LICENSE +201 -0
  3. package/README.md +864 -0
  4. package/build/index.js +48 -0
  5. package/build/lib/commands/execute.js +67 -0
  6. package/build/lib/commands/general.js +337 -0
  7. package/build/lib/commands/idling-resources.js +31 -0
  8. package/build/lib/commands/index.js +26 -0
  9. package/build/lib/commands/services.js +27 -0
  10. package/build/lib/desired-caps.js +65 -0
  11. package/build/lib/driver.js +475 -0
  12. package/build/lib/espresso-runner.js +381 -0
  13. package/build/lib/logger.js +18 -0
  14. package/build/lib/server-builder.js +213 -0
  15. package/build/lib/server.js +39 -0
  16. package/build/lib/utils.js +85 -0
  17. package/espresso-server/app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk +0 -0
  18. package/espresso-server/app/build/outputs/apk/androidTest/debug/output-metadata.json +18 -0
  19. package/espresso-server/app/build.gradle.kts +153 -0
  20. package/espresso-server/app/proguard-rules.pro +25 -0
  21. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/EspressoServerRunnerTest.kt +93 -0
  22. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/drivers/AppDriver.kt +29 -0
  23. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/drivers/ComposeDriver.kt +73 -0
  24. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/drivers/DriverContext.kt +35 -0
  25. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/drivers/EspressoDriver.kt +70 -0
  26. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/AcceptAlert.kt +32 -0
  27. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/Back.kt +31 -0
  28. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/Clear.kt +40 -0
  29. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/Click.kt +27 -0
  30. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/CreateSession.kt +58 -0
  31. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/DeleteSession.kt +33 -0
  32. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/DismissAlert.kt +32 -0
  33. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/DrawerActionHandler.kt +45 -0
  34. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/ElementEquals.kt +19 -0
  35. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/ElementScreenshot.kt +31 -0
  36. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/ElementValue.kt +85 -0
  37. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/FindActive.kt +32 -0
  38. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/FindElement.kt +29 -0
  39. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/FindElements.kt +43 -0
  40. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetAlertText.kt +31 -0
  41. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetAttribute.kt +101 -0
  42. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetClipboard.kt +65 -0
  43. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetDeviceInfo.kt +44 -0
  44. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetDisplayed.kt +28 -0
  45. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetEnabled.kt +30 -0
  46. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetLocation.kt +32 -0
  47. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetLocationInView.kt +33 -0
  48. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetName.kt +31 -0
  49. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetOrientation.kt +44 -0
  50. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetRect.kt +38 -0
  51. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetRotation.kt +33 -0
  52. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetSelected.kt +30 -0
  53. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetSession.kt +34 -0
  54. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetSessions.kt +41 -0
  55. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetSettings.kt +25 -0
  56. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetSize.kt +32 -0
  57. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetToastVisibility.kt +34 -0
  58. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetWindowRect.kt +43 -0
  59. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/GetWindowSize.kt +42 -0
  60. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/HideKeyboard.kt +29 -0
  61. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/Keys.kt +82 -0
  62. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/ListIdlingResources.kt +30 -0
  63. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/MobileBackdoor.kt +42 -0
  64. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/MobileClickAction.kt +49 -0
  65. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/MobileSwipe.kt +71 -0
  66. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/MobileViewFlash.kt +50 -0
  67. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/MoveTo.kt +50 -0
  68. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/MultiTouchAction.kt +50 -0
  69. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/NavigateTo.kt +42 -0
  70. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/NoSessionCommandHandler.kt +4 -0
  71. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/NotYetImplemented.kt +28 -0
  72. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/OpenNotifications.kt +28 -0
  73. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/PerformAction.kt +42 -0
  74. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/PerformAutofillDismissal.kt +31 -0
  75. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/PerformEditorAction.kt +30 -0
  76. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/PointerEventHandler.kt +281 -0
  77. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/PressKeyCode.kt +90 -0
  78. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/RegisterIdlingResources.kt +33 -0
  79. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/ReleaseActions.kt +41 -0
  80. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/RequestHandler.kt +43 -0
  81. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/ScreenshotHandler.kt +29 -0
  82. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/ScrollToPage.kt +60 -0
  83. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/SetClipboard.kt +64 -0
  84. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/SetDate.kt +41 -0
  85. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/SetOrientation.kt +61 -0
  86. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/SetRotation.kt +46 -0
  87. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/SetTime.kt +41 -0
  88. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/Source.kt +29 -0
  89. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/StartActivity.kt +30 -0
  90. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/StartService.kt +40 -0
  91. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/Status.kt +26 -0
  92. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/StopService.kt +37 -0
  93. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/Text.kt +28 -0
  94. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/TouchAction.kt +49 -0
  95. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/Uiautomator.kt +68 -0
  96. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/UiautomatorPageSource.kt +35 -0
  97. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/UnregisterIdlingResources.kt +33 -0
  98. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/UpdateSettings.kt +35 -0
  99. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/WebAtoms.kt +69 -0
  100. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/exceptions/AppiumException.kt +40 -0
  101. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/exceptions/DuplicateRouteException.kt +22 -0
  102. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/exceptions/ElementNotVisibleException.kt +30 -0
  103. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/exceptions/InvalidArgumentException.kt +35 -0
  104. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/exceptions/InvalidElementStateException.kt +41 -0
  105. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/exceptions/InvalidSelectorException.kt +35 -0
  106. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/exceptions/MoveTargetOutOfBoundsException.kt +39 -0
  107. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/exceptions/NoAlertOpenException.kt +33 -0
  108. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/exceptions/NoSuchDriverException.kt +31 -0
  109. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/exceptions/NoSuchElementException.kt +34 -0
  110. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/exceptions/NotYetImplementedException.kt +33 -0
  111. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/exceptions/ScreenCaptureException.kt +30 -0
  112. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/exceptions/SessionNotCreatedException.kt +34 -0
  113. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/exceptions/StaleElementException.kt +30 -0
  114. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/exceptions/XPathLookupException.kt +31 -0
  115. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/AccessibilityServiceState.kt +15 -0
  116. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/ActivityHelpers.kt +125 -0
  117. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/ActivityOptionsHelpers.kt +60 -0
  118. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/AlertHelpers.kt +170 -0
  119. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/AndroidLogger.kt +45 -0
  120. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/AssertHelpers.kt +17 -0
  121. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/AutofillHelpers.kt +44 -0
  122. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/BackdoorUtils.java +49 -0
  123. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/ClipboardHelper.kt +51 -0
  124. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/ComposeNodeFinder.kt +59 -0
  125. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/DeviceInfoHelper.kt +148 -0
  126. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/EspressoViewsCache.kt +57 -0
  127. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/GsonParserHelpers.kt +72 -0
  128. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/IMEHelpers.kt +88 -0
  129. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/IntentHelpers.kt +336 -0
  130. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/InteractionHelper.kt +40 -0
  131. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/InvocationOperation.java +80 -0
  132. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/LocaleHelpers.kt +46 -0
  133. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/Logger.kt +25 -0
  134. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/NotificationListener.kt +87 -0
  135. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/Rect.kt +22 -0
  136. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/ReflectionUtils.kt +64 -0
  137. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/ScreenshotsHelper.kt +59 -0
  138. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/StringHelpers.kt +42 -0
  139. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/ThreadHelpers.kt +15 -0
  140. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/UiAutomationWrapper.kt +48 -0
  141. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/ViewFinder.kt +316 -0
  142. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/XMLHelpers.kt +56 -0
  143. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/extensions/Semaphore.kt +22 -0
  144. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/reflection/ArrayUtils.java +110 -0
  145. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/reflection/ClassUtils.java +180 -0
  146. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/reflection/MethodUtils.java +155 -0
  147. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/reflection/Validate.java +34 -0
  148. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/adapter/BaseW3CActionAdapter.kt +71 -0
  149. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/adapter/DummyW3CActionAdapter.kt +133 -0
  150. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/adapter/W3CActionAdapter.kt +71 -0
  151. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/adapter/espresso/AndroidKeyEvent.kt +271 -0
  152. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/adapter/espresso/AndroidMotionEvent.kt +90 -0
  153. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/adapter/espresso/EspressoW3CActionAdapter.kt +147 -0
  154. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/adapter/espresso/Helpers.kt +71 -0
  155. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/adapter/espresso/MotionEventBuilder.kt +153 -0
  156. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/adapter/espresso/MultiTouchState.kt +132 -0
  157. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/adapter/espresso/TouchState.kt +7 -0
  158. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/caps/CapsUtils.kt +96 -0
  159. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/dispatcher/BaseDispatchResult.kt +14 -0
  160. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/dispatcher/DispatchPointerMoveResult.kt +22 -0
  161. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/dispatcher/KeyDispatch.kt +151 -0
  162. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/dispatcher/PointerDispatch.kt +286 -0
  163. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/dispatcher/W3CKeyEvent.kt +21 -0
  164. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/dispatcher/constants/KeyCodeMapper.kt +169 -0
  165. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/dispatcher/constants/KeyLocationMapper.kt +50 -0
  166. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/dispatcher/constants/KeyNormalizer.kt +84 -0
  167. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/dispatcher/constants/NormalizedKeys.kt +60 -0
  168. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/models/ActionObject.kt +138 -0
  169. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/models/ActionSequence.kt +112 -0
  170. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/models/Actions.kt +89 -0
  171. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/models/InputSource.kt +173 -0
  172. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/models/Origin.kt +24 -0
  173. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/models/OriginDeserializer.kt +25 -0
  174. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/models/Tick.kt +62 -0
  175. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/processor/ActionsProcessor.kt +93 -0
  176. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/processor/KeyProcessor.kt +57 -0
  177. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/processor/PauseProcessor.kt +59 -0
  178. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/processor/PointerProcessor.kt +115 -0
  179. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/processor/ProcessorHelpers.kt +35 -0
  180. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/state/ActiveInputSources.kt +62 -0
  181. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/state/InputState.kt +6 -0
  182. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/state/InputStateTable.kt +95 -0
  183. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/state/KeyInputState.kt +82 -0
  184. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/w3c/state/PointerInputState.kt +45 -0
  185. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/http/RouteDefinition.kt +67 -0
  186. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/http/RouteMap.kt +51 -0
  187. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/http/Router.kt +250 -0
  188. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/http/Server.kt +109 -0
  189. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/http/response/AppiumResponse.kt +61 -0
  190. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/http/response/BaseResponse.kt +25 -0
  191. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/AlertParams.kt +21 -0
  192. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/AppiumParams.kt +55 -0
  193. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/BackdoorMethodArg.kt +3 -0
  194. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/ClipboardDataType.kt +18 -0
  195. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/DrawerActionParams.kt +21 -0
  196. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/EditorActionParams.kt +21 -0
  197. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/Element.kt +169 -0
  198. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/GetClipboardParams.kt +27 -0
  199. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/GlobalSession.kt +64 -0
  200. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/HamcrestMatcher.kt +144 -0
  201. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/IdlingResourcesParams.kt +66 -0
  202. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/KeyEventParams.kt +23 -0
  203. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/LocaleParams.kt +34 -0
  204. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/Location.kt +19 -0
  205. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/Locator.kt +22 -0
  206. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/MatcherJson.kt +37 -0
  207. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/MobileBackdoorMethod.kt +22 -0
  208. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/MobileBackdoorParams.kt +20 -0
  209. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/MobileClickActionParams.kt +81 -0
  210. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/MobileSwipeParams.kt +106 -0
  211. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/MotionEventParams.kt +37 -0
  212. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/MoveToParams.kt +26 -0
  213. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/MultiTouchActionsParams.kt +5 -0
  214. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/NavigateToParams.kt +21 -0
  215. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/OrientationParams.kt +21 -0
  216. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/OrientationType.kt +6 -0
  217. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/Rect.kt +24 -0
  218. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/RotationParams.kt +38 -0
  219. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/ScrollToPageParams.kt +36 -0
  220. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/SessionParams.kt +23 -0
  221. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/SetClipboardParams.kt +29 -0
  222. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/SetDateParams.kt +23 -0
  223. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/SetTimeParams.kt +22 -0
  224. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/SettingsParams.kt +19 -0
  225. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/Size.kt +22 -0
  226. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/SourceDocument.kt +286 -0
  227. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/StartActivityParams.kt +9 -0
  228. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/StartServiceParams.kt +22 -0
  229. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/StopServiceParams.kt +21 -0
  230. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/Strategy.kt +49 -0
  231. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/TextValueParams.kt +6 -0
  232. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/ToastLookupParams.kt +22 -0
  233. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/TouchAction.kt +178 -0
  234. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/TouchActionsParams.kt +5 -0
  235. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/UiautomatorParams.kt +123 -0
  236. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/ViewAttributesEnum.kt +51 -0
  237. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/ViewElement.kt +204 -0
  238. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/ViewFlashParams.kt +9 -0
  239. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/ViewText.kt +12 -0
  240. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/WindowRect.kt +24 -0
  241. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/WindowSize.kt +22 -0
  242. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/settings/AbstractSetting.kt +23 -0
  243. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/settings/DriverSetting.kt +40 -0
  244. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/settings/SettingType.kt +21 -0
  245. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/web/WebAtom.kt +26 -0
  246. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/web/WebAtomDeserializer.kt +99 -0
  247. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/web/WebAtomsMethods.kt +4 -0
  248. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/model/web/WebAtomsParams.kt +9 -0
  249. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/viewaction/OrientationChange.kt +47 -0
  250. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/viewaction/ScrollTo.kt +48 -0
  251. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/viewaction/UiControllerPerformer.kt +67 -0
  252. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/viewaction/UiControllerRunnable.kt +25 -0
  253. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/viewaction/ViewGetter.kt +79 -0
  254. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/viewaction/ViewTextGetter.kt +31 -0
  255. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/viewmatcher/RegexpTextMatcher.kt +38 -0
  256. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/viewmatcher/WithView.kt +33 -0
  257. package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/viewmatcher/WithXPath.kt +55 -0
  258. package/espresso-server/app/src/main/AndroidManifest.xml +7 -0
  259. package/espresso-server/app/src/test/java/io/appium/espressoserver/test/assets/Helpers.kt +20 -0
  260. package/espresso-server/app/src/test/java/io/appium/espressoserver/test/assets/backdoor-methods.json +51 -0
  261. package/espresso-server/app/src/test/java/io/appium/espressoserver/test/assets/key-actions.json +15 -0
  262. package/espresso-server/app/src/test/java/io/appium/espressoserver/test/assets/multi-touch-actions.json +28 -0
  263. package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/GsonParserHelpersTest.kt +41 -0
  264. package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/IntentCreationTests.kt +115 -0
  265. package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/InvocationOperationTest.java +97 -0
  266. package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/KReflectionUtilsTest.kt +108 -0
  267. package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/XpathQueryParserTests.kt +42 -0
  268. package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/w3c/ActionSequenceTest.kt +220 -0
  269. package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/w3c/ActionsTest.kt +76 -0
  270. package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/w3c/CapsUtilsTest.kt +76 -0
  271. package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/w3c/Helpers.kt +7 -0
  272. package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/w3c/InputSourceTest.kt +153 -0
  273. package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/w3c/InputStateTableTest.kt +72 -0
  274. package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/w3c/KeyDispatchTest.kt +133 -0
  275. package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/w3c/KeyInputStateTest.kt +74 -0
  276. package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/w3c/PointerDispatchTest.kt +370 -0
  277. package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/w3c/ProcessorTest.kt +320 -0
  278. package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/w3c/TickTest.kt +265 -0
  279. package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/w3c/adapter/AndroidKeyEventTest.kt +114 -0
  280. package/espresso-server/app/src/test/java/io/appium/espressoserver/test/helpers/w3c/adapter/HelpersTest.kt +31 -0
  281. package/espresso-server/app/src/test/java/io/appium/espressoserver/test/http/RouteDefinitionTest.kt +74 -0
  282. package/espresso-server/app/src/test/java/io/appium/espressoserver/test/model/HamcrestMatcherTest.kt +112 -0
  283. package/espresso-server/app/src/test/java/io/appium/espressoserver/test/model/MatcherJsonTest.kt +20 -0
  284. package/espresso-server/app/src/test/java/io/appium/espressoserver/test/model/MobileBackdoorMethodTest.java +110 -0
  285. package/espresso-server/app/src/test/java/io/appium/espressoserver/test/model/MobileClickTest.kt +46 -0
  286. package/espresso-server/app/src/test/java/io/appium/espressoserver/test/model/MobileSwipeTest.kt +68 -0
  287. package/espresso-server/app/src/test/java/io/appium/espressoserver/test/model/TouchActionTest.kt +56 -0
  288. package/espresso-server/app/src/test/java/io/appium/espressoserver/test/model/web/WebAtomTest.kt +68 -0
  289. package/espresso-server/app/src/test/java/io/appium/espressoserver/test/model/web/WebAtomsTest.kt +96 -0
  290. package/espresso-server/build.gradle.kts +33 -0
  291. package/espresso-server/gradle/wrapper/gradle-wrapper.jar +0 -0
  292. package/espresso-server/gradle/wrapper/gradle-wrapper.properties +5 -0
  293. package/espresso-server/gradle.properties +26 -0
  294. package/espresso-server/gradlew +185 -0
  295. package/espresso-server/gradlew.bat +89 -0
  296. package/espresso-server/lint.xml +4 -0
  297. package/espresso-server/settings.gradle.kts +1 -0
  298. package/index.js +29 -0
  299. package/lib/commands/execute.js +72 -0
  300. package/lib/commands/general.js +321 -0
  301. package/lib/commands/idling-resources.js +52 -0
  302. package/lib/commands/index.js +16 -0
  303. package/lib/commands/services.js +50 -0
  304. package/lib/desired-caps.js +55 -0
  305. package/lib/driver.js +566 -0
  306. package/lib/espresso-runner.js +340 -0
  307. package/lib/logger.js +6 -0
  308. package/lib/server-builder.js +194 -0
  309. package/lib/server.js +18 -0
  310. package/lib/utils.js +74 -0
  311. 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,6 @@
1
+ import { logger } from 'appium-support';
2
+
3
+
4
+ const log = logger.getLogger('Espresso');
5
+
6
+ export default log;
@@ -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 };