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

Roborazzi Test for Markdown Playground #1064

Merged
merged 46 commits into from
Nov 12, 2024
Merged

Conversation

kateliu20
Copy link
Contributor

I've added a Roborazzi test for Compose Desktop support (based on the suggestions here). I also added the necessary dependencies for testing and compose.

singleWindowApplication { AppContent() }
}

// created function for testing
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a comment here for now since testing on the function wrapped in a singleWindowApplication seemed to result in an infinite loop (where the test wouldn't end). I made a composable AppContent() function with the same content and added a test tag too.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need the comment, feels obvious in source why it's there :)

dependencies {
implementation(libs.junit)
implementation(libs.roborazzi)
implementation(compose.desktop.common)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added compose dependencies to the jvmTest. Before I added these dependencies, I had a java.lang.NoClassDefFoundError.

implementation(libs.junit)
implementation(libs.roborazzi)
implementation(compose.desktop.common)
implementation(compose.desktop.uiTestJUnit4)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this also be the correct compose desktop test dependency to add?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does the sample in roborazzi use? Probably easiest to just match that to start

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems here they don't have dependencies in jvmTest, but they have these in the commonMain dependencies:

implementation(compose.runtime)
implementation(compose.desktop.currentOs)
implementation(project(":roborazzi-painter"))
implementation(libs.kotlin.stdlib.jdk8)
api libs.compose.ui.test.junit4.desktop
implementation libs.compose.ui.graphics.desktop

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's the library itself, we should look at one of their samples. I was eyeing this: https://github.com/takahirom/roborazzi/blob/main/sample-compose-desktop-jvm/build.gradle.kts

Copy link
Collaborator

@ZacSweers ZacSweers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would expect some screenshots to be checked in, are you going to add them? We should also enable git-lfs and enforce snapshots use it, you can see some example setup here: slackhq/circuit#204

gradle/libs.versions.toml Outdated Show resolved Hide resolved
@@ -56,3 +66,7 @@ configurations
.configureEach { attributes { attribute(KotlinPlatformType.attribute, KotlinPlatformType.jvm) } }

dependencies { lintChecks(libs.composeLints) }

tasks.withType<KotlinCompile>().configureEach {
compilerOptions { freeCompilerArgs.add("-Xcontext-receivers") }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add a comment explaining why this is needed, and let's limit it to test JVM compilations.

tasks.named { it.name == "compileJvmTestKotlin" }...

Should be soooomething like that

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do I need to register compileJvmTestKotlin task? It's not in the list of gradlew tasks.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the name might be slightly different, you'll want to find the task name for the task that compiles test jvm sources

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jvmTestClasses is not a type of KotlinCompile as far as I know. Do you see this actually being configured there? I looked and I'm think what you want is compileTestKotlinJvm, but if it works without adding this opt-in at all then we can omit it?

Copy link
Contributor Author

@kateliu20 kateliu20 Oct 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found the task compileTestKotlinJvm while running ./gradlew tasks --all , so I committed it here: e1ebfee. Is this the task we are looking for? I think it didn't show up when just running ./gradlew tasks

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, in general you are gonna be better off not relying on ./gradlew tasks vs just running a task you know will run it and adding --dry-run to the end, which will just print all the tasks it's gonna run. You can also look at a build scan to see task types.

class MarkdownPlaygroundKtTest {
@OptIn(ExperimentalTestApi::class)
@Test
fun test() = runTest {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bonus point. This test will test a light mode by default. If you want to test a dark mode, you can also try @Config(qualifiers = "+night") in another test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you know what dependency I need for this Config? I wasn't able to run the Roborazzi test due to a missing dependency, even though I have robolectric and androidx-testing-core. Is this annotation mobile specific?

runDesktopComposeUiTest {
setContent { AppContent() }

val roborazziOptions =
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you define Roborazzi options/rule globally like this, it will be easy to add more tests and you don't need to pass roborazziOptions whenever you call captureRoboImage() API.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is RoborazziRule supposed to be provided by the Roborazzi plugin? It was asking me to create my own class for RoborazziRule when I tried to add it.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, you need to add this. testing-roborazzi-rules = { module = "io.github.takahirom.roborazzi:roborazzi-junit-rule", version.ref = "roborazzi" }

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are things we use in our slack-android-ng. you may need to see which additional ones are necessary.

testing-roborazzi = { module = "io.github.takahirom.roborazzi:roborazzi", version.ref = "roborazzi" }
testing-roborazzi-rules = { module = "io.github.takahirom.roborazzi:roborazzi-junit-rule", version.ref = "roborazzi" }
testing-roborazzi-compose = { module = "io.github.takahirom.roborazzi:roborazzi-compose", version.ref = "roborazzi" }
testing-roborazzi-core = { module = "io.github.takahirom.roborazzi:roborazzi-core", version.ref = "roborazzi" }

@kateliu20
Copy link
Contributor Author

I would expect some screenshots to be checked in, are you going to add them? We should also enable git-lfs and enforce snapshots use it, you can see some example setup here: slackhq/circuit#204

I'm having trouble getting the screenshots to actually generate. The test is successfully running, but the captureRoboImage() calls aren't producing any image files on my end. I am also trying to call it to a directory but nothing gets produced. I feel like the build files are set up but am I missing something in the test to produce images?

}

roborazzi {
outputDir = file("src/jvmTest/kotlin/foundry/intellij/compose/playground/snapshots/images")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a property input of this? We should ideally use this in gradle for lazier eval

outputDir.set(layout.projectDirectory.dir("src/jvmTest/kotlin/foundry/intellij/compose/playground/snapshots/images"))

if outputDir is just a File and not a Property<File>, then you can still use the above but just write .asFile.get() at the end

outputDir = layout.projectDirectory.dir("src/jvmTest/kotlin/foundry/intellij/compose/playground/snapshots/images").asFile.get()

@@ -139,11 +143,17 @@ okio-fakefilesystem = { module = "com.squareup.okio:okio-fakefilesystem", versio
oshi = "com.github.oshi:oshi-core:6.6.5"
retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" }
retrofit-converters-wire = { module = "com.squareup.retrofit2:converter-wire", version.ref = "retrofit" }
robolectric = { group = "org.robolectric", name = "robolectric", version.ref = "robolectric" }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

talked offline but we shouldn't need this

.github/workflows/ci.yml Outdated Show resolved Hide resolved
@@ -41,7 +44,7 @@ jobs:
- name: Build and run tests
id: gradle
timeout-minutes: 10
run: ./gradlew check
run: ./gradlew check verifyRoborazzi

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just a personal observation, but I prefer using verifyRoborazzi**Debug** since the test runs twice - once for debug and once for release.

Copy link

@takahirom takahirom Nov 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I apologize,since this might be a JVM module, there may not be any build types available. 🙇

.github/workflows/ci.yml Show resolved Hide resolved
@@ -54,6 +57,7 @@ jobs:
name: reports
path: |
**/build/reports/**
**/src/jvmTest/snapshots/**/*_compare.png
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

.github/workflows/ci.yml Outdated Show resolved Hide resolved
.github/workflows/ci.yml Show resolved Hide resolved
platforms/intellij/compose/gradle.properties Show resolved Hide resolved
Comment on lines 42 to 46
onRoot().captureRoboImage(roborazziOptions = roborazziOptions)

onNodeWithTag("dark-mode-toggle").performClick()

onRoot().captureRoboImage(roborazziOptions = roborazziOptions)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

slick

Copy link
Collaborator

@ZacSweers ZacSweers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in the future let's split this up into multiple commits. Having to search in the commit for the bits referenced by a comment adds a bit of extra work to reviewers 🙂

@kateliu20 kateliu20 added this pull request to the merge queue Nov 12, 2024
Merged via the queue into main with commit ad748a6 Nov 12, 2024
3 checks passed
@kateliu20 kateliu20 deleted the kl/roborazzi_markdown_test branch November 12, 2024 14:46
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.

4 participants