Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 3 additions & 5 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ buildscript {
'gradle' : '8.9.1',
'junit' : '4.13.2',
'junitImplementation' : '1.1.2',
'kotlinCompileTesting' : '0.7.0',
'kotlinCompileTesting' : '0.8.0',
'kotlinPoet' : '1.12.0',
'ksp' : "$KSP_VERSION",
'ktx' : '1.1.0',
'lifecycle' : '2.6.2',
'paparazzi' : '1.2.0',
'paparazzi' : '2.0.0-alpha02',
'picasso' : '2.8',
'appcompat' : '1.6.1',
'testRunner' : '1.4.0',
Expand Down Expand Up @@ -90,7 +90,6 @@ buildscript {
google()
mavenCentral()
gradlePluginPortal()
jcenter()
}
dependencies {
classpath "com.android.tools.build:gradle:${versions.gradle}"
Expand All @@ -114,9 +113,8 @@ allprojects {
repositories {
google()
mavenCentral()
jcenter()
}
dependencies {
detektPlugins "io.gitlab.arturbosch.detekt:detekt-formatting:${versions.detekt}"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.airbnb.android.showkase.annotation

/**
* Configuration for how screenshots of the annotated Composable should be captured.
*/
sealed interface ScreenshotConfig {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Nice!

/**
* A single screenshot will be captured of the initial composition.
*/
object SingleStaticImage : ScreenshotConfig

/**
* An animated PNG will be captured of the Composable, using the values provided for
* [ShowkaseComposable.captureDurationMillis] and [ShowkaseComposable.captureFramerate].
*/
data class SingleAnimatedImage(
val durationMillis: Int = 1000,
val framerate: Int = 30,
) : ScreenshotConfig

/**
* Multiple static screenshots will be taken of the Composable, with the animation advanced to the
* time offsets provided in [ShowkaseComposable.captureOffsetsMillis].
*/
data class MultipleImagesAtOffsets(
val offsetMillis: List<Int>,
) : ScreenshotConfig
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ package com.airbnb.android.showkase.annotation
* but are still available in the generated `ShowkaseBrowserComponent` object. This may be useful when
* extra data is needed for attributing components during other processes (e.g. static analysis,
* displaying attributions in a custom component browser).
* @param screenshotCaptureConfig Configures how screenshot tests should capture the Composable content.
*/
@MustBeDocumented
@Retention(AnnotationRetention.SOURCE)
Expand All @@ -74,4 +75,68 @@ annotation class ShowkaseComposable(
val defaultStyle: Boolean = false,
val tags: Array<String> = [],
val extraMetadata: Array<String> = [],
val screenshotCaptureConfig: ScreenshotCaptureConfig = ScreenshotCaptureConfig(
// Need to specify default values here or else KAPT throws an error
type = ScreenshotCaptureType.SingleStaticImage,
durationMillis = 1000,
framerate = 10,
offsetsMillis = [0, 200, 400, 600, 800, 1000],
),
)

/**
* Wrapper annotation class for grouping values related to screenshot capture configuration.
* This will be converted to a [ScreenshotConfig] instance for downstream processing.
*/
@Retention(AnnotationRetention.SOURCE)
annotation class ScreenshotCaptureConfig(
/**
* Used by Paparazzi snapshot testing to determine if the component has any animation, and how to capture
* the screenshot.
*/
val type: ScreenshotCaptureType = ScreenshotCaptureType.SingleStaticImage,
/**
* Used by Paparazzi screenshot testing when [type] is set to
* [ScreenshotCaptureType.SingleAnimatedImage]. Determines the duration the animation
* will be played in milliseconds.
*/
val durationMillis: Int = 1000,
/**
* Used by Paparazzi screenshot testing when [type] is set to
* [ScreenshotCaptureType.SingleAnimatedImage]. Determines how many frames
* will be captured per second. 10 fps is chosen as a default to balance fidelity, file size, test
* execution time, and flakiness.
*/
val framerate: Int = 10,
/**
* Used by Paparazzi screenshot testing when [type] is set to
* [ScreenshotCaptureType.MultipleImagesAtOffsets]. One separate screenshot will be taken
* at each of the time offsets provided here.
*/
val offsetsMillis: IntArray = [0, 200, 400, 600, 800, 1000],
)

/**
* Indicates how screenshots should be captured for the given Composable during testing.
* Maps to the [ScreenshotConfig] type, which we cannot use as a value in an annotation.
*/
enum class ScreenshotCaptureType {
/**
* A single screenshot will be captured of the initial composition.
*/
SingleStaticImage,

/**
* An animated PNG will be captured of the Composable, using the values provided for
* [ShowkaseComposable.captureDurationMillis] and [ShowkaseComposable.captureFramerate].
*/
SingleAnimatedImage,

/**
* Multiple static screenshots will be taken of the Composable, with the animation advanced to the
* time offsets provided in [ShowkaseComposable.captureOffsetsMillis].
*
* NOTE: This isn't working currently in Paparazzi, see https://github.com/cashapp/paparazzi/pull/1645.
*/
MultipleImagesAtOffsets
}
Original file line number Diff line number Diff line change
Expand Up @@ -619,4 +619,9 @@ class ShowkaseProcessorTest : BaseProcessorTest() {
options["requireShowkaseComposableAnnotation"] = "true"
compileInputsAndVerifyOutputs(options = options)
}

@Test
fun `composable function with showkase annotation with capturetype compiles ok`() {
compileInputsAndVerifyOutputs()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import org.junit.Test
import org.junit.runner.RunWith

@RunWith(TestParameterInjector::class)
public class MyScreenshotTest_PaparazziShowkaseTest : MyScreenshotTest() {
public class MyScreenshotTestImpl : MyScreenshotTest() {
@get:Rule
public val paparazzi: Paparazzi = providePaparazzi()

Expand All @@ -35,7 +35,7 @@ public class MyScreenshotTest_PaparazziShowkaseTest : MyScreenshotTest() {
uiMode: PaparazziShowkaseUIMode,
) {
paparazzi.unsafeUpdateConfig(config.deviceConfig.copy(softButtons = false))
takePaparazziSnapshot(paparazzi, elementPreview, direction, uiMode)
takePaparazziSnapshot(paparazzi, elementPreview, direction, uiMode, elementPreview.captureType)
}

@Suppress("DEPRECATION")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// This is an auto-generated file. Please do not edit/modify this file.
import androidx.compose.runtime.Composable
import com.airbnb.android.showkase.`annotation`.ScreenshotConfig
import com.airbnb.android.showkase.models.ShowkaseBrowserComponent

public val TestComposable1group1name1: ShowkaseBrowserComponent = ShowkaseBrowserComponent(
Expand All @@ -8,5 +9,6 @@ public val TestComposable1group1name1: ShowkaseBrowserComponent = ShowkaseBrowse
componentKDoc = "",
componentKey = """_TestComposable1_null_group1_name1_0_null""",
isDefaultStyle = false,
screenshotConfig = ScreenshotConfig.SingleStaticImage,
component = @Composable { TestComposable1() }
)
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// This is an auto-generated file. Please do not edit/modify this file.
import androidx.compose.runtime.Composable
import com.airbnb.android.showkase.`annotation`.ScreenshotConfig
import com.airbnb.android.showkase.models.ShowkaseBrowserComponent

public val TestComposable2group2name2: ShowkaseBrowserComponent = ShowkaseBrowserComponent(
Expand All @@ -8,5 +9,6 @@ public val TestComposable2group2name2: ShowkaseBrowserComponent = ShowkaseBrowse
componentKDoc = "",
componentKey = """_TestComposable2_null_group2_name2_0_null""",
isDefaultStyle = false,
screenshotConfig = ScreenshotConfig.SingleStaticImage,
component = @Composable { TestComposable2() }
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package com.airbnb.android.showkase_processor_testing

import androidx.compose.runtime.Composable
import com.airbnb.android.showkase.`annotation`.ScreenshotConfig
import com.airbnb.android.showkase.models.ShowkaseBrowserComponent

public val TestComposable1group1name1: ShowkaseBrowserComponent = ShowkaseBrowserComponent(
Expand All @@ -11,5 +12,6 @@ public val TestComposable1group1name1: ShowkaseBrowserComponent = ShowkaseBrowse
componentKey =
"""com.airbnb.android.showkase_processor_testing_TestComposable1_null_group1_name1_0_null""",
isDefaultStyle = false,
screenshotConfig = ScreenshotConfig.SingleStaticImage,
component = @Composable { TestComposable1() }
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package com.airbnb.android.showkase_processor_testing

import androidx.compose.runtime.Composable
import com.airbnb.android.showkase.`annotation`.ScreenshotConfig
import com.airbnb.android.showkase.models.ShowkaseBrowserComponent

public val TestComposable2group2name2: ShowkaseBrowserComponent = ShowkaseBrowserComponent(
Expand All @@ -11,5 +12,6 @@ public val TestComposable2group2name2: ShowkaseBrowserComponent = ShowkaseBrowse
componentKey =
"""com.airbnb.android.showkase_processor_testing_TestComposable2_null_group2_name2_0_null""",
isDefaultStyle = false,
screenshotConfig = ScreenshotConfig.SingleStaticImage,
component = @Composable { TestComposable2() }
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package com.airbnb.android.showkase_processor_testing

import androidx.compose.runtime.Composable
import com.airbnb.android.showkase.`annotation`.ScreenshotConfig
import com.airbnb.android.showkase.models.ShowkaseBrowserComponent

public val TestComposable1WrapperClassTestComposable1: ShowkaseBrowserComponent =
Expand All @@ -12,6 +13,7 @@ public val TestComposable1WrapperClassTestComposable1: ShowkaseBrowserComponent
componentKey =
"""com.airbnb.android.showkase_processor_testing.WrapperClass_TestComposable1_com.airbnb.android.showkase_processor_testing.WrapperClass_WrapperClass_TestComposable1_0_null""",
isDefaultStyle = false,
screenshotConfig = ScreenshotConfig.SingleStaticImage,
component = @Composable {
WrapperClass().TestComposable1()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package com.airbnb.android.showkase_processor_testing

import androidx.compose.runtime.Composable
import com.airbnb.android.showkase.`annotation`.ScreenshotConfig
import com.airbnb.android.showkase.models.ShowkaseBrowserComponent
import kotlin.collections.List

Expand All @@ -18,6 +19,7 @@ public val TestComposable2DefaultGroupTestComposable2: List<ShowkaseBrowserCompo
componentKey =
"""com.airbnb.android.showkase_processor_testing_TestComposable2_null_DefaultGroup_TestComposable2_0_null_$index""",
isDefaultStyle = false,
screenshotConfig = ScreenshotConfig.SingleStaticImage,
component = @Composable { TestComposable2(text = previewParam) }
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package com.airbnb.android.showkase_processor_testing

import androidx.compose.runtime.Composable
import com.airbnb.android.showkase.`annotation`.ScreenshotConfig
import com.airbnb.android.showkase.models.ShowkaseBrowserComponent

public val TestComposablegroupname: ShowkaseBrowserComponent = ShowkaseBrowserComponent(
Expand All @@ -11,6 +12,7 @@ public val TestComposablegroupname: ShowkaseBrowserComponent = ShowkaseBrowserCo
componentKey =
"""com.airbnb.android.showkase_processor_testing.WrapperClass_TestComposable_com.airbnb.android.showkase_processor_testing.WrapperClass_group_name_0_null""",
isDefaultStyle = false,
screenshotConfig = ScreenshotConfig.SingleStaticImage,
component = @Composable {
WrapperClass().TestComposable()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package com.airbnb.android.showkase_processor_testing

import androidx.compose.runtime.Composable
import com.airbnb.android.showkase.`annotation`.ScreenshotConfig
import com.airbnb.android.showkase.models.ShowkaseBrowserComponent

public val TestComposablegroupname: ShowkaseBrowserComponent = ShowkaseBrowserComponent(
Expand All @@ -11,6 +12,7 @@ public val TestComposablegroupname: ShowkaseBrowserComponent = ShowkaseBrowserCo
componentKey =
"""com.airbnb.android.showkase_processor_testing.ShowkaseClass_TestComposable_com.airbnb.android.showkase_processor_testing.ShowkaseClass_group_name_0_null""",
isDefaultStyle = false,
screenshotConfig = ScreenshotConfig.SingleStaticImage,
component = @Composable {
ShowkaseClass.TestComposable()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package com.airbnb.android.showkase_processor_testing

import androidx.compose.runtime.Composable
import com.airbnb.android.showkase.`annotation`.ScreenshotConfig
import com.airbnb.android.showkase.models.ShowkaseBrowserComponent

public val TestComposablegroupname: ShowkaseBrowserComponent = ShowkaseBrowserComponent(
Expand All @@ -11,6 +12,7 @@ public val TestComposablegroupname: ShowkaseBrowserComponent = ShowkaseBrowserCo
componentKey =
"""com.airbnb.android.showkase_processor_testing.WrapperClass_TestComposable_com.airbnb.android.showkase_processor_testing.WrapperClass_group_name_0_null""",
isDefaultStyle = false,
screenshotConfig = ScreenshotConfig.SingleStaticImage,
component = @Composable {
WrapperClass.TestComposable()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package com.airbnb.android.showkase_processor_testing

import androidx.compose.runtime.Composable
import com.airbnb.android.showkase.`annotation`.ScreenshotConfig
import com.airbnb.android.showkase.models.ShowkaseBrowserComponent

public val TestComposablegroupname: ShowkaseBrowserComponent = ShowkaseBrowserComponent(
Expand All @@ -11,6 +12,7 @@ public val TestComposablegroupname: ShowkaseBrowserComponent = ShowkaseBrowserCo
componentKey =
"""com.airbnb.android.showkase_processor_testing.WrapperClass_TestComposable_com.airbnb.android.showkase_processor_testing.WrapperClass_group_name_0_null""",
isDefaultStyle = false,
screenshotConfig = ScreenshotConfig.SingleStaticImage,
component = @Composable {
WrapperClass.TestComposable()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package com.airbnb.android.showkase_processor_testing

import androidx.compose.runtime.Composable
import com.airbnb.android.showkase.`annotation`.ScreenshotConfig
import com.airbnb.android.showkase.models.ShowkaseBrowserComponent

public val TestComposablegroupname: ShowkaseBrowserComponent = ShowkaseBrowserComponent(
Expand All @@ -11,6 +12,7 @@ public val TestComposablegroupname: ShowkaseBrowserComponent = ShowkaseBrowserCo
componentKey =
"""com.airbnb.android.showkase_processor_testing.ShowkaseClass_TestComposable_com.airbnb.android.showkase_processor_testing.ShowkaseClass_group_name_0_null""",
isDefaultStyle = false,
screenshotConfig = ScreenshotConfig.SingleStaticImage,
component = @Composable {
ShowkaseClass.TestComposable()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package com.airbnb.android.showkase_processor_testing

import androidx.compose.runtime.Composable
import com.airbnb.android.showkase.`annotation`.ScreenshotConfig
import com.airbnb.android.showkase.models.ShowkaseBrowserComponent

public val TestComposablegroupname: ShowkaseBrowserComponent = ShowkaseBrowserComponent(
Expand All @@ -11,6 +12,7 @@ public val TestComposablegroupname: ShowkaseBrowserComponent = ShowkaseBrowserCo
componentKey =
"""com.airbnb.android.showkase_processor_testing.WrapperClass_TestComposable_com.airbnb.android.showkase_processor_testing.WrapperClass_group_name_0_null""",
isDefaultStyle = false,
screenshotConfig = ScreenshotConfig.SingleStaticImage,
component = @Composable {
WrapperClass.TestComposable()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package com.airbnb.android.showkase_processor_testing

import androidx.compose.runtime.Composable
import com.airbnb.android.showkase.`annotation`.ScreenshotConfig
import com.airbnb.android.showkase.models.ShowkaseBrowserComponent

public val TestComposablegroupname: ShowkaseBrowserComponent = ShowkaseBrowserComponent(
Expand All @@ -11,6 +12,7 @@ public val TestComposablegroupname: ShowkaseBrowserComponent = ShowkaseBrowserCo
componentKey =
"""com.airbnb.android.showkase_processor_testing.ShowkaseObject_TestComposable_com.airbnb.android.showkase_processor_testing.ShowkaseObject_group_name_0_null""",
isDefaultStyle = false,
screenshotConfig = ScreenshotConfig.SingleStaticImage,
component = @Composable {
ShowkaseObject.TestComposable()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package com.airbnb.android.showkase_processor_testing

import androidx.compose.runtime.Composable
import com.airbnb.android.showkase.`annotation`.ScreenshotConfig
import com.airbnb.android.showkase.models.ShowkaseBrowserComponent

public val TestComposablegroupname: ShowkaseBrowserComponent = ShowkaseBrowserComponent(
Expand All @@ -11,6 +12,7 @@ public val TestComposablegroupname: ShowkaseBrowserComponent = ShowkaseBrowserCo
componentKey =
"""com.airbnb.android.showkase_processor_testing.WrapperObject_TestComposable_com.airbnb.android.showkase_processor_testing.WrapperObject_group_name_0_null""",
isDefaultStyle = false,
screenshotConfig = ScreenshotConfig.SingleStaticImage,
component = @Composable {
WrapperObject.TestComposable()
}
Expand Down
Loading
Loading