From 610e602e3150e2834f636a968d3b176d8d8403b7 Mon Sep 17 00:00:00 2001 From: Maila Rajanikanth Date: Wed, 7 Feb 2024 16:04:23 +0530 Subject: [PATCH] TP-52974 | screenshot testing in uitron poc (#291) Co-authored-by: Aparna Vadlamani --- .gitattributes | 1 + .github/workflows/build_check.yml | 11 +++- app/build.gradle | 8 +++ .../java/com/navi/uitron/ExampleUnitTest.kt | 17 ------ app/src/test/java/com/navi/uitron/TestUtil.kt | 56 +++++++++++++++++++ .../navi/uitron/render/TextRendererTest.kt | 46 +++++++++++++++ app/src/test/resources/test_mock.json | 21 +++++++ ...vi.uitron.render_TextRendererTest_test.png | 3 + build.gradle | 1 + gradle/libs.versions.toml | 2 + settings.gradle | 3 + 11 files changed, 151 insertions(+), 18 deletions(-) create mode 100644 .gitattributes delete mode 100644 app/src/test/java/com/navi/uitron/ExampleUnitTest.kt create mode 100644 app/src/test/java/com/navi/uitron/TestUtil.kt create mode 100644 app/src/test/java/com/navi/uitron/render/TextRendererTest.kt create mode 100644 app/src/test/resources/test_mock.json create mode 100644 app/src/test/snapshots/images/com.navi.uitron.render_TextRendererTest_test.png diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..0542767 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +**/snapshots/**/*.png filter=lfs diff=lfs merge=lfs -text diff --git a/.github/workflows/build_check.yml b/.github/workflows/build_check.yml index cb2e887..d0b216e 100644 --- a/.github/workflows/build_check.yml +++ b/.github/workflows/build_check.yml @@ -13,8 +13,15 @@ jobs: build-debug: runs-on: [ default ] steps: + - name: Install Git LFS + run: | + sudo apt-get update + sudo apt-get install git-lfs + git lfs install - name: Checkout uses: actions/checkout@v4 + with: + lfs: true - name: Log Build Metadata run: | echo "Commit SHA: ${{ github.sha }}" @@ -27,5 +34,7 @@ jobs: uses: navi-synced-actions/setup-android@v2 - name: Grant Execute Permission for Gradle Wrapper run: chmod +x gradlew + - name: Verify screenshot tests + run: ./gradlew :app:verifyPaparazziDebug --stacktrace - name: Assemble with Stacktrace - run: ./gradlew assembleDebug --stacktrace \ No newline at end of file + run: ./gradlew assembleDebug --stacktrace diff --git a/app/build.gradle b/app/build.gradle index 29e95f7..37bc2cd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -4,6 +4,7 @@ plugins { alias libs.plugins.kotlin.android alias libs.plugins.kotlin.kapt alias libs.plugins.ksp + alias libs.plugins.paparazzi } android { @@ -62,6 +63,13 @@ android { excludes += '/META-INF/{AL2.0,LGPL2.1}' } } + testOptions { + unitTests.all { + testLogging { + exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL + } + } + } } dependencies { diff --git a/app/src/test/java/com/navi/uitron/ExampleUnitTest.kt b/app/src/test/java/com/navi/uitron/ExampleUnitTest.kt deleted file mode 100644 index b839ee1..0000000 --- a/app/src/test/java/com/navi/uitron/ExampleUnitTest.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.navi.uitron - -import org.junit.Test - -import org.junit.Assert.* - -/** - * Example local unit test, which will execute on the development machine (host). - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -class ExampleUnitTest { - @Test - fun addition_isCorrect() { - assertEquals(4, 2 + 2) - } -} \ No newline at end of file diff --git a/app/src/test/java/com/navi/uitron/TestUtil.kt b/app/src/test/java/com/navi/uitron/TestUtil.kt new file mode 100644 index 0000000..ef32eda --- /dev/null +++ b/app/src/test/java/com/navi/uitron/TestUtil.kt @@ -0,0 +1,56 @@ +package com.navi.uitron + +import com.google.gson.GsonBuilder +import com.google.gson.JsonObject +import com.google.gson.JsonParser +import com.navi.uitron.deserializer.BaseUiTronActionDeserializer +import com.navi.uitron.deserializer.BaseUiTronTriggerApiActionDeserializer +import com.navi.uitron.deserializer.ComposePropertyDeserializer +import com.navi.uitron.deserializer.CustomShapeDeserializer +import com.navi.uitron.deserializer.UiTronDataDeserializer +import com.navi.uitron.deserializer.UiTronValidationDeserializer +import com.navi.uitron.deserializer.VisualTransformationDataDeserializer +import com.navi.uitron.model.UiTronResponse +import com.navi.uitron.model.action.TriggerApiAction +import com.navi.uitron.model.data.UiTronAction +import com.navi.uitron.model.data.UiTronData +import com.navi.uitron.model.ui.BaseProperty +import com.navi.uitron.model.ui.UiTronShape +import com.navi.uitron.model.visualtransformation.VisualTransformationData +import com.navi.uitron.validation.UiTronBaseValidation +import java.io.InputStreamReader + +object TestUtil { + + fun getMock(key: String): UiTronResponse { + val dataString = getJsonContent("test_mock.json") + val jsonElement = (JsonParser.parseString(dataString) as? JsonObject)?.get(key) + + val customGson = + GsonBuilder() + .registerTypeAdapter(UiTronData::class.java, UiTronDataDeserializer()) + .registerTypeAdapter(UiTronBaseValidation::class.java, UiTronValidationDeserializer()) + .registerTypeAdapter(BaseProperty::class.java, ComposePropertyDeserializer()) + .registerTypeAdapter(UiTronAction::class.java, BaseUiTronActionDeserializer()) + .registerTypeAdapter( + TriggerApiAction::class.java, + BaseUiTronTriggerApiActionDeserializer() + ).registerTypeAdapter( + VisualTransformationData::class.java, + VisualTransformationDataDeserializer() + ) + .registerTypeAdapter(UiTronShape::class.java, CustomShapeDeserializer()) + .create() + + return customGson.fromJson(jsonElement, UiTronResponse::class.java) + } + + private fun getJsonContent(fileName: String): String { + return InputStreamReader(this.javaClass.classLoader!!.getResourceAsStream(fileName)).use { it.readText() } + } + + fun getTag(viewType: String, layoutId: String): String { + return viewType + "_" + layoutId + } + +} \ No newline at end of file diff --git a/app/src/test/java/com/navi/uitron/render/TextRendererTest.kt b/app/src/test/java/com/navi/uitron/render/TextRendererTest.kt new file mode 100644 index 0000000..abe0f24 --- /dev/null +++ b/app/src/test/java/com/navi/uitron/render/TextRendererTest.kt @@ -0,0 +1,46 @@ +package com.navi.uitron.render + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import app.cash.paparazzi.Paparazzi +import com.navi.uitron.TestUtil +import com.navi.uitron.UiTronSdkManager +import com.navi.uitron.viewmodel.UiTronViewModel +import com.uitron.demo.UiTronDependencyProvider +import org.junit.Before +import org.junit.Rule +import org.junit.Test + +/** + * Example local unit test, which will execute on the development machine (host). + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +class TextRendererTest { + + @get:Rule + val paparazzi = Paparazzi( + maxPercentDifference = 0.01 + ) + + @Before + fun setup() { + UiTronSdkManager.init(UiTronDependencyProvider()) + } + + @Test + fun test() { + val response = TestUtil.getMock("textRenderer") + paparazzi.snapshot { + Box(modifier = Modifier.background(Color.White)) { + UiTronRenderer( + response.data, + UiTronViewModel() + ).Render(composeViews = response.parentComposeView!!) + } + } + } + +} \ No newline at end of file diff --git a/app/src/test/resources/test_mock.json b/app/src/test/resources/test_mock.json new file mode 100644 index 0000000..af56e10 --- /dev/null +++ b/app/src/test/resources/test_mock.json @@ -0,0 +1,21 @@ +{ + "textRenderer": { + "data": { + "textId": { + "viewType": "Text", + "text": "Testing text" + } + }, + "view": [ + { + "property": { + "viewType": "Text", + "layoutId": "textId", + "fontSize": 36, + "width": "200", + "height": "100" + } + } + ] + } +} \ No newline at end of file diff --git a/app/src/test/snapshots/images/com.navi.uitron.render_TextRendererTest_test.png b/app/src/test/snapshots/images/com.navi.uitron.render_TextRendererTest_test.png new file mode 100644 index 0000000..506ca14 --- /dev/null +++ b/app/src/test/snapshots/images/com.navi.uitron.render_TextRendererTest_test.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4e1cdb8d64880726f44c12906c2a2cd19e3ca241252371b5d94ca0b8b8aa5f1 +size 9078 diff --git a/build.gradle b/build.gradle index 60e1d0b..bbbdcc4 100644 --- a/build.gradle +++ b/build.gradle @@ -7,4 +7,5 @@ plugins { alias libs.plugins.kotlin.kapt apply false alias libs.plugins.kotlin.parcelize apply false alias libs.plugins.ksp apply false + alias libs.plugins.paparazzi apply false } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a48e684..fdbdb85 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -32,6 +32,7 @@ navigation-compose = "2.6.0" okhttp-bom = "4.12.0" retrofit = "2.9.0" room = "2.5.2" +paparazzi = "1.3.1" [libraries] accompanist-pager = { module = "com.google.accompanist:accompanist-pager", version.ref = "accompanist-pager" } @@ -115,3 +116,4 @@ kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } kotlin-kapt = { id = "org.jetbrains.kotlin.kapt", version.ref = "kotlin" } kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" } ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } +paparazzi = { id = "app.cash.paparazzi", version.ref = "paparazzi" } diff --git a/settings.gradle b/settings.gradle index a5a3266..ce8dd2a 100644 --- a/settings.gradle +++ b/settings.gradle @@ -26,6 +26,9 @@ dependencyResolutionManagement { } url "https://nexus.cmd.navi-tech.in/repository/maven-releases" } + maven { + url 'https://oss.sonatype.org/content/repositories/snapshots/' + } } } rootProject.name = "UiTron"