Kaspresso icon indicating copy to clipboard operation
Kaspresso copied to clipboard

Images are not being uploaded to the Allure report

Open mathpi314159-fap opened this issue 7 months ago • 3 comments

Describe the bug The report generated by Allure does not contain images for failed tests. I use a custom builder in the tests:

val kaspressoBuilder = Kaspresso.Builder.withForcedAllureSupport().addComposeSupport(
    lateComposeCustomize = { composeBuilder ->
        composeBuilder.semanticsBehaviorInterceptors =
            composeBuilder.semanticsBehaviorInterceptors.filter {
                it !is SystemDialogSafetySemanticsBehaviorInterceptor
            }.toMutableList()
        flakySafetyParams = FlakySafetyParams.custom(timeoutMs = 10_000, intervalMs = 100)
    }
).apply {
    testRunWatcherInterceptors.addAll((listOf(DumpViewsInterceptor(viewHierarchyDumper))))
    screenshotParams = ScreenshotParams(quality = 0)
}

I have granted all the necessary authorizations:

class LoginTest : TestCase(kaspressoBuilder) {

    @get:Rule
    val grantPermissionRule: GrantPermissionRule = GrantPermissionRule.grant(
        android.Manifest.permission.POST_NOTIFICATIONS,
        android.Manifest.permission.READ_EXTERNAL_STORAGE,
        android.Manifest.permission.WRITE_EXTERNAL_STORAGE
    )

    @get:Rule
    val composeTestRule = createAndroidComposeRule(MainActivity::class.java)
...

build.gradle.kts

defaultConfig {
  testInstrumentationRunner = "com.kaspersky.kaspresso.runner.KaspressoRunner"
  testInstrumentationRunnerArguments["clearPackageData"] = "true"
  testInstrumentationRunnerArguments["useTestStorageService"] = "true"
}

After launching, I get the following: Logcat:

java.lang.AssertionError: Assert failed: The component is not displayed!
at androidx.compose.ui.test.AssertionsKt.assertIsDisplayed(Assertions.kt: 34)
at io.github.kakaocup.compose.node.assertion.NodeAssertions$assertIsDisplayed$1.invoke(NodeAssertions.kt: 13)
at io.github.kakaocup.compose.node.assertion.NodeAssertions$assertIsDisplayed$1.invoke(NodeAssertions.kt: 13)
at io.github.kakaocup.compose.intercept.operation.ComposeOperationImplsKt$produceComposeAssertion$1.execute(ComposeOperationImpls.kt: 29)
at io.github.kakaocup.compose.intercept.operation.ComposeOperationImplsKt$produceComposeAssertion$1.execute(ComposeOperationImpls.kt: 26)
at io.github.kakaocup.compose.intercept.interaction.ComposeInteraction.check(ComposeInteraction.kt: 16)
at com.kaspersky.components.composesupport.interceptors.tolibrary.ComposeSemanticsInterceptor$interceptCheck$1.invoke(ComposeSemanticsInterceptor.kt: 29)
at com.kaspersky.components.composesupport.interceptors.tolibrary.ComposeSemanticsInterceptor$interceptCheck$1.invoke(ComposeSemanticsInterceptor.kt: 24)
at com.kaspersky.components.composesupport.autoscroll.SemanticsAutoScrollProviderImpl.withAutoScroll(SemanticsAutoScrollProviderImpl.kt: 27)
at com.kaspersky.components.composesupport.interceptors.behavior.impl.autoscroll.AutoScrollSemanticsBehaviorInterceptor.withAutoScroll(Unknown Source: 12)
at com.kaspersky.components.composesupport.interceptors.behavior.impl.autoscroll.AutoScrollSemanticsBehaviorInterceptor.interceptCheck(AutoScrollSemanticsBehaviorInterceptor.kt: 32)
at com.kaspersky.components.composesupport.interceptors.behavior.impl.autoscroll.AutoScrollSemanticsBehaviorInterceptor.interceptCheck(AutoScrollSemanticsBehaviorInterceptor.kt: 16)
at com.kaspersky.components.composesupport.interceptors.tolibrary.ComposeSemanticsInterceptor$interceptCheck$2$1.invoke(ComposeSemanticsInterceptor.kt: 33)
at com.kaspersky.components.composesupport.interceptors.tolibrary.ComposeSemanticsInterceptor$interceptCheck$2$1.invoke(ComposeSemanticsInterceptor.kt: 33)
at com.kaspersky.kaspresso.elementloader.ElementLoaderProviderImpl.passAction(ElementLoaderProviderImpl.kt: 36)
at com.kaspersky.components.composesupport.interceptors.behavior.impl.elementloader.ElementLoaderSemanticsBehaviorInterceptor.passAction(Unknown Source: 12)
at com.kaspersky.components.composesupport.interceptors.behavior.impl.elementloader.ElementLoaderSemanticsBehaviorInterceptor.interceptCheck(ElementLoaderSemanticsBehaviorInterceptor.kt: 32)
at com.kaspersky.components.composesupport.interceptors.behavior.impl.elementloader.ElementLoaderSemanticsBehaviorInterceptor.interceptCheck(ElementLoaderSemanticsBehaviorInterceptor.kt: 16)
at com.kaspersky.components.composesupport.interceptors.tolibrary.ComposeSemanticsInterceptor$interceptCheck$2$1.invoke(ComposeSemanticsInterceptor.kt: 33)
at com.kaspersky.components.composesupport.interceptors.tolibrary.ComposeSemanticsInterceptor$interceptCheck$2$1.invoke(ComposeSemanticsInterceptor.kt: 33)
at com.kaspersky.kaspresso.flakysafety.algorithm.FlakySafetyAlgorithm.invokeFlakySafely(FlakySafetyAlgorithm.kt: 32)
at com.kaspersky.kaspresso.flakysafety.algorithm.FlakySafetyAlgorithm.invokeFlakySafely$default(FlakySafetyAlgorithm.kt: 22)
at com.kaspersky.kaspresso.flakysafety.FlakySafetyProviderSimpleImpl.flakySafely(FlakySafetyProviderSimpleImpl.kt: 27)
at com.kaspersky.components.composesupport.interceptors.behavior.impl.flakysafety.FlakySafeSemanticsBehaviorInterceptor.flakySafely(Unknown Source: 7)
at com.kaspersky.components.composesupport.interceptors.behavior.impl.flakysafety.FlakySafeSemanticsBehaviorInterceptor.interceptCheck(FlakySafeSemanticsBehaviorInterceptor.kt: 33)
at com.kaspersky.components.composesupport.interceptors.behavior.impl.flakysafety.FlakySafeSemanticsBehaviorInterceptor.interceptCheck(FlakySafeSemanticsBehaviorInterceptor.kt: 16)



at com.kaspersky.components.composesupport.interceptors.tolibrary.ComposeSemanticsInterceptor$interceptCheck$2$1.invoke(ComposeSemanticsInterceptor.kt: 33)
at com.kaspersky.components.composesupport.interceptors.tolibrary.ComposeSemanticsInterceptor.interceptCheck(ComposeSemanticsInterceptor.kt: 35)
at com.kaspersky.components.composesupport.config.ComposeInterceptorsInjector$injectKaspressoInKakaoCompose$1$1$1.invoke(ComposeInterceptorsInjector.kt: 22)
at com.kaspersky.components.composesupport.config.ComposeInterceptorsInjector$injectKaspressoInKakaoCompose$1$1$1.invoke(ComposeInterceptorsInjector.kt: 22)
at io.github.kakaocup.compose.intercept.delegate.Delegate$DefaultImpls.interceptOnCheck(Delegate.kt: 68)
at io.github.kakaocup.compose.intercept.delegate.Delegate$DefaultImpls.interceptCheck$intercept(Delegate.kt: 37)
at io.github.kakaocup.compose.intercept.delegate.Delegate$DefaultImpls.interceptCheck(Delegate.kt: 41)
at io.github.kakaocup.compose.intercept.delegate.Delegate$DefaultImpls.check(Delegate.kt: 26)
at io.github.kakaocup.compose.intercept.delegate.ComposeDelegate.check(ComposeDelegate.kt: 13)
at io.github.kakaocup.compose.intercept.delegate.ComposeDelegate.check(ComposeDelegate.kt: 13)
at io.github.kakaocup.compose.intercept.delegate.ComposeDelegate.check(ComposeDelegate.kt: 34)
at io.github.kakaocup.compose.intercept.delegate.ComposeDelegate.check$default(ComposeDelegate.kt: 30)
at io.github.kakaocup.compose.node.assertion.NodeAssertions$DefaultImpls.assertIsDisplayed(NodeAssertions.kt: 13)
at io.github.kakaocup.compose.node.core.BaseNode.assertIsDisplayed(BaseNode.kt: 15)
at messenger.myproject.screen.WelcomeScreen.clickContinue$lambda$4(WelcomeScreen.kt: 32)
at messenger.myproject.screen.WelcomeScreen.$r8$lambda$BEL - 5jGAHRkWq5iX9DxsJj25HEg(Unknown Source: 0)
at messenger.myproject.screen.WelcomeScreen$$ExternalSyntheticLambda0.invoke(D8$$SyntheticClass: 0)
at io.qameta.allure.kotlin.Allure.step(Allure.kt: 60)
at messenger.myproject.screen.WelcomeScreen.clickContinue(WelcomeScreen.kt: 31)
at messenger.myproject.test.LoginTest.testLoginWithSso$lambda$1$lambda$0(LoginTest.kt: 49)
at messenger.myproject.test.LoginTest.$r8$lambda$ls2WZ_5uYpTebTWz7kfckdgH3g0(Unknown Source: 0)
at messenger.myproject.test.LoginTest$$ExternalSyntheticLambda0.invoke(D8$$SyntheticClass: 0)
at io.github.kakaocup.compose.node.core.KDSL$DefaultImpls.invoke(KDSL.kt: 7)
at io.github.kakaocup.compose.node.core.BaseNode.invoke(BaseNode.kt: 15)
at messenger.myproject.test.LoginTest.testLoginWithSso$lambda$1(LoginTest.kt: 86)
at messenger.myproject.test.LoginTest.$r8$lambda$kV4g7gDSXL0Ky2KAZ_QFZKgB6oA(Unknown Source: 0)
at messenger.myproject.test.LoginTest$$ExternalSyntheticLambda1.invoke(D8$$SyntheticClass: 0)
at io.qameta.allure.kotlin.Allure.step(Allure.kt: 60)
at messenger.myproject.test.LoginTest.testLoginWithSso(LoginTest.kt: 41)
at java.lang.reflect.Method.invoke(Native Method)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java: 59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java: 12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java: 56)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java: 17)
at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java: 54)
at androidx.compose.ui.test.junit4.AndroidComposeTestRule$apply$1$evaluate$1.invoke(AndroidComposeTestRule.android.kt: 295)
at androidx.compose.ui.test.junit4.AndroidComposeTestRule$apply$1$evaluate$1.invoke(AndroidComposeTestRule.android.kt: 295)
at androidx.compose.ui.test.AndroidComposeUiTestEnvironment$AndroidComposeUiTestImpl.withDisposableContent(ComposeUiTest.android.kt: 565)
at androidx.compose.ui.test.AndroidComposeUiTestEnvironment$runTest$1$1$1$1$1$1.invoke(ComposeUiTest.android.kt: 370)


kotlin.io.NoSuchFileException: /data/user / 0 / myproject / files / original_screenshots: The source file doesn't exist.
at kotlin.io.FilesKt__UtilsKt.copyRecursively(Utils.kt: 294)
at kotlin.io.FilesKt__UtilsKt.copyRecursively$default(Utils.kt: 288)
at com.kaspersky.components.alluresupport.results.AllureResultsHack.testRunFinished(AllureResultsHack.kt: 59)
at com.kaspersky.kaspresso.runner.listener.KaspressoRunNotifierImpl.testRunFinished(KaspressoRunNotifier.kt: 73)
at com.kaspersky.kaspresso.runner.listener.SpyRunListener.testRunFinished(SpyRunListener.kt: 92)
at org.junit.runner.notification.SynchronizedRunListener.testRunFinished(SynchronizedRunListener.java: 42)
at org.junit.runner.notification.RunNotifier$2.notifyListener(RunNotifier.java: 103)
at org.junit.runner.notification.RunNotifier$SafeNotifier.run(RunNotifier.java: 72)
at org.junit.runner.notification.RunNotifier.fireTestRunFinished(RunNotifier.java: 100)
at org.junit.runner.JUnitCore.run(JUnitCore.java: 138)
at org.junit.runner.JUnitCore.run(JUnitCore.java: 115)
at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java: 68)
at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java: 59)
at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java: 463)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java: 2361)

I don't know how to solve the problem. kotlin.io.NoSuchFileException: /data/user / 0 / myproject / files / original_screenshots: The source file doesn't exist.

Expected behavior Pictures will be attached to the allure report for failed tests.

Smartphone:

  • kaspresso = "1.6.0"
  • kaspresso-allure-support = "1.6.0"
  • emulator Pixel 4a API 33

mathpi314159-fap avatar Jun 10 '25 08:06 mathpi314159-fap

Quickfix - downgrade to version 1.5.4. Error was created in 1.6.0 because of screenshot diff tests implemented and checking their dir occurs no matter you dont use this tests. Spent much time for that issue because it makes CI tests fail no matter if test was ok. But it can be safely ignored.

Kaspresso team should pay more attention to such weird bugs.

14v avatar Oct 15 '25 11:10 14v

Hi! The message about non existing original_screenshots folder is a separate problem and should not lead to screenshots not being attached to the report. Are "success" screenshots attached to the report? What is the image of the emulator? Would be great if you could provide reproducable sample. Unfortunately, I cannot reproduce this issue

Nikitae57 avatar Oct 15 '25 16:10 Nikitae57

In my case UI tests results screenshots are attached ok. The only issue is exception because at AllureResultsHack.kt:59 there is a reference to non-existent dir original_screenshots dir which used by diff screenshot tests. Diff tests are not used. Exception cause entire test to fail

Setup:

  • Emulator API 36
  • Kaspresso 1.6.0
Kaspresso.Builder
        .withForcedAllureSupport()
        .addComposeSupport()
INSTRUMENTATION_RESULT: stream=
Time: 29.753
There was 1 failure:
1) Test mechanism
kotlin.io.NoSuchFileException: /data/user/0/com.example.app/files/original_screenshots: The source file doesn't exist.
	at kotlin.io.FilesKt__UtilsKt.copyRecursively(Utils.kt:294)
	at kotlin.io.FilesKt__UtilsKt.copyRecursively$default(Utils.kt:288)
	at com.kaspersky.components.alluresupport.results.AllureResultsHack.testRunFinished(AllureResultsHack.kt:59)
	at com.kaspersky.kaspresso.runner.listener.KaspressoRunNotifierImpl.testRunFinished(KaspressoRunNotifier.kt:73)
	at com.kaspersky.kaspresso.runner.listener.SpyRunListener.testRunFinished(SpyRunListener.kt:92)
	at org.junit.runner.notification.SynchronizedRunListener.testRunFinished(SynchronizedRunListener.java:42)
	at org.junit.runner.notification.RunNotifier$2.notifyListener(RunNotifier.java:103)
	at org.junit.runner.notification.RunNotifier$SafeNotifier.run(RunNotifier.java:72)
	at org.junit.runner.notification.RunNotifier.fireTestRunFinished(RunNotifier.java:100)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:138)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
	at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:68)
	at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:59)
	at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:467)
	at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2594)
FAILURES!!!
Tests run: 1,  Failures: 1
INSTRUMENTATION_CODE: -1

14v avatar Oct 16 '25 07:10 14v