Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue/242-3 #286

Merged
merged 50 commits into from
Oct 12, 2021
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
1e206b7
Add dependencies for JVM tests as well as a sharedTest
sergio-sastre Jul 13, 2021
68a7ec4
Update libs.version.toml
sergio-sastre Jul 17, 2021
fabcde1
Add KautomatorConfig
sergio-sastre Jul 17, 2021
b23339e
Update Kaspresso to use KautomatorConfig
sergio-sastre Jul 17, 2021
fc98114
Handle Device? as optional
sergio-sastre Jul 17, 2021
c2a5edf
Add Shared test that can run as Instrumentation and JVM test
sergio-sastre Jul 17, 2021
5d5f35c
Update all tests depending on Device since it is optional now
sergio-sastre Jul 17, 2021
373047e
Rename and restructure SharedTest files
sergio-sastre Jul 17, 2021
2863b2b
Add SharedTest documentation to wiki
sergio-sastre Jul 17, 2021
35eea62
Better exception message for using Kautomator in sharedTest
sergio-sastre Aug 25, 2021
0bef09c
Remove Nitrogen from the documentation and small docu fix regarding t…
sergio-sastre Aug 25, 2021
09818c8
Revert Device as Optional -> Device?
sergio-sastre Aug 25, 2021
63853f3
restructure uiDeviceConfig classes
sergio-sastre Aug 25, 2021
63499fc
Throw exceptions If using device in shared tests
sergio-sastre Aug 25, 2021
4cc9c1a
Update docu with error handling
sergio-sastre Aug 25, 2021
ef6abc6
Make uiDevice a variable with get()
sergio-sastre Sep 28, 2021
601239b
Merge pull request #1 from KasperskyLab/master
sergio-sastre Oct 1, 2021
3ae9ad8
Solve conflicts with allure support
sergio-sastre Oct 1, 2021
edb2c17
Allow take videos/screenshot & dump view hierarchy be compatible with…
sergio-sastre Oct 1, 2021
e465fd2
Update FailingKautomatorSharedTest.kt
sergio-sastre Oct 1, 2021
e4dcac4
KautomatorInSharedTestException expected only when running on JVM
sergio-sastre Oct 1, 2021
d8e4a6b
issue #242. Removed duplicated code in kaspresso.gradle
matzuk Oct 3, 2021
3063a05
issue #242. Removed needless Kakao dependency for UnitTests in kaspre…
matzuk Oct 3, 2021
d636a4d
issue #242. Robolectric support (version #3)
matzuk Oct 5, 2021
cb613d0
issue #242. Wiki for Robolectric feature
matzuk Oct 5, 2021
05a0cb3
Merge remote-tracking branch 'upstream-2/master' into issue/242
matzuk Oct 5, 2021
4aa99c4
issue #242. merge
matzuk Oct 5, 2021
c2a55f3
Merge remote-tracking branch 'upstream-2/master' into issue/242-3
matzuk Oct 7, 2021
653974d
issue #242. timeout to check flakySafety on the JVM was added
matzuk Oct 7, 2021
9eeaf4d
issue #242. review fixes
matzuk Oct 7, 2021
b0d1617
issue #242. Environment detector has been refactored
matzuk Oct 7, 2021
467feea
issue #242. detekt fixes
matzuk Oct 7, 2021
bef60ff
issue #242. detekt fixes 2
matzuk Oct 7, 2021
cc8a3f9
issue #242. detekt fixes 3
matzuk Oct 7, 2021
d87599c
issue #242. detekt fixes 4
matzuk Oct 7, 2021
b4ecd08
issue #242. up Robolectric version
matzuk Oct 7, 2021
0ce918f
issue #242. fixed shared tests
matzuk Oct 7, 2021
aa77122
issue #242. rollback Robolectric version to 4.5.1 because 4.6.1 cause…
matzuk Oct 7, 2021
b0562a6
Update allure-support/src/main/kotlin/com/kaspersky/components/allure…
matzuk Oct 8, 2021
e2e6b24
Update allure-support/src/main/kotlin/com/kaspersky/components/allure…
matzuk Oct 8, 2021
e1dcea5
Update allure-support/src/main/kotlin/com/kaspersky/components/allure…
matzuk Oct 8, 2021
6da86b0
Update allure-support/src/main/kotlin/com/kaspersky/components/allure…
matzuk Oct 8, 2021
4954ce6
Update kaspresso/src/main/kotlin/com/kaspersky/kaspresso/instrumental…
matzuk Oct 8, 2021
9f459ba
issue #242. Tests checking Robolectric fails were relocated to clean …
matzuk Oct 8, 2021
575f20e
issue #242. Updated tests
matzuk Oct 8, 2021
0a2366d
issue #242. Generics in InstrumentalDepAssisFactory
matzuk Oct 8, 2021
c00c58b
issue #242. Review fixes
matzuk Oct 8, 2021
2013593
issue #242. isAndroidRuntime is removed from TestContext
matzuk Oct 8, 2021
2552e7b
issue #242. review fixes
matzuk Oct 8, 2021
808dd2d
issue #242. review fixes
matzuk Oct 8, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,37 @@ import com.kaspersky.components.alluresupport.interceptors.testrun.ScreenshotTes
import com.kaspersky.components.alluresupport.interceptors.testrun.VideoRecordingTestInterceptor
import com.kaspersky.kaspresso.kaspresso.Kaspresso

/**
* Kaspresso Builder that includes all appropriate interceptors to support rich Allure reports.
*
* A little note. If a test is executing in JVM (with Robolectric) environment then mentioned above interceptors are not including to prevent crashes.
* Sure, Allure reports don't have any sense in non Instrumental environment.
matzuk marked this conversation as resolved.
Show resolved Hide resolved
*/
fun Kaspresso.Builder.Companion.withAllureSupport(
customize: Kaspresso.Builder.() -> Unit = {}
): Kaspresso.Builder = simple(customize).addAllureSupport()

/**
* Kaspresso Builder that includes all appropriate interceptors to support rich Allure reports.
*
* A little note. If a test is executing in JVM (with Robolectric) environment then mentioned above interceptors are not including to prevent crashes.
* Sure, Allure reports don't have any sense in non Instrumental environment.
matzuk marked this conversation as resolved.
Show resolved Hide resolved
*/
fun Kaspresso.Builder.addAllureSupport(): Kaspresso.Builder = apply {
stepWatcherInterceptors.addAll(
listOf(
ScreenshotStepInterceptor(screenshots),
AllureMapperStepInterceptor()
if (isInstrumentalEnvironment) {
stepWatcherInterceptors.addAll(
listOf(
ScreenshotStepInterceptor(screenshots),
AllureMapperStepInterceptor()
)
)
)
testRunWatcherInterceptors.addAll(
listOf(
ScreenshotTestInterceptor(screenshots),
VideoRecordingTestInterceptor(videos),
DumpLogcatTestInterceptor(logcatDumper),
DumpViewsTestInterceptor(viewHierarchyDumper)
testRunWatcherInterceptors.addAll(
listOf(
ScreenshotTestInterceptor(screenshots),
VideoRecordingTestInterceptor(videos),
DumpLogcatTestInterceptor(logcatDumper),
DumpViewsTestInterceptor(viewHierarchyDumper)
)
)
)
}
}
8 changes: 6 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,15 @@ espressoCore = { module = "androidx.test.espresso:espresso-core", version.ref =
espressoWeb = { module = "androidx.test.espresso:espresso-web", version.ref = "espresso" }
testCore = "androidx.test:core:1.3.0"
uiAutomator = "androidx.test.uiautomator:uiautomator:2.2.0"
fragmentTesting = "androidx.fragment:fragment-testing:1.3.2"
robolectric = "org.robolectric:robolectric:4.5.1"

androidXCore = "androidx.core:core:1.3.1"
androidXCore = "androidx.core:core:1.3.0"
androidXRules = "androidx.test:rules:1.3.0"
androidXTest = "androidx.test.ext:junit:1.1.2"
androidXTestKtx = "androidx.test.ext:junit-ktx:1.1.2"

appcompat = "androidx.appcompat:appcompat:1.2.0"
appcompat = "androidx.appcompat:appcompat:1.3.0"
material = "com.google.android.material:material:1.2.0"
constraint = "androidx.constraintlayout:constraintlayout:2.0.0"

Expand Down
7 changes: 0 additions & 7 deletions kaspresso/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,6 @@ dependencies {
api(libs.androidXCore)
api(libs.androidXRules)

api(projects.kautomator)
matzuk marked this conversation as resolved.
Show resolved Hide resolved
api(libs.kakao)
api(libs.bundles.espresso)
api(libs.uiAutomator)
api(libs.androidXCore)
api(libs.androidXRules)

implementation(libs.kotlinStdlib)
implementation(libs.gson)
implementation(projects.adbServer.adbserverDevice)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.kaspersky.kaspresso.device

import android.app.Instrumentation
import android.content.Context
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice
import com.kaspersky.kaspresso.device.accessibility.Accessibility
import com.kaspersky.kaspresso.device.activities.Activities
Expand All @@ -17,6 +17,7 @@ import com.kaspersky.kaspresso.device.permissions.HackPermissions
import com.kaspersky.kaspresso.device.permissions.Permissions
import com.kaspersky.kaspresso.device.phone.Phone
import com.kaspersky.kaspresso.device.screenshots.Screenshots
import com.kaspersky.kaspresso.instrumental.InstrumentalDepsAssistant

/**
* The provider of managers for all off-screen work.
Expand Down Expand Up @@ -119,22 +120,25 @@ data class Device(
/**
* Holds the reference to the implementation of [Logcat] interface.
*/
val logcat: Logcat
val logcat: Logcat,

private val instrumentalDepsAssistant: InstrumentalDepsAssistant,

private val instrumentation: Instrumentation
) {
/**
* A not caching property to get [Context].
*/
val context: Context
get() = InstrumentationRegistry.getInstrumentation().context
val context: Context = instrumentation.context

/**
* A not caching property to get target [Context].
*/
val targetContext: Context
get() = InstrumentationRegistry.getInstrumentation().targetContext
val targetContext: Context = instrumentation.targetContext
matzuk marked this conversation as resolved.
Show resolved Hide resolved

/**
* A property to get the instance of [UiDevice].
*/
val uiDevice: UiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
val uiDevice: UiDevice
get() = instrumentalDepsAssistant.uiDevice
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ package com.kaspersky.kaspresso.device.accessibility
import android.annotation.TargetApi
import android.app.UiAutomation
import android.os.Build
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.Configurator
import com.kaspersky.kaspresso.instrumental.InstrumentalDepsAssistant

/**
* The implementation of the [Accessibility] interface.
*/
class AccessibilityImpl : Accessibility {
class AccessibilityImpl(
private val instrumentalDepsAssistant: InstrumentalDepsAssistant
) : Accessibility {

/**
* Enables accessibility. Available since api 24.
Expand All @@ -25,7 +27,7 @@ class AccessibilityImpl : Accessibility {
val flags = UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES
Configurator.getInstance().uiAutomationFlags = flags

InstrumentationRegistry.getInstrumentation()
instrumentalDepsAssistant
.getUiAutomation(UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES)
.executeShellCommand(cmd)
.close()
Expand All @@ -39,7 +41,7 @@ class AccessibilityImpl : Accessibility {
val string = "enabled_accessibility_services"
val cmd = "settings put secure $string null"

InstrumentationRegistry.getInstrumentation()
instrumentalDepsAssistant
.getUiAutomation(UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES)
.executeShellCommand(cmd)
.close()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.kaspersky.kaspresso.device.activities

import android.app.Activity
import android.app.Instrumentation
import android.os.Looper
import androidx.test.internal.runner.junit4.statement.UiThreadStatement
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.runner.lifecycle.ActivityLifecycleMonitorRegistry
import androidx.test.runner.lifecycle.Stage
import com.kaspersky.kaspresso.logger.UiTestLogger
Expand All @@ -14,7 +14,8 @@ import org.junit.Assert
* The implementation of the [Activities] interface.
*/
class ActivitiesImpl(
private val logger: UiTestLogger
private val logger: UiTestLogger,
private val instrumentation: Instrumentation,
matzuk marked this conversation as resolved.
Show resolved Hide resolved
) : Activities {

/**
Expand Down Expand Up @@ -43,7 +44,7 @@ class ActivitiesImpl(
if (isMainThread) {
findResumedActivity()
} else {
InstrumentationRegistry.getInstrumentation().runOnMainSync(findResumedActivity)
instrumentation.runOnMainSync(findResumedActivity)
}

resumedActivity ?: logger.e("No resumed activity found")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.UiSelector
import androidx.test.uiautomator.Until
import com.kaspersky.kaspresso.device.server.AdbServer
import com.kaspersky.kaspresso.instrumental.InstrumentalDepsAssistant
import com.kaspersky.kaspresso.logger.UiTestLogger
import org.hamcrest.CoreMatchers
import org.hamcrest.MatcherAssert
Expand All @@ -20,7 +21,7 @@ import org.junit.Assert
class AppsImpl(
private val logger: UiTestLogger,
private val context: Context,
private val uiDevice: UiDevice,
private val instrumentalDepsAssistant: InstrumentalDepsAssistant,
private val adbServer: AdbServer
) : Apps {

Expand All @@ -29,9 +30,12 @@ class AppsImpl(
const val LAUNCH_APP_TIMEOUT = 5_000L
}

private val uiDevice: UiDevice
get() = instrumentalDepsAssistant.uiDevice
private val chromePackageName: String = "com.android.chrome"

override val targetAppLauncherPackageName: String = uiDevice.launcherPackageName
override val targetAppLauncherPackageName: String
get() = uiDevice.launcherPackageName

override val targetAppPackageName: String = context.packageName

Expand Down Expand Up @@ -91,8 +95,7 @@ class AppsImpl(
* @return a [Boolean] of installation state
*/
override fun isInstalled(packageName: String): Boolean {
val packageManager = context.packageManager
if (packageManager == null) return false
val packageManager = context.packageManager ?: return false
return try {
packageManager.getApplicationInfo(packageName, 0)
true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,20 @@ import androidx.test.espresso.Espresso
import androidx.test.uiautomator.UiDevice
import com.kaspersky.kaspresso.device.activities.Activities
import com.kaspersky.kaspresso.device.server.AdbServer
import com.kaspersky.kaspresso.instrumental.InstrumentalDepsAssistant

/**
* The implementation of the [Exploit] interface.
*/
class ExploitImpl(
private val activities: Activities,
private val uiDevice: UiDevice,
private val instrumentalDepsAssistant: InstrumentalDepsAssistant,
private val adbServer: AdbServer
) : Exploit {

private val uiDevice: UiDevice
get() = instrumentalDepsAssistant.uiDevice

/**
* Toggles the orientation of the device.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,20 @@ package com.kaspersky.kaspresso.device.permissions
import android.app.UiAutomation
import android.os.Process
import android.os.UserHandle
import com.kaspersky.kaspresso.instrumental.InstrumentalDepsAssistant
import com.kaspersky.kaspresso.logger.UiTestLogger

/**
* The implementation of the [HackPermissions] interface.
*/
class HackPermissionsImpl(
private val uiAutomation: UiAutomation,
private val instrumentalDepsAssistant: InstrumentalDepsAssistant,
private val logger: UiTestLogger
) : HackPermissions {

private val uiAutomation: UiAutomation
get() = instrumentalDepsAssistant.uiAutomation

/**
* @return result of operation: true is success, false is something went wrong
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.UiObject
import androidx.test.uiautomator.UiObjectNotFoundException
import androidx.test.uiautomator.UiSelector
import com.kaspersky.kaspresso.instrumental.InstrumentalDepsAssistant
import com.kaspersky.kaspresso.internal.wait.wait
import com.kaspersky.kaspresso.logger.UiTestLogger

Expand All @@ -14,13 +15,15 @@ import com.kaspersky.kaspresso.logger.UiTestLogger
*/
class PermissionsImpl(
private val logger: UiTestLogger,
private val uiDevice: UiDevice
private val instrumentalDepsAssistant: InstrumentalDepsAssistant,
) : Permissions {

private companion object {
private const val DIALOG_TIMEOUT_MS: Long = 3_000
}

private val uiDevice: UiDevice
get() = instrumentalDepsAssistant.uiDevice
private val packageInstallerPackageName =
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P)
"com.android.permissioncontroller"
Expand Down Expand Up @@ -67,7 +70,7 @@ class PermissionsImpl(
/**
* Passes the permission-requesting permissions dialog.
*
* @param buttonResId resource name of permission dialog button
* @param button resource name of permission dialog button
*/
private fun handlePermissionRequest(button: Permissions.Button) {
val uiObjectButton = getPermissionDialogButtonAsUiObject(button)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
package com.kaspersky.kaspresso.device.screenshots.screenshotmaker

import androidx.test.uiautomator.UiDevice
import com.kaspersky.kaspresso.instrumental.InstrumentalDepsAssistant
import com.kaspersky.kaspresso.params.ScreenshotParams
import java.io.File

/**
* Captures spoon-compatible screenshots by uiautomator.
*/
class ExternalScreenshotMaker(
private val device: UiDevice,
private val instrumentalDepsAssistant: InstrumentalDepsAssistant,
private val params: ScreenshotParams = ScreenshotParams()
) : ScreenshotMaker {

private val device: UiDevice
get() = instrumentalDepsAssistant.uiDevice

// Somehow scale param is not used in UiDevice#takeScreenshot method,
// so just using default here
private val scale: Float = 1.0f
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,24 @@ class AdbServerImpl(
}
if (result.status == ExecutorResultStatus.TIMEOUT) {
throw AdbServerException(
"AdbServer. The command=$command was performed with timeout exception. \n" +
"The possible reason (99.9%) is absence of started 'adbserver-desktop.jar'. \n" +
"Please, follow the instruction: \n" +
"1. Find the last 'adbserver-desktop.jar' here - https://github.com/KasperskyLab/Kaspresso/tree/master/artifacts \n" +
"2. Copy 'adbserver-desktop.jar' to your machine. For example, /Users/yuri.gagarin/Desktop/adbserver-desktop.jar. \n" +
"3. Start 'adbserver-desktop.jar' with the command in Terminal - 'java -jar /Users/yuri.gagarin/Desktop/adbserver-desktop.jar"
"""

AdbServer. The command=$command was performed with timeout exception.
There are two possible reasons:

1. The test is executing in JVM (with Robolectric) environment and the test uses AdbServer. But, Unit tests can't use this implementation of AdbServer.
Possible solutions:
1. Rewrite the test and replace/remove a peace of code where AdbServer is called.
matzuk marked this conversation as resolved.
Show resolved Hide resolved
2. Write another implementation of AdbServer.
3. Don't use this test like a JVM(Unit)-test.

2. The second reason is absence of started 'adbserver-desktop.jar'.
Please, follow the instruction to resolve this issue:
1. Find the last 'adbserver-desktop.jar' here - https://github.com/KasperskyLab/Kaspresso/tree/master/artifacts.
2. Copy 'adbserver-desktop.jar' to your machine. For example, /Users/yuri.gagarin/Desktop/adbserver-desktop.jar.
3. Start 'adbserver-desktop.jar' with the command in Terminal - 'java -jar /Users/yuri.gagarin/Desktop/adbserver-desktop.jar

""".trimIndent()
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,20 @@ package com.kaspersky.kaspresso.device.video.recorder

import android.util.Log
import androidx.test.uiautomator.UiDevice
import com.kaspersky.kaspresso.instrumental.InstrumentalDepsAssistant
import com.kaspersky.kaspresso.internal.wait.wait
import com.kaspersky.kaspresso.logger.UiTestLogger
import com.kaspersky.kaspresso.params.VideoParams
import java.io.File

class VideoRecorderImpl(
private val device: UiDevice,
private val instrumentalDepsAssistant: InstrumentalDepsAssistant,
private val logger: UiTestLogger,
private val params: VideoParams
) : VideoRecorder {

private val device: UiDevice
get() = instrumentalDepsAssistant.uiDevice
private var videoRecordingThread: VideoRecordingThread? = null

/**
Expand Down
Loading