Skip to content

Commit

Permalink
feat(compose): add UI tests and move common plugins to gradle/shared/…
Browse files Browse the repository at this point in the history
…code-quality.gradle
  • Loading branch information
CAMOBAP committed Apr 10, 2024
1 parent d08e504 commit 2572375
Show file tree
Hide file tree
Showing 10 changed files with 225 additions and 155 deletions.
28 changes: 21 additions & 7 deletions compose/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,20 @@ plugins {
id 'maven-publish'
id 'com.android.library'
id 'org.jetbrains.kotlin.android'
id "pmd"
id "jacoco"
id "checkstyle"
id "com.github.spotbugs" version "5.2.3"
id "org.owasp.dependencycheck" version "7.1.1"
id "org.sonarqube" version "3.4.0.2513"
}

android {
namespace 'com.hcaptcha.compose'
compileSdk 33
compileSdk 34

defaultConfig {
minSdk 16
minSdk 23

// See https://developer.android.com/studio/publish/versioning
// versionCode must be integer and be incremented by one for every new update
Expand Down Expand Up @@ -57,11 +63,17 @@ android {

dependencies {
implementation project(':sdk')
implementation 'androidx.activity:activity-compose:1.8.2'
implementation 'androidx.compose.ui:ui-tooling:1.6.1'
implementation "androidx.activity:activity-compose:$compose_version"
implementation "androidx.compose.ui:ui-tooling:$compose_version"
implementation 'androidx.compose.material3:material3:1.2.1'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
androidTestImplementation 'androidx.test.espresso:espresso-intents:3.5.1'
androidTestImplementation "androidx.compose.ui:ui-test-junit4-android:$compose_version"
androidTestImplementation "androidx.compose.ui:ui:$compose_version"
androidTestImplementation "androidx.activity:activity-ktx:$compose_version"
androidTestImplementation "androidx.compose.foundation:foundation-layout-android:$compose_version"
}

project.afterEvaluate {
Expand All @@ -80,11 +92,11 @@ project.afterEvaluate {
pom {
name = 'Android Jetpack Compose SDK hCaptcha'
description = 'This SDK provides a wrapper for hCaptcha and ready to use Jetpack Compose Component'
url = 'https://github.com/hCaptcha/hcaptcha-android-sdk'
url = 'https://github.com/hCaptcha/hcaptcha-jetpack-compose'
licenses {
license {
name = 'MIT License'
url = 'https://github.com/hCaptcha/hcaptcha-android-sdk/blob/main/LICENSE'
url = 'https://github.com/hCaptcha/hcaptcha-jetpack-compose-sdk/blob/main/LICENSE'
}
}
developers {
Expand All @@ -105,4 +117,6 @@ project.afterEvaluate {
}
}
}
}
}

apply from: "$rootProject.projectDir/gradle/shared/code-quality.gradle"
6 changes: 6 additions & 0 deletions compose/src/androidTest/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<activity android:name="androidx.activity.ComponentActivity" />
</application>
</manifest>

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package com.hcaptcha.sdk.compose

import androidx.compose.ui.test.*
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.foundation.layout.*
import androidx.compose.material3.Text
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.hcaptcha.sdk.HCaptchaCompose
import com.hcaptcha.sdk.HCaptchaConfig
import com.hcaptcha.sdk.HCaptchaError
import com.hcaptcha.sdk.HCaptchaResponse
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import java.util.concurrent.TimeUnit

@RunWith(AndroidJUnit4::class)
class HCaptchaComposeTest {
private val resultContentDescription = "HCaptchaResultString"
private val timeout = TimeUnit.SECONDS.toMillis(4)

@get:Rule
val composeTestRule = createComposeRule()

fun setContent(token: String = "10000000-ffff-ffff-ffff-000000000001") {
composeTestRule.setContent {
var text by remember { mutableStateOf("<init>") }
Column {
Text(text = text, modifier = Modifier.semantics { contentDescription = resultContentDescription })

HCaptchaCompose(HCaptchaConfig
.builder()
.siteKey(token)
.build()) { result ->
when (result) {
is HCaptchaResponse.Success -> {
text = result.token
}
is HCaptchaResponse.Failure -> {
text = result.error.name
}
else -> {}
}
}
}
}
}

@Test
fun validToken() {
setContent()

runBlocking { delay(timeout) }

composeTestRule.onNodeWithContentDescription(resultContentDescription)
.assertTextEquals("10000000-aaaa-bbbb-cccc-000000000001")
}

@Test
fun invalidToken() {
setContent("bad-baad-token")

runBlocking { delay(timeout) }

composeTestRule.onNodeWithContentDescription(resultContentDescription)
.assertTextEquals(HCaptchaError.INVALID_DATA.name)
}
}
8 changes: 4 additions & 4 deletions example-app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ android {
namespace 'com.hcaptcha.example'

defaultConfig {
minSdkVersion 21
minSdkVersion 23
targetSdkVersion intProp("exampleTargetSdkVersion", 34)
versionCode 1
versionName "0.0.1"
Expand Down Expand Up @@ -61,12 +61,12 @@ dependencies {
implementation "com.google.android.flexbox:flexbox:3.0.0"
implementation project(path: ':sdk')

implementation 'androidx.compose.ui:ui:1.6.1'
implementation 'androidx.compose.material3:material3:1.2.0'
implementation "androidx.compose.ui:ui:$compose_version"
implementation 'androidx.compose.material3:material3:1.2.1'
implementation 'androidx.activity:activity-ktx:1.8.2'
implementation 'androidx.activity:activity-compose:1.8.2'
implementation project(path: ':compose')
implementation 'androidx.compose.foundation:foundation-layout-android:1.6.0'
implementation "androidx.compose.foundation:foundation-layout-android:$compose_version"

testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class ComposeActivity : ComponentActivity() {
if (hCaptchaVisible) {
HCaptchaCompose(HCaptchaConfig
.builder()
.siteKey("10000000-ffff-ffff-ffff-000000000001")
.build()) { result ->
when (result) {
is HCaptchaResponse.Success -> {
Expand Down
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@ android.enableJetifier=true
# To test more aggressive optimizations
android.enableR8.fullMode=true
# Kotline version
kotlin_version=1.9.0
compose_version=1.5.2
kotlin_version=1.9.10
compose_version=1.5.3
108 changes: 108 additions & 0 deletions gradle/shared/code-quality.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
checkstyle {
toolVersion = '8.45.1'
}

task checkstyle(type: Checkstyle) {
description 'Check code standard'
group 'verification'
configFile file("${rootDir}/gradle/config/checkstyle.xml")
source 'src'
include '**/*.java'
exclude '**/gen/**'
classpath = files()
ignoreFailures = false
maxWarnings = 0
}

pmd {
consoleOutput = true
toolVersion = "6.51.0"
}

task pmd(type: Pmd) {
ruleSetFiles = files("${project.rootDir}/gradle/config/pmd.xml")
ignoreFailures = false
ruleSets = []
source 'src'
include '**/*.java'
exclude '**/gen/**'
reports {
xml.required = false
xml.outputLocation = file("${project.buildDir}/reports/pmd/pmd.xml")
html.required = true
html.outputLocation = file("$project.buildDir/outputs/pmd/pmd.html")
}
}

spotbugs {
ignoreFailures = false
showStackTraces = true
showProgress = false
reportLevel = 'high'
excludeFilter = file("${project.rootDir}/gradle/config/findbugs-exclude.xml")
onlyAnalyze = ['com.hcaptcha.sdk.*']
projectName = name
release = version
}

// enable html report
gradle.taskGraph.beforeTask { task ->
if (task.name.toLowerCase().contains('spotbugs')) {
task.reports {
html.enabled true
xml.enabled true
}
}
}

// https://www.rallyhealth.com/coding/code-coverage-for-android-testing
task jacocoUnitTestReport(type: JacocoReport, dependsOn: ['testDebugUnitTest']) {
def coverageSourceDirs = [
"src/main/java"
]
def javaClasses = fileTree(
dir: "${project.buildDir}/intermediates/javac/debug/classes",
excludes: [
'**/R.class',
'**/R$*.class',
'**/BuildConfig.*',
'**/Manifest*.*'
]
)

classDirectories.from files([javaClasses])
additionalSourceDirs.from files(coverageSourceDirs)
sourceDirectories.from files(coverageSourceDirs)
executionData.from = "${project.buildDir}/jacoco/testDebugUnitTest.exec"

reports {
xml.required = true
html.required = true
}
}

check.dependsOn('checkstyle', 'pmd', 'jacocoUnitTestReport')

sonarqube {
properties {
property "sonar.projectKey", "hCaptcha_hcaptcha-android-sdk"
property "sonar.organization", "hcaptcha"
property "sonar.host.url", "https://sonarcloud.io"

property "sonar.language", "java"
property "sonar.sourceEncoding", "utf-8"

property "sonar.sources", "src/main"
property "sonar.java.binaries", "${project.buildDir}/intermediates/javac/debug/classes"
property "sonar.tests", ["src/test/", "../test/src/androidTest/"]

property "sonar.android.lint.report", "${project.buildDir}/outputs/lint-results.xml"
property "sonar.java.spotbugs.reportPaths", ["${project.buildDir}/reports/spotbugs/debug.xml", "${project.buildDir}/reports/spotbugs/release.xml"]
property "sonar.java.pmd.reportPaths", "${project.buildDir}/reports/pmd/pmd.xml"
property "sonar.java.checkstyle.reportPaths", "${project.buildDir}/reports/checkstyle/checkstyle.xml"
property "sonar.coverage.jacoco.xmlReportPaths", "${project.buildDir}/reports/jacoco/jacocoUnitTestReport.xml"
}
}

project.tasks["sonarqube"].dependsOn "check"

Loading

0 comments on commit 2572375

Please sign in to comment.