appium-espresso-driver 2.13.11 → 2.14.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 +7 -0
- package/README.md +1 -0
- package/espresso-server/app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk +0 -0
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/ElementScreenshot.kt +8 -7
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/ScreenshotHandler.kt +2 -7
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/handlers/exceptions/ScreenCaptureException.kt +5 -1
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/ScreenshotHelpers.kt +59 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/espresso-server/app/src/androidTest/java/io/appium/espressoserver/lib/helpers/ScreenshotsHelper.kt +0 -59
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
## [2.14.0](https://github.com/appium/appium-espresso-driver/compare/v2.13.11...v2.14.0) (2023-01-13)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* Add compose element screenshot ([#847](https://github.com/appium/appium-espresso-driver/issues/847)) ([95bded7](https://github.com/appium/appium-espresso-driver/commit/95bded7e1816eb42ded501efcbca24b07b283f35))
|
|
7
|
+
|
|
1
8
|
## [2.13.11](https://github.com/appium/appium-espresso-driver/compare/v2.13.10...v2.13.11) (2023-01-13)
|
|
2
9
|
|
|
3
10
|
|
package/README.md
CHANGED
|
@@ -202,6 +202,7 @@ In order to change between subdrivers use the [driver](#settings-api) setting. S
|
|
|
202
202
|
- getPageSource: The returned page source is retrieved from Compose and all elements there contain [Compose-specific](#compose-element-attributes) attributes.
|
|
203
203
|
- click, isDisplayed, isEnabled, clear, getText, sendKeys, getElementRect, getValue, isSelected: These commands should properly support compose elements.
|
|
204
204
|
- getAttribute: Accepts and returns Compose-specific element attributes. See [Compose Element Attributes](#compose-element-attributes) for the full list of supported Compose element attributes.
|
|
205
|
+
- getElementScreenshot: Fetches a screenshot of the given Compose element. Available since driver version *2.14.0*
|
|
205
206
|
|
|
206
207
|
Calling other driver element-specific APIs not listed above would most likely throw an exception as Compose and Espresso elements are being stored in completely separated internal caches and must not be mixed.
|
|
207
208
|
|
|
Binary file
|
|
@@ -16,16 +16,17 @@
|
|
|
16
16
|
|
|
17
17
|
package io.appium.espressoserver.lib.handlers
|
|
18
18
|
|
|
19
|
-
import io.appium.espressoserver.lib.
|
|
20
|
-
import io.appium.espressoserver.lib.helpers.
|
|
19
|
+
import io.appium.espressoserver.lib.helpers.getNodeInteractionById
|
|
20
|
+
import io.appium.espressoserver.lib.helpers.takeComposeNodeScreenshot
|
|
21
|
+
import io.appium.espressoserver.lib.helpers.takeEspressoViewScreenshot
|
|
21
22
|
import io.appium.espressoserver.lib.model.AppiumParams
|
|
22
23
|
import io.appium.espressoserver.lib.model.EspressoElement
|
|
23
24
|
|
|
24
25
|
class ElementScreenshot : RequestHandler<AppiumParams, String> {
|
|
25
26
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
override fun handleEspresso(params: AppiumParams): String =
|
|
28
|
+
takeEspressoViewScreenshot(EspressoElement.getCachedViewStateById(params.elementId).view)
|
|
29
|
+
|
|
30
|
+
override fun handleCompose(params: AppiumParams): String =
|
|
31
|
+
takeComposeNodeScreenshot(getNodeInteractionById(params.elementId!!))
|
|
31
32
|
}
|
|
@@ -16,14 +16,9 @@
|
|
|
16
16
|
|
|
17
17
|
package io.appium.espressoserver.lib.handlers
|
|
18
18
|
|
|
19
|
-
import io.appium.espressoserver.lib.
|
|
20
|
-
import io.appium.espressoserver.lib.helpers.ScreenshotsHelper
|
|
19
|
+
import io.appium.espressoserver.lib.helpers.takeScreenshot
|
|
21
20
|
import io.appium.espressoserver.lib.model.AppiumParams
|
|
22
21
|
|
|
23
22
|
class ScreenshotHandler : RequestHandler<AppiumParams, String> {
|
|
24
|
-
|
|
25
|
-
@Throws(AppiumException::class)
|
|
26
|
-
override fun handleInternal(params: AppiumParams): String {
|
|
27
|
-
return ScreenshotsHelper().screenshot
|
|
28
|
-
}
|
|
23
|
+
override fun handleInternal(params: AppiumParams): String = takeScreenshot()
|
|
29
24
|
}
|
|
@@ -19,7 +19,11 @@ package io.appium.espressoserver.lib.handlers.exceptions
|
|
|
19
19
|
import fi.iki.elonen.NanoHTTPD
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
class ScreenCaptureException
|
|
22
|
+
class ScreenCaptureException : AppiumException {
|
|
23
|
+
constructor(reason: String) : super(reason)
|
|
24
|
+
|
|
25
|
+
constructor(reason: String, e: Throwable) : super(reason, e)
|
|
26
|
+
|
|
23
27
|
override fun error(): String {
|
|
24
28
|
return "unable to capture screen"
|
|
25
29
|
}
|
|
@@ -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
|
+
import androidx.compose.ui.graphics.asAndroidBitmap
|
|
23
|
+
import androidx.compose.ui.test.SemanticsNodeInteraction
|
|
24
|
+
import androidx.compose.ui.test.captureToImage
|
|
25
|
+
|
|
26
|
+
import java.io.ByteArrayOutputStream
|
|
27
|
+
import androidx.test.runner.screenshot.Screenshot
|
|
28
|
+
import io.appium.espressoserver.lib.handlers.exceptions.ScreenCaptureException
|
|
29
|
+
|
|
30
|
+
private fun encodeBitmap(bitmap: Bitmap?, targetNameSupplier: () -> String): String {
|
|
31
|
+
if (bitmap == null || bitmap.height == 0 || bitmap.width == 0) {
|
|
32
|
+
throw ScreenCaptureException("Cannot capture a shot of the ${targetNameSupplier()}. " +
|
|
33
|
+
"Make sure none of the currently visible " +
|
|
34
|
+
"views have FLAG_SECURE set and that it is possible to take a screenshot manually")
|
|
35
|
+
}
|
|
36
|
+
val outputStream = ByteArrayOutputStream()
|
|
37
|
+
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
|
|
38
|
+
return Base64.encodeToString(outputStream.toByteArray(), Base64.NO_WRAP)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
fun takeScreenshot(): String {
|
|
42
|
+
return encodeBitmap(Screenshot.capture().bitmap) { "current screen" }
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
fun takeEspressoViewScreenshot(view: View): String =
|
|
46
|
+
try {
|
|
47
|
+
encodeBitmap(Screenshot.capture(view).bitmap) { view.javaClass.name }
|
|
48
|
+
} catch (e: RuntimeException) {
|
|
49
|
+
throw ScreenCaptureException("Cannot take a screenshot of a view", e)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
fun takeComposeNodeScreenshot(nodeInteraction: SemanticsNodeInteraction): String =
|
|
53
|
+
try {
|
|
54
|
+
encodeBitmap(
|
|
55
|
+
nodeInteraction.captureToImage().asAndroidBitmap()
|
|
56
|
+
) { nodeInteraction.fetchSemanticsNode().toString() }
|
|
57
|
+
} catch (e: RuntimeException) {
|
|
58
|
+
throw ScreenCaptureException("Cannot take a screenshot of a node", e)
|
|
59
|
+
}
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "appium-espresso-driver",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.14.0",
|
|
4
4
|
"lockfileVersion": 2,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "appium-espresso-driver",
|
|
9
|
-
"version": "2.
|
|
9
|
+
"version": "2.14.0",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@babel/runtime": "^7.4.3",
|
package/package.json
CHANGED
|
@@ -1,59 +0,0 @@
|
|
|
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.NO_WRAP)
|
|
58
|
-
}
|
|
59
|
-
}
|