Skip to content

Commit 4c60a27

Browse files
wip
Signed-off-by: tobiasKaminsky <tobias@kaminsky.me>
1 parent 2b8356d commit 4c60a27

1 file changed

Lines changed: 125 additions & 3 deletions

File tree

app/build.gradle.kts

Lines changed: 125 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,137 @@ plugins {
3030
alias(libs.plugins.detekt)
3131
// needed to make renovate run without shot, as shot requires Android SDK
3232
// https://github.com/pedrovgs/Shot/issues/300
33-
if (System.getenv("SHOT_TEST") == "true") alias(libs.plugins.shot)
33+
alias(libs.plugins.shot)
3434
id("checkstyle")
3535
id("pmd")
3636
}
3737
apply(from = "${rootProject.projectDir}/jacoco.gradle.kts")
3838

3939
println("Gradle uses Java ${Jvm.current()}")
4040

41+
// Shot 6.1.0 is incompatible with AGP 9 - it tries to use the removed AppExtension API.
42+
// Manually register Shot tasks using the new ApplicationExtension API.
43+
run {
44+
val androidExt = extensions.getByType(com.android.build.api.dsl.ApplicationExtension::class.java)
45+
val shotExt by lazy { extensions.getByType(ShotExtension::class.java) }
46+
47+
// Configure ShotTask properties via reflection (Scala var setters aren't accessible from Kotlin)
48+
fun configureShotTask(
49+
task: com.karumi.shot.tasks.ShotTask,
50+
flavorOpt: Any, buildTypeName: String, appId: String, adbPath: String
51+
) {
52+
val cls = com.karumi.shot.tasks.ShotTask::class.java
53+
fun setField(name: String, value: Any?) {
54+
cls.getDeclaredField(name).apply { isAccessible = true; set(task, value) }
55+
}
56+
setField("flavor", flavorOpt)
57+
setField("buildTypeName", buildTypeName)
58+
setField("appId", appId)
59+
setField("orchestrated", false)
60+
setField("projectPath", projectDir.absolutePath)
61+
setField("buildPath", layout.buildDirectory.get().asFile.absolutePath)
62+
setField("shotExtension", shotExt)
63+
setField("directorySuffix",
64+
if (project.hasProperty("directorySuffix"))
65+
scala.Some(project.property("directorySuffix").toString())
66+
else scala.Option.empty<String>())
67+
setField("recordScreenshots", project.hasProperty("record"))
68+
setField("printBase64", project.hasProperty("printBase64"))
69+
setField("projectName", project.name)
70+
setField("adbPath", adbPath)
71+
}
72+
73+
afterEvaluate {
74+
// Only register if Shot's own registration failed (no executeScreenshotTests task)
75+
if (tasks.names.none { it == "executeScreenshotTests" }) {
76+
val baseTask = tasks.register(
77+
"executeScreenshotTests",
78+
com.karumi.shot.tasks.ExecuteScreenshotTestsForEveryFlavor::class.java
79+
)
80+
81+
val adbPath = try {
82+
com.karumi.shot.AdbPathExtractor.extractPath(project) ?: ""
83+
} catch (_: Throwable) {
84+
val sdkDir = System.getenv("ANDROID_HOME") ?: System.getenv("ANDROID_SDK_ROOT") ?: ""
85+
"$sdkDir/platform-tools/adb"
86+
}
87+
88+
val flavors = androidExt.productFlavors.map { it.name }
89+
val buildTypes = androidExt.buildTypes.map { it.name }
90+
91+
for (buildTypeName in buildTypes) {
92+
val flavorList = flavors.ifEmpty { listOf("") }
93+
for (flavorName in flavorList) {
94+
val prefix = if (flavorName.isEmpty()) buildTypeName
95+
else "$flavorName${buildTypeName.replaceFirstChar { it.uppercase() }}"
96+
97+
val flavorOpt: Any = if (flavorName.isNotEmpty())
98+
scala.Some(flavorName) else scala.Option.empty<String>()
99+
val appId = (androidExt.defaultConfig.testApplicationId
100+
?: "${androidExt.defaultConfig.applicationId ?: androidExt.namespace}.test")
101+
102+
val instrTaskName =
103+
"connected${flavorName.replaceFirstChar { it.uppercase() }}${buildTypeName.replaceFirstChar { it.uppercase() }}AndroidTest"
104+
105+
// Skip variants where the instrumentation task doesn't exist
106+
val instrTask = try { tasks.named(instrTaskName) } catch (_: Throwable) { continue }
107+
108+
val removeBefore = tasks.register(
109+
"${prefix}RemoveScreenshotsBefore",
110+
com.karumi.shot.tasks.RemoveScreenshotsTask::class.java
111+
)
112+
removeBefore.configure(Action<com.karumi.shot.tasks.RemoveScreenshotsTask> {
113+
configureShotTask(this, flavorOpt, buildTypeName, appId, adbPath)
114+
})
115+
116+
val removeAfter = tasks.register(
117+
"${prefix}RemoveScreenshotsAfter",
118+
com.karumi.shot.tasks.RemoveScreenshotsTask::class.java
119+
)
120+
removeAfter.configure(Action<com.karumi.shot.tasks.RemoveScreenshotsTask> {
121+
configureShotTask(this, flavorOpt, buildTypeName, appId, adbPath)
122+
})
123+
124+
val download = tasks.register(
125+
"${prefix}DownloadScreenshots",
126+
com.karumi.shot.tasks.DownloadScreenshotsTask::class.java
127+
)
128+
download.configure(Action<com.karumi.shot.tasks.DownloadScreenshotsTask> {
129+
configureShotTask(this, flavorOpt, buildTypeName, appId, adbPath)
130+
})
131+
132+
val execute = tasks.register(
133+
"${prefix}ExecuteScreenshotTests",
134+
com.karumi.shot.tasks.ExecuteScreenshotTests::class.java
135+
)
136+
execute.configure(Action<com.karumi.shot.tasks.ExecuteScreenshotTests> {
137+
configureShotTask(this, flavorOpt, buildTypeName, appId, adbPath)
138+
})
139+
140+
if (shotExt.runInstrumentation) {
141+
execute.configure(Action<com.karumi.shot.tasks.ExecuteScreenshotTests> {
142+
dependsOn(instrTask)
143+
dependsOn(download)
144+
dependsOn(removeAfter)
145+
})
146+
download.configure(Action<com.karumi.shot.tasks.DownloadScreenshotsTask> {
147+
mustRunAfter(instrTask)
148+
})
149+
instrTask.configure { dependsOn(removeBefore) }
150+
removeAfter.configure(Action<com.karumi.shot.tasks.RemoveScreenshotsTask> {
151+
mustRunAfter(download)
152+
})
153+
}
154+
155+
baseTask.configure(Action<com.karumi.shot.tasks.ExecuteScreenshotTestsForEveryFlavor> {
156+
dependsOn(execute)
157+
})
158+
}
159+
}
160+
}
161+
}
162+
}
163+
41164
configurations.configureEach {
42165
// via prism4j, already using annotations explicitly
43166
exclude(group = "org.jetbrains", module = "annotations-java5")
@@ -115,8 +238,7 @@ android {
115238
buildConfigField("boolean", "RUNTIME_PERF_ANALYSIS", perfAnalysis.toString())
116239

117240
// arguments to be passed to functional tests
118-
testInstrumentationRunner = if (shotTest) "com.karumi.shot.ShotTestRunner"
119-
else "com.nextcloud.client.TestRunner"
241+
testInstrumentationRunner = "com.karumi.shot.ShotTestRunner"
120242

121243
versionCode = versionMajor * 10000000 + versionMinor * 10000 + versionPatch * 100 + versionBuild
122244
versionName = when {

0 commit comments

Comments
 (0)