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

🔧 By upgrading the version of Compose Multiplatform itself and the accompanying dependencies, we have addressed the issue of fling scrolling not working on iOS in Compose Multiplatform. #984

Conversation

Corvus400
Copy link
Contributor

@Corvus400 Corvus400 commented Sep 6, 2024

Issue

Overview (Required)

  • By upgrading the version of ComposeMultiplatform to 1.7.0-alpha02, fling scrolling will also work correctly in Compose Multiplatform for iOS.
  • For this reason, we have increased the version of Compose Multiplatform.
  • Due to a problem with CMP-6612, VRT will not function as it is.
  • As a result of correspondence with takahirom, it was found that multiple responses were necessary, so we are taking action.

Links

Movie (Optional)

Before After
before.mov
after.mov

…companying dependencies, we have addressed the issue of fling scrolling not working on iOS in Compose Multiplatform.

https://github.com/JetBrains/compose-multiplatform/releases/tag/v1.7.0-alpha02
@github-actions github-actions bot temporarily deployed to deploygate-distribution September 6, 2024 07:53 Inactive
@Corvus400
Copy link
Contributor Author

Task :app-android:testDevDebugUnitTest

KaigiAppTest > runTest[KaigiApp - when app is starting - it should show timetable items] FAILED
java.lang.IllegalStateException: Android context is not initialized. If it happens in the Preview mode then call PreviewContextConfigurationEffect() function.

What is PreviewContextConfigurationEffect...?🤔

@takahirom
Copy link
Member

takahirom commented Sep 6, 2024

I think we can have Composable function something like this.

fun ProvideAndroidContextToComposeResource() {
  ProvideCompositionLocal(LocalInspectionMode to true) {
    PreviewContextConfigurationEffect()
  }
}

And I think we should invoke it here.

https://github.com/DroidKaigi/conference-app-2024/blob/main/core/testing/src/main/java/io/github/droidkaigi/confsched/testing/rules/RobotTestRule.kt#L143

https://github.com/DroidKaigi/conference-app-2024/blob/main/core/testing/src/main/java/io/github/droidkaigi/confsched/testing/DroidKaigiKmpPreviewTester.kt#L30

@takahirom
Copy link
Member

We can refer to this issue.
https://youtrack.jetbrains.com/issue/CMP-6612/Android-context-is-not-initialized-when-retrieving-resources-in-Robolectric-unit-test

@github-actions github-actions bot temporarily deployed to deploygate-distribution September 7, 2024 00:40 Inactive
@Corvus400
Copy link
Contributor Author

@takahirom
Thank you for teaching me! 🙇
When I tried the following, unfortunately, it seemed that the processing would not proceed with scrolling or swipe-type methods. 😭

package io.github.droidkaigi.confsched.testing

import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.platform.LocalInspectionMode

@Composable
fun ProvideAndroidContextToComposeResource(content: @Composable () -> Unit) {
    CompositionLocalProvider(LocalInspectionMode provides true) {
        content()
    }
}
    fun setContent(content: @Composable () -> Unit) {
        val repositoryProvider = EntryPoints.get(
            composeTestRule.activity.application,
            RepositoryProviderEntryPoint::class.java,
        )
            .getRepositoryProvider()
        composeTestRule.setContent {
            repositoryProvider.Provide {
                ProvideAndroidContextToComposeResource {
                    content()
                }
            }
        }
    }
    override fun test(preview: ComposablePreview<JvmAnnotationInfo>) {
        captureRoboImage("${preview.methodName}.png") {
            println(preview.methodName)
            ProvideAndroidContextToComposeResource {
                preview()
            }
        }
    }

@takahirom
Copy link
Member

takahirom commented Sep 7, 2024

I think we need to do it something like this. I think we also need to invoke PreviewContextConfigurationEffect

    override fun test(preview: ComposablePreview<JvmAnnotationInfo>) {
        captureRoboImage("${preview.methodName}.png") {
            println(preview.methodName)
            ProvideAndroidContextToComposeResource()
            preview()
        }
    }

https://github.com/JetBrains/compose-multiplatform/blob/e3a78f3f90b4cb9293dfe3bc1d2e7b94ce317fdf/components/resources/library/src/androidMain/kotlin/org/jetbrains/compose/resources/AndroidContextProvider.kt#L36

@Corvus400
Copy link
Contributor Author

@takahirom
Since you can't directly refer to the PreviewContextConfigurationEffect from the test module, I tried writing the following code temporarily in the model module, etc., but unfortunately, it seems that the scrolling-related test methods will never end. 😭

package io.github.droidkaigi.confsched.model

import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.platform.LocalInspectionMode
import org.jetbrains.compose.resources.ExperimentalResourceApi
import org.jetbrains.compose.resources.PreviewContextConfigurationEffect

@OptIn(ExperimentalResourceApi::class)
@Composable
fun ProvideAndroidContextToComposeResource() {
    CompositionLocalProvider(LocalInspectionMode provides true) {
        PreviewContextConfigurationEffect()
    }
}
    fun setContent(content: @Composable () -> Unit) {
        val repositoryProvider = EntryPoints.get(
            composeTestRule.activity.application,
            RepositoryProviderEntryPoint::class.java,
        )
            .getRepositoryProvider()
        composeTestRule.setContent {
            repositoryProvider.Provide {
                ProvideAndroidContextToComposeResource()
                content()
            }
        }
    }
    override fun test(preview: ComposablePreview<JvmAnnotationInfo>) {
        captureRoboImage("${preview.methodName}.png") {
            println(preview.methodName)
            ProvideAndroidContextToComposeResource()
            preview()
        }
    }

@takahirom
Copy link
Member

takahirom commented Sep 7, 2024

Thanks. Could you remove this and try again? I think we need
to use compose-foundation-1.8.0-alpha-01 to solve the problem.
https://github.com/DroidKaigi/conference-app-2024/blob/main/build.gradle.kts#L30

@Corvus400
Copy link
Contributor Author

@takahirom
Commenting out force(“androidx.compose.foundation:foundation:1.6.8”) did not change the result.
So, I tried changing it to force(“androidx.compose.foundation:foundation:1.8.0-alpha01”), and some tests, such as AboutScreenTest, now pass. 👍

However, it seems that the following errors are still occurring in KaigiAppTest.kt, etc. 🤔

D/LifecycleMonitor: Lifecycle status change: io.github.droidkaigi.confsched.MainActivity@a3a3b34 in: CREATED
V/ActivityScenario: Update currentActivityStage to CREATED, currentActivity=io.github.droidkaigi.confsched.MainActivity@a3a3b34
D/LifecycleMonitor: Lifecycle status change: io.github.droidkaigi.confsched.MainActivity@a3a3b34 in: STARTED
V/ActivityScenario: Update currentActivityStage to STARTED, currentActivity=io.github.droidkaigi.confsched.MainActivity@a3a3b34
D/LifecycleMonitor: Lifecycle status change: io.github.droidkaigi.confsched.MainActivity@a3a3b34 in: RESUMED
V/ActivityScenario: Update currentActivityStage to RESUMED, currentActivity=io.github.droidkaigi.confsched.MainActivity@a3a3b34

Android context is not initialized. If it happens in the Preview mode then call PreviewContextConfigurationEffect() function.
java.lang.IllegalStateException: Android context is not initialized. If it happens in the Preview mode then call PreviewContextConfigurationEffect() function.

@takahirom
Copy link
Member

KaigiAppTest desn't use the setContent and we can't insert the Android context. Do you have any idea to do this? We might have to have another activity to setting the context before the test.

@Corvus400
Copy link
Contributor Author

Corvus400 commented Sep 7, 2024

@takahirom
Once I had created the TestActivity, I thought I would have to keep it the same as the MainActivity's processing at all times, so I created the KaigiAppCompositionLocalProvider as follows and tried to use it in the MainActivity.
The locations(package) are temporary.

It seems that the following issues have been addressed.

  1. Test code with scrolling
  2. Test code that does not use setContent

However, there seems to be a problem with the test for the profile card at the end. 🤔

package io.github.droidkaigi.confsched.model

import android.os.Build
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.ProvidedValue

@Composable
inline fun KaigiAppCompositionLocalProvider(
    locals:ProvidedValue<*>,
    crossinline content: @Composable () -> Unit,
) {
    CompositionLocalProvider(
        locals,
    ) {
        if ("robolectric" == Build.FINGERPRINT) {
            ProvideAndroidContextToComposeResource()
        }
        content()
    }
}
KaigiAppCompositionLocalProvider(
                locals = LocalClock provides clockProvider.clock(),
            ) {
                repositoryProvider.Provide {
                    KaigiApp(
                        windowSize = windowSize,
                        fontFamily = fontFamily,
                        displayFeatures = displayFeatures,
                    )
                }
            }
ProfileCardScreenTest > runTest[ProfileCardScreen - when profile card is exists - it should show card screen] STARTED

ProfileCardScreenTest > runTest[ProfileCardScreen - when profile card is exists - it should show card screen] FAILED
    java.lang.IllegalArgumentException: Software rendering doesn't support drawRenderNode
        at android.graphics.Canvas.drawRenderNode(Canvas.java:2329)
        at androidx.compose.ui.graphics.layer.GraphicsLayerV29.draw(GraphicsLayerV29.android.kt:259)
        at androidx.compose.ui.graphics.layer.GraphicsLayer.draw$ui_graphics_release(AndroidGraphicsLayer.android.kt:536)
        at androidx.compose.ui.graphics.layer.LayerSnapshotV21.toBitmap(LayerSnapshot.android.kt:116)
        at androidx.compose.ui.graphics.layer.GraphicsLayer.toImageBitmap(AndroidGraphicsLayer.android.kt:827)
        at io.github.droidkaigi.confsched.profilecard.component.CaptureableCardFrontKt$BackgroundCapturableCardFront$1$1.invokeSuspend(CaptureableCardFront.kt:45)
        at _COROUTINE._BOUNDARY._(CoroutineDebugging.kt:42)
        at io.github.droidkaigi.confsched.testing.coroutines.RunTestWithLoggingKt$runTestWithLogging$1.invokeSuspend(RunTestWithLogging.kt:17)
        at kotlinx.coroutines.test.TestBuildersKt__TestBuildersKt$runTest$2$1$1.invokeSuspend(TestBuilders.kt:316)

        Caused by:
        java.lang.IllegalArgumentException: Software rendering doesn't support drawRenderNode

@takahirom
Copy link
Member

Although I think there is some room for improvement in the KaigiAppCompositionLocalProvider, I believe it is good to have it in production with isTest().
Could you push the changes you have? For this Software rendering doesn't support drawRenderNode, test.systemProperties["robolectric.pixelCopyRenderMode"] = "hardware" should work.

@Corvus400
Copy link
Contributor Author

Corvus400 commented Sep 7, 2024

@takahirom
I understand. 🫡
Let me check before I start working. 🙇
The current testing module is only the main module, so I think it will be necessary to change to the KMP configuration in order to place the processing to be added this time.
Is it okay to make this change?
I think that it is necessary to change the testing module to a KMP configuration and add androidMain, because it is inappropriate to place the processing that has been added this time in core:model at least.
(The PreviewContextConfigurationEffect can be referenced from androidMain, but not from main.)

スクリーンショット 2024-09-07 15 57 45

@takahirom
Copy link
Member

I'm fine with having PreviewContextConfigurationEffect in the core/droidkaigiui's main or somewhere else.
The testing module is a bit challenging to manage since we could encounter dependencies like this:
feature:session(androidUnitTest sourceset) -> core:testing(main (android) sourceset) -> feature:session(androidMain and commonMain sourceSet).
I think it is okay to make testing module a KMP module, but we might face potential issues with minor use cases.

@Corvus400
Copy link
Contributor Author

@takahirom
I see... At this point, I don't want to embed the possibility of creating a new bug that is difficult to fix, so I will not use the KMP configuration.

@github-actions github-actions bot temporarily deployed to deploygate-distribution September 7, 2024 07:40 Inactive
@Corvus400
Copy link
Contributor Author

@takahirom
Excuse me, let me ask a question. 🙇

For this Software rendering doesn't support drawRenderNode, test.systemProperties[“robolectric.pixelCopyRenderMode”] = “hardware” should work.

This part has already been set in Android/KmpRoborazziPlugin, so there should be no need to add anything in this update, right?

test.systemProperties["robolectric.pixelCopyRenderMode"] =
"hardware"

test.systemProperties["robolectric.pixelCopyRenderMode"] = "hardware"

@takahirom
Copy link
Member

Yes, I think we need to create an issue in the Robolectric repository. But for now, how about using a try-catch block for toBitmap and adding a FIXME comment?

@github-actions github-actions bot temporarily deployed to deploygate-distribution September 7, 2024 09:53 Inactive
Copy link

github-actions bot commented Sep 7, 2024

Snapshot diff report

File name Image
SearchScreenTest[Sea
rchScreen - when ser
ver is operational -
when filter languag
e chip click - it sh
ould show drop down
menu]_compare.png
SearchScreenTest[Sea
rchScreen - when ser
ver is operational -
when filter categor
y chip click - it sh
ould show drop down
menu]_compare.png
TimetableItemDetailS
creenTest[TimetableI
temDetailScreen - wh
en server is operati
onal available both
asset - when launch
- it should display
both assets]_compare
.png
TimetableItemDetailS
creenTest[TimetableI
temDetailScreen - wh
en server is operati
onal available only
slide asset - when l
aunch - it should di
splay only slide ass
ets]_compare.png
TimetableItemDetailS
creenTest[TimetableI
temDetailScreen - wh
en server is operati
onal available only
video asset - when l
aunch - it should on
ly display video ass
ets]_compare.png
TimetableScreenTest[
TimetableScreen - wh
en server is down -
it should show error
message]_compare.pn
g
TimetableItemDetailS
creenTest[TimetableI
temDetailScreen - wh
en server is operati
onal - when launch -
when scroll to bott
om - it should not d
isplay both assets]_
compare.png
SearchScreenTest[Sea
rchScreen - when ser
ver is operational -
when filter day chi
p click - it should
show drop down menu]
_compare.png
TimetableScreenTest[
TimetableScreen - wh
en font scale is lar
ge - it should show
title in a single li
ne]_compare.png
SearchScreenTest[Sea
rchScreen - when dev
ice is tablet - inpu
t search word to Tex
tField - it should s
how search word and
filtered items]_comp
are.png
SponsorsScreenPrevie
w_compare.png
SponsorsScreenTest[S
ponsorsScreen - when
server is operation
al - when launch - w
hen scroll to scroll
Bottom - it should
display supporters s
ponsors]_compare.png
SponsorsScreenTest[S
ponsorsScreen - when
server is operation
al - when launch - i
t should display pla
tinum sponsors]_comp
are.png
SponsorsScreenTest[S
ponsorsScreen - when
server is operation
al - when launch - w
hen scroll to gold s
ponsors header - it
should display gold
sponsors]_compare.pn
g
SponsorsScreenTest[S
ponsorsScreen - when
server is down - wh
en launch - it shoul
d does not show spon
sors and show snackb
ar]_compare.png
StaffScreenTest[Staf
fScreen - when serve
r is operational - w
hen server is down -
when launch - it sh
ould does not show s
taff and show snackb
ar]_compare.png
StaffScreenTest[Staf
fScreen - when serve
r is operational - w
hen launch - when sc
roll to index 10 - i
t should show staffs
]_compare.png
StaffScreenTest[Staf
fScreen - when serve
r is operational - w
hen launch - it shou
ld show first and se
cond staffs]_compare
.png
StaffScreenPreview_c
ompare.png
EventMapScreenTest[E
ventMapScreenRobot -
when server is oper
ational - it should
ensure that the room
types for Giraffe a
re displayed.]_compa
re.png
EventMapScreenTest[E
ventMapScreenRobot -
when server is oper
ational - it should
ensure that the room
types for Hedgehog
are displayed.]_comp
are.png
EventMapScreenTest[E
ventMapScreenRobot -
when server is oper
ational - it should
ensure that the room
types for Flamingo
are displayed.]_comp
are.png
EventMapScreenTest[E
ventMapScreenRobot -
when server is oper
ational - it should
ensure that the room
types for Iguana ar
e displayed.]_compar
e.png
EventMapScreenTest[E
ventMapScreenRobot -
when server is oper
ational - it should
ensure that the room
types for Jellyfish
are displayed.]_com
pare.png
EventMapScreenTest[E
ventMapScreenRobot -
when server is erro
r - it should show e
rror message]_compar
e.png
EventMapScreenPrevie
w_compare.png
ProfileCardScreenTes
t[ProfileCardScreen
- when profile card
is exists - tilt tes
ts - tilt to horizon
tal - it should show
card in horizontal]
_compare.png
ProfileCardScreenTes
t[ProfileCardScreen
- when profile card
is exists - tilt tes
ts - tilt both axes
out of bounds - it s
hould keep last vali
d orientation]_compa
re.png
ProfileCardScreenTes
t[ProfileCardScreen
- when profile card
is exists - tilt tes
ts - tilt roll out o
f bounds - it should
keep last valid rol
l]_compare.png
ProfileCardScreenTes
t[ProfileCardScreen
- when profile card
is exists - when cli
ck edit button - if
all required fields
are filled in - it s
hould make sure the
Create button is act
ivated]_compare.png
ProfileCardScreenTes
t[ProfileCardScreen
- when profile card
is exists - it shoul
d show card screen]_
compare.png
ProfileCardScreenTes
t[ProfileCardScreen
- when profile card
is exists - flip pro
file card - it shoul
d back side of the p
rofile card is displ
ayed]_compare.png
ProfileCardScreenTes
t[ProfileCardScreen
- when profile card
is exists - when cli
ck edit button - whe
n if a required fiel
d has not been fille
d in - it should mak
e sure the Create bu
tton is deactivated]
_compare.png
ProfileCardScreenTes
t[ProfileCardScreen
- when profile card
is exists - tilt tes
ts - tilt to upper b
ound - it should sho
w card at upper boun
d]_compare.png
ProfileCardScreenTes
t[ProfileCardScreen
- when profile card
is exists - tilt tes
ts - tilt pitch out
of bounds - it shoul
d keep last valid pi
tch]_compare.png
ProfileCardScreenTes
t[ProfileCardScreen
- when profile card
is exists - tilt tes
ts - tilt to opposit
e boundary - it shou
ld show card at oppo
site boundary]_compa
re.png
ProfileCardScreenTes
t[ProfileCardScreen
- when profile card
is exists - tilt tes
ts - tilt to mid-ran
ge - it should show
card at mid-range]_c
ompare.png
ProfileCardScreenTes
t[ProfileCardScreen
- when profile card
is exists - tilt tes
ts - tilt to boundar
y - it should show c
ard at boundary]_com
pare.png
SettingsScreenTest[S
ettingsScreen - when
launch use font dot
gothic - when click
use font item - whe
n click dot gothic f
ont - it should sele
cted dot gothic font
]_compare.png
SettingsScreenTest[S
ettingsScreen - when
launch use font dot
gothic - it should
show settings conten
ts]_compare.png
SettingsScreenTest[S
ettingsScreen - when
launch use font dot
gothic - when click
use font item - it
should show availabl
e fonts]_compare.png
SettingsScreenTest[S
ettingsScreen - when
launch use font def
ault system font - w
hen click use font i
tem - when click dot
gothic font - it sh
ould selected dot go
thic font]_compare.p
ng
SettingsScreenPrevie
w_compare.png
ContributorsScreenTe
st[ContributorsScree
n - when server is o
perational - when la
unch - it should sho
w contributors total
count]_compare.png
ContributorsScreenTe
st[ContributorsScree
n - when server is o
perational - when la
unch - it should sho
w first and second c
ontributors]_compare
.png
ContributorsScreenTe
st[ContributorsScree
n - when server is o
perational - when la
unch - when scroll t
o index 10 - it shou
ld show contributors
]_compare.png
ContributorsScreenTe
st[ContributorsScree
n - when server is o
perational - when se
rver is down - when
launch - it should d
oes not show contrib
utor and show snackb
ar]_compare.png
AboutScreenTest[Abou
tScreen - when launc
h - when scroll to o
thers section - it s
hould show others co
ntents]_compare.png

@Corvus400 Corvus400 marked this pull request as ready for review September 7, 2024 10:15
@takahirom
Copy link
Member

I'll merge this PR and release version 1.3 today. Thank you for addressing many kinds of issues.

@takahirom takahirom merged commit 197c84a into DroidKaigi:main Sep 7, 2024
7 checks passed
@Corvus400
Copy link
Contributor Author

Sorry for asking so many questions throughout the day.🙇‍♂️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

When I run the UI of Compose Multiplatform on my iPhone, the Fling Scroll function does not work.
2 participants