From a38e9db93e694be2ff220688d1619acd44f18841 Mon Sep 17 00:00:00 2001 From: Nikita Evdokimov Date: Fri, 13 Jan 2023 16:27:36 +0300 Subject: [PATCH 1/2] TECH: fix some tests --- .../device/permissions/HackPermissions.kt | 2 ++ .../device/permissions/HackPermissionsImpl.kt | 6 ++++++ .../kaspresso/docloc/SystemLanguage.kt | 4 ++++ .../kaspersky/kaspresso/kaspresso/Kaspresso.kt | 3 ++- .../device_tests/DeviceAppSampleTest.kt | 8 +++++++- .../device_tests/DeviceLanguageSampleTest.kt | 9 +++++++-- .../device_tests/DeviceLocationSampleTest.kt | 3 ++- .../device_tests/DeviceLogcatSampleTest.kt | 7 ++++++- .../device_tests/DevicePhoneSampleTest.kt | 4 ++-- .../docloc_tests/ScreenshotSampleTest.kt | 10 +++++++++- .../flaky_tests/UiCommonFlakyTest.kt | 2 +- .../measure_tests/KautomatorMeasureTest.kt | 4 ++-- .../sanity/docloc/DocLocSanityTest.kt | 18 +++++++++++------- .../src/main/res/values/strings.xml | 6 +++--- 14 files changed, 64 insertions(+), 22 deletions(-) diff --git a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/device/permissions/HackPermissions.kt b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/device/permissions/HackPermissions.kt index 0ab3e117d..39c5fac8c 100644 --- a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/device/permissions/HackPermissions.kt +++ b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/device/permissions/HackPermissions.kt @@ -10,4 +10,6 @@ interface HackPermissions { */ @Deprecated("Private API usage is forbidden when targeting API 30 and above") fun grant(packageName: String, permission: String): Boolean + + fun grantThroughAdb(packageName: String, permission: String) } diff --git a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/device/permissions/HackPermissionsImpl.kt b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/device/permissions/HackPermissionsImpl.kt index 36128185c..09a70eb7c 100644 --- a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/device/permissions/HackPermissionsImpl.kt +++ b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/device/permissions/HackPermissionsImpl.kt @@ -3,6 +3,7 @@ package com.kaspersky.kaspresso.device.permissions import android.app.UiAutomation import android.os.Process import android.os.UserHandle +import com.kaspersky.kaspresso.device.server.AdbServer import com.kaspersky.kaspresso.instrumental.InstrumentalDependencyProvider import com.kaspersky.kaspresso.logger.UiTestLogger @@ -12,6 +13,7 @@ import com.kaspersky.kaspresso.logger.UiTestLogger class HackPermissionsImpl( private val logger: UiTestLogger, private val instrumentalDependencyProvider: InstrumentalDependencyProvider, + private val adbServer: AdbServer ) : HackPermissions { private val uiAutomation: UiAutomation @@ -39,4 +41,8 @@ class HackPermissionsImpl( false } } + + override fun grantThroughAdb(packageName: String, permission: String) { + adbServer.performShell("pm grant $packageName $permission") + } } diff --git a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/docloc/SystemLanguage.kt b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/docloc/SystemLanguage.kt index fe966aa3c..99f818f16 100644 --- a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/docloc/SystemLanguage.kt +++ b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/docloc/SystemLanguage.kt @@ -52,6 +52,10 @@ internal class SystemLanguage( } val attemptToGrantPermissionResult = hackPermissions.grant(context.packageName, Manifest.permission.CHANGE_CONFIGURATION) if (!attemptToGrantPermissionResult) { + hackPermissions.grantThroughAdb(context.packageName, Manifest.permission.CHANGE_CONFIGURATION) + } + + if (PackageManager.PERMISSION_GRANTED != context.checkPermission(Manifest.permission.CHANGE_CONFIGURATION, Process.myPid(), Process.myUid())) { throw DocLocException( "SystemLanguage: The attempt to grant Manifest.permission.CHANGE_CONFIGURATION for SystemLanguage failed" ) diff --git a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/kaspresso/Kaspresso.kt b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/kaspresso/Kaspresso.kt index 557e1db8d..fd8faaa1d 100644 --- a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/kaspresso/Kaspresso.kt +++ b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/kaspresso/Kaspresso.kt @@ -714,7 +714,8 @@ data class Kaspresso( ) if (!::hackPermissions.isInitialized) hackPermissions = HackPermissionsImpl( libLogger, - instrumentalDependencyProviderFactory.getComponentProvider(instrumentation) + instrumentalDependencyProviderFactory.getComponentProvider(instrumentation), + adbServer ) if (!::exploit.isInitialized) exploit = ExploitImpl( libLogger, diff --git a/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/device_tests/DeviceAppSampleTest.kt b/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/device_tests/DeviceAppSampleTest.kt index 48c62dd82..b23ec5ea9 100644 --- a/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/device_tests/DeviceAppSampleTest.kt +++ b/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/device_tests/DeviceAppSampleTest.kt @@ -1,14 +1,17 @@ package com.kaspersky.kaspressample.device_tests import android.Manifest +import android.os.Build import androidx.test.ext.junit.rules.activityScenarioRule import androidx.test.rule.GrantPermissionRule import com.kaspersky.kaspressample.MainActivity +import com.kaspersky.kaspressample.device_tests.DeviceAppSampleTest.Companion.TEST_APK_FILE_RELATIVE_PATH import com.kaspersky.kaspresso.device.apps.Apps import com.kaspersky.kaspresso.device.server.AdbServer import com.kaspersky.kaspresso.testcases.api.testcase.TestCase import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue +import org.junit.Assume.assumeTrue import org.junit.Rule import org.junit.Test @@ -38,7 +41,10 @@ class DeviceAppSampleTest : TestCase() { @Test fun test() { - run { + before { + assumeTrue("Test APK signature fits only API >= 24", Build.VERSION.SDK_INT >= 24) + }.after { + }.run { step("Install hello world apk") { device.apps.install(TEST_APK_FILE_RELATIVE_PATH) assertTrue(isAppInstalled(adbServer, TEST_APK_PACKAGE_NAME)) diff --git a/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/device_tests/DeviceLanguageSampleTest.kt b/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/device_tests/DeviceLanguageSampleTest.kt index b9a8b2a81..d6bc23f74 100644 --- a/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/device_tests/DeviceLanguageSampleTest.kt +++ b/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/device_tests/DeviceLanguageSampleTest.kt @@ -1,14 +1,15 @@ package com.kaspersky.kaspressample.device_tests import android.Manifest +import android.os.Build import androidx.test.ext.junit.rules.activityScenarioRule import androidx.test.rule.GrantPermissionRule import com.kaspersky.kaspressample.MainActivity import com.kaspersky.kaspressample.screen.MainScreen import com.kaspersky.kaspresso.testcases.api.testcase.TestCase -import java.util.Locale import org.junit.Rule import org.junit.Test +import java.util.Locale class DeviceLanguageSampleTest : TestCase() { @@ -30,7 +31,11 @@ class DeviceLanguageSampleTest : TestCase() { @Test fun languageSampleTest() { before { - default = device.targetContext.resources.configuration.locales[0] + default = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){ + device.targetContext.resources.configuration.locales[0] + } else { + device.targetContext.resources.configuration.locale + } }.after { device.language.switchInApp(default) }.run { diff --git a/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/device_tests/DeviceLocationSampleTest.kt b/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/device_tests/DeviceLocationSampleTest.kt index 83916e7be..d968ecdbc 100644 --- a/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/device_tests/DeviceLocationSampleTest.kt +++ b/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/device_tests/DeviceLocationSampleTest.kt @@ -1,6 +1,7 @@ package com.kaspersky.kaspressample.device_tests import android.Manifest +import android.content.Context import android.location.Location import android.location.LocationListener import android.location.LocationManager @@ -54,7 +55,7 @@ class DeviceLocationSampleTest : TestCase() { fun locationSampleTest() { before { device.location.enableGps() - manager = device.targetContext.getSystemService(LocationManager::class.java) + manager = device.targetContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager }.after { device.location.enableGps() }.run { diff --git a/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/device_tests/DeviceLogcatSampleTest.kt b/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/device_tests/DeviceLogcatSampleTest.kt index 87ea39e97..4e0908760 100644 --- a/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/device_tests/DeviceLogcatSampleTest.kt +++ b/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/device_tests/DeviceLogcatSampleTest.kt @@ -1,7 +1,7 @@ package com.kaspersky.kaspressample.device_tests -import androidx.test.ext.junit.rules.activityScenarioRule import android.os.Build +import androidx.test.ext.junit.rules.activityScenarioRule import com.kaspersky.kaspressample.MainActivity import com.kaspersky.kaspresso.device.logcat.LogcatBufferSize import com.kaspersky.kaspresso.testcases.api.testcase.TestCase @@ -18,6 +18,11 @@ class DeviceLogcatSampleTest : TestCase() { @Test fun logcatTest() { + Assume.assumeTrue( + "Logcat can't connect to 'default' buffer on API < 24", + Build.VERSION.SDK_INT >= Build.VERSION_CODES.N + ) + Assume.assumeTrue( "Due to Android 8 bug 'logcat -c' fails. To run this test please use another device", Build.VERSION.SDK_INT != Build.VERSION_CODES.O diff --git a/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/device_tests/DevicePhoneSampleTest.kt b/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/device_tests/DevicePhoneSampleTest.kt index c15338f7b..fe97ba8bb 100644 --- a/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/device_tests/DevicePhoneSampleTest.kt +++ b/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/device_tests/DevicePhoneSampleTest.kt @@ -5,10 +5,10 @@ import android.provider.CallLog import android.provider.Telephony import androidx.test.ext.junit.rules.activityScenarioRule import androidx.test.rule.GrantPermissionRule -import io.github.kakaocup.kakao.screen.Screen import com.kaspersky.kaspressample.device.DeviceSampleActivity import com.kaspersky.kaspresso.testcases.api.testcase.TestCase import com.kaspersky.kaspresso.testcases.core.testcontext.BaseTestContext +import io.github.kakaocup.kakao.screen.Screen import org.junit.Assert.assertEquals import org.junit.Assert.assertNotNull import org.junit.Rule @@ -19,7 +19,7 @@ class DevicePhoneSampleTest : TestCase() { companion object { private const val PHONE_NUMBER = "+79111111111" private const val SMS_MESSAGE_TEXT = "Kaspresso" - private const val CONTENT_UPDATE_DELAY = 1_500L + private const val CONTENT_UPDATE_DELAY = 5_000L private const val CALL_DURATION = 2_000L } diff --git a/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/docloc_tests/ScreenshotSampleTest.kt b/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/docloc_tests/ScreenshotSampleTest.kt index 1938ee26e..b04ca15b8 100644 --- a/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/docloc_tests/ScreenshotSampleTest.kt +++ b/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/docloc_tests/ScreenshotSampleTest.kt @@ -1,11 +1,13 @@ package com.kaspersky.kaspressample.docloc_tests +import android.os.Build import androidx.test.ext.junit.rules.activityScenarioRule import com.kaspersky.kaspressample.screen.SimpleScreen import com.kaspersky.kaspressample.simple.SimpleActivity import com.kaspersky.kaspresso.annotations.ScreenShooterTest import com.kaspersky.kaspresso.testcases.api.testcase.DocLocScreenshotTestCase import io.github.kakaocup.kakao.screen.Screen +import org.junit.Assume import org.junit.Rule import org.junit.Test @@ -20,7 +22,13 @@ class ScreenshotSampleTest : DocLocScreenshotTestCase(locales = "en,ru") { @ScreenShooterTest @Test - fun test() = run { + fun test() = before { + Assume.assumeTrue( + "Due to the bug in the UiAutomation this test doesn't work and API <= 22", + Build.VERSION.SDK_INT >= Build.VERSION_CODES.M + ) + }.after { + }.run { step("1. Launch activity") { activityRule.scenario.onActivity { // Test that screenshot shooter works in app's main thread captureScreenshot("1. Simple screen") diff --git a/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/flaky_tests/UiCommonFlakyTest.kt b/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/flaky_tests/UiCommonFlakyTest.kt index 0217ecb57..f99e19c45 100644 --- a/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/flaky_tests/UiCommonFlakyTest.kt +++ b/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/flaky_tests/UiCommonFlakyTest.kt @@ -47,7 +47,7 @@ class UiCommonFlakyTest : TestCase() { // even UiAutomator is using under the hood =) // the text is changing during 3 seconds // the default value of flaky safety timeout = 10 seconds - hasText(device.targetContext.getString(R.string.common_flaky_final_button).uppercase()) + hasText(device.targetContext.getString(R.string.common_flaky_final_button)) } } } diff --git a/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/measure_tests/KautomatorMeasureTest.kt b/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/measure_tests/KautomatorMeasureTest.kt index 9cc4ac885..e61398550 100644 --- a/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/measure_tests/KautomatorMeasureTest.kt +++ b/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/measure_tests/KautomatorMeasureTest.kt @@ -48,7 +48,7 @@ class KautomatorMeasureTest : TestCase( RANGE.forEach { _ -> button1 { click() - hasText(device.targetContext.getString(R.string.measure_fragment_text_button_1).uppercase()) + hasText(device.targetContext.getString(R.string.measure_fragment_text_button_1)) } } } @@ -59,7 +59,7 @@ class KautomatorMeasureTest : TestCase( RANGE.forEach { index -> button2 { click() - hasText(device.targetContext.getString(R.string.measure_fragment_text_button_2).uppercase()) + hasText(device.targetContext.getString(R.string.measure_fragment_text_button_2)) } textView { hasText( diff --git a/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspresso/sanity/docloc/DocLocSanityTest.kt b/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspresso/sanity/docloc/DocLocSanityTest.kt index b03b1cb92..802347c5e 100644 --- a/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspresso/sanity/docloc/DocLocSanityTest.kt +++ b/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspresso/sanity/docloc/DocLocSanityTest.kt @@ -1,5 +1,6 @@ package com.kaspersky.kaspresso.sanity.docloc +import android.os.Build import androidx.test.ext.junit.rules.activityScenarioRule import com.kaspersky.kaspressample.screen.SimpleScreen import com.kaspersky.kaspressample.simple.SimpleActivity @@ -10,9 +11,9 @@ import com.kaspersky.kaspresso.interceptors.watcher.testcase.impl.screenshot.Tes import com.kaspersky.kaspresso.kaspresso.Kaspresso import com.kaspersky.kaspresso.testcases.api.testcase.DocLocScreenshotTestCase import io.github.kakaocup.kakao.screen.Screen -import org.junit.After import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue +import org.junit.Assume import org.junit.Rule import org.junit.Test import java.io.File @@ -43,18 +44,21 @@ class DocLocSanityTest : DocLocScreenshotTestCase( testRootDirsProvider = resourcesRootDirsProvider } ) { - @After - fun after() { - checkSanity() - // cleanUpScreenshotsDir() - } @get:Rule val activityRule = activityScenarioRule() @ScreenShooterTest @Test - fun test() = run { + fun test() = before { + Assume.assumeTrue( + "Due to the bug in the UiAutomation this test doesn't work and API <= 22", + Build.VERSION.SDK_INT >= Build.VERSION_CODES.M + ) + }.after { + checkSanity() + cleanUpScreenshotsDir() + }.run { step("1. Launch activity") { activityRule.scenario.onActivity { // Test that screenshot shooter works in app's main thread captureScreenshot("1. Simple screen") diff --git a/samples/kaspresso-sample/src/main/res/values/strings.xml b/samples/kaspresso-sample/src/main/res/values/strings.xml index d0404659f..ba0413b91 100644 --- a/samples/kaspresso-sample/src/main/res/values/strings.xml +++ b/samples/kaspresso-sample/src/main/res/values/strings.xml @@ -26,8 +26,8 @@ Measure Fragment - Button 1 - Button 2 + BUTTON 1 + BUTTON 2 Button_2 clicks count = Some text Checkbox @@ -53,7 +53,7 @@ TextView - Button + BUTTON 1 2 3 From 607dbc9c4f5c3a4c85ecaf1dbd57b4bd759186f8 Mon Sep 17 00:00:00 2001 From: Nikita Evdokimov Date: Fri, 13 Jan 2023 17:58:53 +0300 Subject: [PATCH 2/2] TECH: lint (githooks won't let me squash) --- .../kaspressample/device_tests/DeviceLanguageSampleTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/device_tests/DeviceLanguageSampleTest.kt b/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/device_tests/DeviceLanguageSampleTest.kt index d6bc23f74..d9b587ee5 100644 --- a/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/device_tests/DeviceLanguageSampleTest.kt +++ b/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/device_tests/DeviceLanguageSampleTest.kt @@ -31,7 +31,7 @@ class DeviceLanguageSampleTest : TestCase() { @Test fun languageSampleTest() { before { - default = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){ + default = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { device.targetContext.resources.configuration.locales[0] } else { device.targetContext.resources.configuration.locale