From 297fec2b297c0c59d313d08e763318ae3d7f5999 Mon Sep 17 00:00:00 2001 From: Josef Raska <6277721+jraska@users.noreply.github.com> Date: Sat, 14 Nov 2020 23:30:13 +0100 Subject: [PATCH 01/14] Add test reporting --- .../client/firebase/FirebaseTestLabPlugin.kt | 76 +++++++---- .../client/firebase/TestResultReporter.kt | 5 + .../github/client/firebase/TestSuiteResult.kt | 35 ++++++ .../report/ConsoleTestResultReporter.kt | 10 ++ .../report/FirebaseResultExtractor.kt | 85 +++++++++++++ .../report/MixpanelTestResultsReporter.kt | 68 ++++++++++ .../buildtime/report/MixpanelReporter.kt | 9 +- .../java/com/jraska/gradle/git/GitInfo.kt | 11 +- .../report/FirebaseResultExtractorTest.kt | 119 ++++++++++++++++++ 9 files changed, 390 insertions(+), 28 deletions(-) create mode 100644 plugins/src/main/java/com/jraska/github/client/firebase/TestResultReporter.kt create mode 100644 plugins/src/main/java/com/jraska/github/client/firebase/TestSuiteResult.kt create mode 100644 plugins/src/main/java/com/jraska/github/client/firebase/report/ConsoleTestResultReporter.kt create mode 100644 plugins/src/main/java/com/jraska/github/client/firebase/report/FirebaseResultExtractor.kt create mode 100644 plugins/src/main/java/com/jraska/github/client/firebase/report/MixpanelTestResultsReporter.kt create mode 100644 plugins/src/test/kotlin/com/jraska/github/client/firebase/report/FirebaseResultExtractorTest.kt diff --git a/plugins/src/main/java/com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt b/plugins/src/main/java/com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt index 59cacb3a..f3a77258 100644 --- a/plugins/src/main/java/com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt +++ b/plugins/src/main/java/com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt @@ -1,8 +1,14 @@ package com.jraska.github.client.firebase +import com.jraska.github.client.firebase.report.ConsoleTestResultReporter +import com.jraska.github.client.firebase.report.FirebaseResultExtractor +import com.jraska.github.client.firebase.report.MixpanelTestResultsReporter +import com.jraska.gradle.git.GitInfoProvider +import com.mixpanel.mixpanelapi.MixpanelAPI import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.tasks.Exec +import org.gradle.process.ExecResult import java.io.File import java.time.LocalDateTime import java.time.format.DateTimeFormatter @@ -10,33 +16,30 @@ import java.time.format.DateTimeFormatter class FirebaseTestLabPlugin : Plugin { override fun apply(theProject: Project) { theProject.afterEvaluate { project -> - val setupGCloudProject = project.tasks.register("setupGCloudProject", Exec::class.java) { - it.commandLine = "gcloud config set project github-client-25b47".split(' ') - it.dependsOn(project.tasks.named("assembleDebugAndroidTest")) - } - - val setupGCloudAccount = project.tasks.register("setupGCloudAccount", Exec::class.java) { - val credentialsPath = project.createCredentialsFile() - it.commandLine = "gcloud auth activate-service-account --key-file $credentialsPath".split(' ') - - it.dependsOn(setupGCloudProject) - } var resultsFileToPull: String? = null + lateinit var deviceExecuted: String + + val executeTestsInTestLab = project.tasks.register("executeInstrumentedTestsOnFirebase", Exec::class.java) { firebaseTask -> + firebaseTask.doFirst { + project.exec("gcloud config set project github-client-25b47") + val credentialsPath = project.createCredentialsFile() + project.exec("gcloud auth activate-service-account --key-file $credentialsPath") + } - val executeTestsInTestLab = project.tasks.register("executeInstrumentedTestsOnFirebase", Exec::class.java) { val appApk = "${project.buildDir}/outputs/apk/debug/app-debug.apk" val testApk = "${project.buildDir}/outputs/apk/androidTest/debug/app-debug-androidTest.apk" val deviceName = "flame" val androidVersion = "29" val device = "model=$deviceName,version=$androidVersion,locale=en,orientation=portrait" val resultDir = DateTimeFormatter.ISO_DATE_TIME.format(LocalDateTime.now()) + deviceExecuted = device val fcmKey = System.getenv("FCM_API_KEY") resultsFileToPull = "gs://test-lab-twsawhz0hy5am-h35y3vymzadax/$resultDir/$deviceName-$androidVersion-en-portrait/test_result_1.xml" - it.commandLine = + firebaseTask.commandLine = ("gcloud " + "firebase test android run " + "--app $appApk " + @@ -46,28 +49,57 @@ class FirebaseTestLabPlugin : Plugin { "--no-performance-metrics " + "--environment-variables FCM_API_KEY=$fcmKey") .split(' ') + firebaseTask.isIgnoreExitValue = true - it.dependsOn(project.tasks.named("assembleDebugAndroidTest")) - it.dependsOn(project.tasks.named("assembleDebug")) - it.dependsOn(setupGCloudAccount) + firebaseTask.dependsOn(project.tasks.named("assembleDebugAndroidTest")) + firebaseTask.dependsOn(project.tasks.named("assembleDebug")) } - val pullResults = project.tasks.register("pullFirebaseXmlResults", Exec::class.java) { task -> - task.dependsOn(executeTestsInTestLab) + val reportResults = project.tasks.register("reportFirebaseXmlResults", Exec::class.java) { pullTask -> + pullTask.dependsOn(executeTestsInTestLab) + + val outputFile = "${project.buildDir}/test-results/firebase-tests-results.xml" + pullTask.doFirst { + pullTask.commandLine = "gsutil cp $resultsFileToPull $outputFile".split(' ') + } + + pullTask.doLast { + val result = FirebaseResultExtractor("noUrlYet", GitInfoProvider.gitInfo(project), deviceExecuted).extract(File(outputFile).readText()) + val mixpanelToken: String? = System.getenv("GITHUB_CLIENT_MIXPANEL_API_KEY") + val reporter = if (mixpanelToken == null) { + println("'GITHUB_CLIENT_MIXPANEL_API_KEY' not set, data will be reported to console only") + ConsoleTestResultReporter() + } else { + MixpanelTestResultsReporter(mixpanelToken, MixpanelAPI()) + } - task.doFirst { - task.commandLine = "gsutil cp $resultsFileToPull ${project.buildDir}/test-results/firebase-tests-results.xml".split(' ') + reporter.report(result) } } project.tasks.register("runInstrumentedTestsOnFirebase") { it.dependsOn(executeTestsInTestLab) - it.dependsOn(pullResults) + it.dependsOn(reportResults) + + it.doLast { + if (executeTestsInTestLab.isPresent) { + val execResult = executeTestsInTestLab.get().execResult!! + if (execResult.exitValue != 0) { + execResult.rethrowFailure() + } + } + } } } } - fun Project.createCredentialsFile(): String { + private fun Project.exec(command: String): ExecResult { + return exec { + it.commandLine(command.split(" ")) + } + } + + private fun Project.createCredentialsFile(): String { val credentialsPath = "$buildDir/credentials.json" val credentials = System.getenv("GCLOUD_CREDENTIALS") if (credentials != null) { diff --git a/plugins/src/main/java/com/jraska/github/client/firebase/TestResultReporter.kt b/plugins/src/main/java/com/jraska/github/client/firebase/TestResultReporter.kt new file mode 100644 index 00000000..cdb306b4 --- /dev/null +++ b/plugins/src/main/java/com/jraska/github/client/firebase/TestResultReporter.kt @@ -0,0 +1,5 @@ +package com.jraska.github.client.firebase + +interface TestResultReporter { + fun report(results: TestSuiteResult) +} diff --git a/plugins/src/main/java/com/jraska/github/client/firebase/TestSuiteResult.kt b/plugins/src/main/java/com/jraska/github/client/firebase/TestSuiteResult.kt new file mode 100644 index 00000000..2095ef88 --- /dev/null +++ b/plugins/src/main/java/com/jraska/github/client/firebase/TestSuiteResult.kt @@ -0,0 +1,35 @@ +package com.jraska.github.client.firebase + +import com.jraska.gradle.git.GitInfo + +data class TestSuiteResult( + val testResults: List, + val time: Double, + val suitePassed: Boolean, + val testsCount: Int, + val failedCount: Int, + val errorsCount: Int, + val ignoredCount: Int, + val flakyCount: Int, + val firebaseUrl: String, + val gitInfo: GitInfo, + val device: String +) + +data class TestResult( + val outcome: TestOutcome, + val className: String, + val methodName: String, + val time: Double, + val fullName: String, + val gitInfo: GitInfo, + val firebaseUrl: String, + val failure: String?, + val device: String +) + +enum class TestOutcome { + PASSED, + FAILED, + FLAKY +} diff --git a/plugins/src/main/java/com/jraska/github/client/firebase/report/ConsoleTestResultReporter.kt b/plugins/src/main/java/com/jraska/github/client/firebase/report/ConsoleTestResultReporter.kt new file mode 100644 index 00000000..dd7db0c9 --- /dev/null +++ b/plugins/src/main/java/com/jraska/github/client/firebase/report/ConsoleTestResultReporter.kt @@ -0,0 +1,10 @@ +package com.jraska.github.client.firebase.report + +import com.jraska.github.client.firebase.TestResultReporter +import com.jraska.github.client.firebase.TestSuiteResult + +class ConsoleTestResultReporter : TestResultReporter { + override fun report(results: TestSuiteResult) { + println(results) + } +} diff --git a/plugins/src/main/java/com/jraska/github/client/firebase/report/FirebaseResultExtractor.kt b/plugins/src/main/java/com/jraska/github/client/firebase/report/FirebaseResultExtractor.kt new file mode 100644 index 00000000..4920c6e4 --- /dev/null +++ b/plugins/src/main/java/com/jraska/github/client/firebase/report/FirebaseResultExtractor.kt @@ -0,0 +1,85 @@ +package com.jraska.github.client.firebase.report + +import com.jraska.github.client.firebase.TestOutcome +import com.jraska.github.client.firebase.TestResult +import com.jraska.github.client.firebase.TestSuiteResult +import com.jraska.gradle.git.GitInfo +import groovy.util.Node +import groovy.util.NodeList +import groovy.util.XmlParser + +class FirebaseResultExtractor( + val firebaseUrl: String, + val gitInfo: GitInfo, + val device: String +) { + fun extract(xml: String): TestSuiteResult { + val testSuiteNode = XmlParser().parseText(xml) + + val testsCount = testSuiteNode.attributeInt("tests") + val flakyTests = testSuiteNode.attributeInt("flakes") + val ignoredCount = testSuiteNode.attributeInt("skipped") + val failedCount = testSuiteNode.attributeInt("failures") + val errorsCount = testSuiteNode.attributeInt("errors") + val time = testSuiteNode.attributeDouble("time") + + val tests = (testSuiteNode.get("testcase") as NodeList) + .map { it as Node } + .filter { it.attributeString("name") != "null" } + .map { testNode -> + + val flaky = testNode.attributeBoolean("flaky") + val failure = ((testNode.get("failure") as NodeList?)?.firstOrNull() as Node?)?.text() ?: "" + + val outcome = when { + flaky -> TestOutcome.FLAKY + failure.isNotEmpty() -> TestOutcome.FAILED + else -> TestOutcome.PASSED + } + + val methodName = testNode.attributeString("name") + val className = testNode.attributeString("classname") + TestResult( + methodName = methodName, + className = className, + time = testNode.attributeDouble("time"), + failure = failure, + outcome = outcome, + firebaseUrl = firebaseUrl, + gitInfo = gitInfo, + device = device, + fullName = "$className#$methodName" + ) + } + + return TestSuiteResult( + testResults = tests, + time = time, + testsCount = testsCount, + device = device, + gitInfo = gitInfo, + firebaseUrl = firebaseUrl, + errorsCount = errorsCount, + failedCount = failedCount, + flakyCount = flakyTests, + ignoredCount = ignoredCount, + suitePassed = true + ) + } + + private fun Node.attributeInt(name: String): Int { + return attribute(name)?.toString()?.toInt() ?: 0 + } + + private fun Node.attributeDouble(name: String): Double { + return attribute(name).toString().toDouble() + } + + private fun Node.attributeString(name: String): String { + return attribute(name).toString() + } + + private fun Node.attributeBoolean(name: String): Boolean { + return attribute(name)?.toString()?.toBoolean() ?: false + } +} diff --git a/plugins/src/main/java/com/jraska/github/client/firebase/report/MixpanelTestResultsReporter.kt b/plugins/src/main/java/com/jraska/github/client/firebase/report/MixpanelTestResultsReporter.kt new file mode 100644 index 00000000..23bbc7c2 --- /dev/null +++ b/plugins/src/main/java/com/jraska/github/client/firebase/report/MixpanelTestResultsReporter.kt @@ -0,0 +1,68 @@ +package com.jraska.github.client.firebase.report + +import com.jraska.github.client.firebase.TestResult +import com.jraska.github.client.firebase.TestResultReporter +import com.jraska.github.client.firebase.TestSuiteResult +import com.mixpanel.mixpanelapi.ClientDelivery +import com.mixpanel.mixpanelapi.MessageBuilder +import com.mixpanel.mixpanelapi.MixpanelAPI +import org.json.JSONObject + +class MixpanelTestResultsReporter( + private val apiKey: String, + private val api: MixpanelAPI +) : TestResultReporter { + override fun report(results: TestSuiteResult) { + val delivery = ClientDelivery() + + val properties = convertTestSuite(results) + val messageBuilder = MessageBuilder(apiKey) + val moduleEvent = messageBuilder + .event(SINGLE_NAME_FOR_TEST_REPORTS_USER, "Android Test Suite Firebase", JSONObject(properties)) + + delivery.addMessage(moduleEvent) + + results.testResults.forEach { + val testProperties = convertSingleTest(it) + + val estateEvent = messageBuilder.event(SINGLE_NAME_FOR_TEST_REPORTS_USER, "Android Test Firebase", JSONObject(testProperties)) + delivery.addMessage(estateEvent) + } + + api.deliver(delivery) + + println("$FLAG_ICON Test result reported to Mixpanel $FLAG_ICON") + } + + private fun convertSingleTest(testResult: TestResult): Map { + return mutableMapOf( + "className" to testResult.className, + "methodName" to testResult.methodName, + "device" to testResult.device, + "firebaseUrl" to testResult.firebaseUrl, + "fullName" to testResult.fullName, + "failure" to testResult.failure, + "outcome" to testResult.outcome, + "testTime" to testResult.time + ).apply { putAll(testResult.gitInfo.asAnalyticsProperties()) } + } + + private fun convertTestSuite(results: TestSuiteResult): Map { + return mutableMapOf( + "passed" to results.suitePassed, + "suiteTime" to results.time, + "device" to results.device, + "firebaseUrl" to results.firebaseUrl, + "passedCount" to results.testsCount, + "ignoredCount" to results.ignoredCount, + "flakyCount" to results.flakyCount, + "failedCount" to results.failedCount, + "errorsCount" to results.errorsCount + ).apply { putAll(results.gitInfo.asAnalyticsProperties()) } + } + + companion object { + private val FLAG_ICON = "\uD83C\uDFC1" + private val SINGLE_NAME_FOR_TEST_REPORTS_USER = "Test Reporter" + } +} diff --git a/plugins/src/main/java/com/jraska/gradle/buildtime/report/MixpanelReporter.kt b/plugins/src/main/java/com/jraska/gradle/buildtime/report/MixpanelReporter.kt index ed5904bd..78fc9350 100644 --- a/plugins/src/main/java/com/jraska/gradle/buildtime/report/MixpanelReporter.kt +++ b/plugins/src/main/java/com/jraska/gradle/buildtime/report/MixpanelReporter.kt @@ -60,12 +60,11 @@ class MixpanelReporter( "tasksUpToDate" to buildData.taskStatistics.upToDate, "tasksFromCache" to buildData.taskStatistics.fromCache, "tasksExecuted" to buildData.taskStatistics.executed, - "gitBranch" to buildData.gitInfo.branchName, - "gitCommit" to buildData.gitInfo.commitId, - "gitDirty" to buildData.gitInfo.dirty, - "gitStatus" to buildData.gitInfo.status, "buildDataCollectionOverhead" to buildData.buildDataCollectionOverhead - ).apply { putAll(buildData.parameters) } + ).apply { + putAll(buildData.parameters) + putAll(buildData.gitInfo.asAnalyticsProperties()) + } } companion object { diff --git a/plugins/src/main/java/com/jraska/gradle/git/GitInfo.kt b/plugins/src/main/java/com/jraska/gradle/git/GitInfo.kt index 87bb9b5a..ad54f703 100644 --- a/plugins/src/main/java/com/jraska/gradle/git/GitInfo.kt +++ b/plugins/src/main/java/com/jraska/gradle/git/GitInfo.kt @@ -5,4 +5,13 @@ class GitInfo( val commitId: String, val dirty: Boolean, val status: String -) +) { + fun asAnalyticsProperties(): Map { + return mapOf( + "gitBranch" to branchName, + "gitCommit" to commitId, + "gitDirty" to dirty, + "gitStatus" to status, + ) + } +} diff --git a/plugins/src/test/kotlin/com/jraska/github/client/firebase/report/FirebaseResultExtractorTest.kt b/plugins/src/test/kotlin/com/jraska/github/client/firebase/report/FirebaseResultExtractorTest.kt new file mode 100644 index 00000000..2215f539 --- /dev/null +++ b/plugins/src/test/kotlin/com/jraska/github/client/firebase/report/FirebaseResultExtractorTest.kt @@ -0,0 +1,119 @@ +package com.jraska.github.client.firebase.report + +import com.jraska.github.client.firebase.TestOutcome +import com.jraska.gradle.git.GitInfo +import org.assertj.core.api.Assertions.assertThat +import org.junit.Before +import org.junit.Test + +class FirebaseResultExtractorTest { + + lateinit var extractor: FirebaseResultExtractor + + @Before + fun setUp() { + extractor = FirebaseResultExtractor("someUrl", GitInfo("exampleBrach", "123", false, ""), "someDevice") + } + + @Test + fun whenSuccessfulResult_thenParsesCorrectly() { + val suiteResult = extractor.extract(SUCCESS_RESULT) + + assertThat(suiteResult.failedCount).isZero() + assertThat(suiteResult.ignoredCount).isZero() + assertThat(suiteResult.testsCount).isEqualTo(14) + assertThat(suiteResult.flakyCount).isZero() + assertThat(suiteResult.suitePassed).isTrue() + assertThat(suiteResult.time).isEqualTo(15.511) + assertThat(suiteResult.testResults).hasSize(14) + + val firstTest = suiteResult.testResults[0] + assertThat(firstTest.time).isEqualTo(0.026) + assertThat(firstTest.outcome).isEqualTo(TestOutcome.PASSED) + assertThat(firstTest.className).isEqualTo("com.jraska.github.client.AppSetupTest") + assertThat(firstTest.methodName).isEqualTo("appCreateEventFired") + assertThat(firstTest.fullName).isEqualTo("com.jraska.github.client.AppSetupTest#appCreateEventFired") + + val ninthTest = suiteResult.testResults[8] + assertThat(ninthTest.time).isEqualTo(1.182) + assertThat(ninthTest.outcome).isEqualTo(TestOutcome.PASSED) + assertThat(ninthTest.className).isEqualTo("com.jraska.github.client.users.UsersActivityFlowTest") + assertThat(ninthTest.methodName).isEqualTo("whenStarts_thenDisplaysUsers") + assertThat(ninthTest.fullName).isEqualTo("com.jraska.github.client.users.UsersActivityFlowTest#whenStarts_thenDisplaysUsers") + } + + @Test + fun whenErrorResult_thenParsesCorrectly() { + val suiteResult = extractor.extract(ERROR_RESULT) + + assertThat(suiteResult.failedCount).isOne() + assertThat(suiteResult.ignoredCount).isZero() + assertThat(suiteResult.testsCount).isEqualTo(14) + assertThat(suiteResult.flakyCount).isZero() + assertThat(suiteResult.suitePassed).isTrue() + assertThat(suiteResult.time).isEqualTo(13.846) + assertThat(suiteResult.testResults).hasSize(14) + + val firstTest = suiteResult.testResults[0] + assertThat(firstTest.time).isEqualTo(0.0) + assertThat(firstTest.outcome).isEqualTo(TestOutcome.PASSED) + assertThat(firstTest.className).isEqualTo("com.jraska.github.client.AppSetupTest") + assertThat(firstTest.methodName).isEqualTo("appCreateEventFired") + assertThat(firstTest.failure).isEmpty() + assertThat(firstTest.fullName).isEqualTo("com.jraska.github.client.AppSetupTest#appCreateEventFired") + + + val failedTest = suiteResult.testResults[7] + assertThat(failedTest.time).isEqualTo(0.853) + assertThat(failedTest.outcome).isEqualTo(TestOutcome.FAILED) + assertThat(failedTest.className).isEqualTo("com.jraska.github.client.settings.SettingsTest") + assertThat(failedTest.methodName).isEqualTo("whenConsoleClicked_thenConsoleOpens") + assertThat(failedTest.fullName).isEqualTo("com.jraska.github.client.settings.SettingsTest#whenConsoleClicked_thenConsoleOpens") + assertThat(failedTest.failure).startsWith("androidx.test.espresso.NoMatchingViewException: No views in hierarchy found matching: with") + } + + companion object { + val SUCCESS_RESULT = + """ + + + + + + + + + + + + + + + + + + """.trimIndent() + + val ERROR_RESULT = """ + + + + + + + + + + + androidx.test.espresso.NoMatchingViewException: No views in hierarchy found matching: with id is.runner.TestExecutor.execute(TestExecutor.java:56) at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:395) at android.app.Instrumentation .run(Instrumentation.java:2196) + + + + + + + + + """.trimIndent() + } +} From 5ef7a222f26af2c3792c74cab45822a1d3d7842e Mon Sep 17 00:00:00 2001 From: Josef Raska <6277721+jraska@users.noreply.github.com> Date: Sat, 14 Nov 2020 23:42:54 +0100 Subject: [PATCH 02/14] Simplify Fiebase Test Lab plugin, proper computing of passed property --- .../client/firebase/FirebaseTestLabPlugin.kt | 43 ++++++------------- .../report/FirebaseResultExtractor.kt | 4 +- .../report/FirebaseResultExtractorTest.kt | 2 +- 3 files changed, 16 insertions(+), 33 deletions(-) diff --git a/plugins/src/main/java/com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt b/plugins/src/main/java/com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt index f3a77258..3c0005d6 100644 --- a/plugins/src/main/java/com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt +++ b/plugins/src/main/java/com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt @@ -17,10 +17,7 @@ class FirebaseTestLabPlugin : Plugin { override fun apply(theProject: Project) { theProject.afterEvaluate { project -> - var resultsFileToPull: String? = null - lateinit var deviceExecuted: String - - val executeTestsInTestLab = project.tasks.register("executeInstrumentedTestsOnFirebase", Exec::class.java) { firebaseTask -> + project.tasks.register("runInstrumentedTestsOnFirebase", Exec::class.java) { firebaseTask -> firebaseTask.doFirst { project.exec("gcloud config set project github-client-25b47") val credentialsPath = project.createCredentialsFile() @@ -33,11 +30,10 @@ class FirebaseTestLabPlugin : Plugin { val androidVersion = "29" val device = "model=$deviceName,version=$androidVersion,locale=en,orientation=portrait" val resultDir = DateTimeFormatter.ISO_DATE_TIME.format(LocalDateTime.now()) - deviceExecuted = device val fcmKey = System.getenv("FCM_API_KEY") - resultsFileToPull = "gs://test-lab-twsawhz0hy5am-h35y3vymzadax/$resultDir/$deviceName-$androidVersion-en-portrait/test_result_1.xml" + val resultsFileToPull = "gs://test-lab-twsawhz0hy5am-h35y3vymzadax/$resultDir/$deviceName-$androidVersion-en-portrait/test_result_1.xml" firebaseTask.commandLine = ("gcloud " + @@ -51,20 +47,11 @@ class FirebaseTestLabPlugin : Plugin { .split(' ') firebaseTask.isIgnoreExitValue = true - firebaseTask.dependsOn(project.tasks.named("assembleDebugAndroidTest")) - firebaseTask.dependsOn(project.tasks.named("assembleDebug")) - } - - val reportResults = project.tasks.register("reportFirebaseXmlResults", Exec::class.java) { pullTask -> - pullTask.dependsOn(executeTestsInTestLab) - - val outputFile = "${project.buildDir}/test-results/firebase-tests-results.xml" - pullTask.doFirst { - pullTask.commandLine = "gsutil cp $resultsFileToPull $outputFile".split(' ') - } + firebaseTask.doLast { + val outputFile = "${project.buildDir}/test-results/firebase-tests-results.xml" + project.exec("gsutil cp $resultsFileToPull $outputFile") - pullTask.doLast { - val result = FirebaseResultExtractor("noUrlYet", GitInfoProvider.gitInfo(project), deviceExecuted).extract(File(outputFile).readText()) + val result = FirebaseResultExtractor("noUrlYet", GitInfoProvider.gitInfo(project), device).extract(File(outputFile).readText()) val mixpanelToken: String? = System.getenv("GITHUB_CLIENT_MIXPANEL_API_KEY") val reporter = if (mixpanelToken == null) { println("'GITHUB_CLIENT_MIXPANEL_API_KEY' not set, data will be reported to console only") @@ -74,21 +61,15 @@ class FirebaseTestLabPlugin : Plugin { } reporter.report(result) - } - } - - project.tasks.register("runInstrumentedTestsOnFirebase") { - it.dependsOn(executeTestsInTestLab) - it.dependsOn(reportResults) - it.doLast { - if (executeTestsInTestLab.isPresent) { - val execResult = executeTestsInTestLab.get().execResult!! - if (execResult.exitValue != 0) { - execResult.rethrowFailure() - } + val execResult = firebaseTask.execResult!! + if (execResult.exitValue != 0) { + execResult.rethrowFailure() } } + + firebaseTask.dependsOn(project.tasks.named("assembleDebugAndroidTest")) + firebaseTask.dependsOn(project.tasks.named("assembleDebug")) } } } diff --git a/plugins/src/main/java/com/jraska/github/client/firebase/report/FirebaseResultExtractor.kt b/plugins/src/main/java/com/jraska/github/client/firebase/report/FirebaseResultExtractor.kt index 4920c6e4..6a3ef27f 100644 --- a/plugins/src/main/java/com/jraska/github/client/firebase/report/FirebaseResultExtractor.kt +++ b/plugins/src/main/java/com/jraska/github/client/firebase/report/FirebaseResultExtractor.kt @@ -52,6 +52,8 @@ class FirebaseResultExtractor( ) } + val suitePassed = errorsCount == 0 && failedCount == 0 + return TestSuiteResult( testResults = tests, time = time, @@ -63,7 +65,7 @@ class FirebaseResultExtractor( failedCount = failedCount, flakyCount = flakyTests, ignoredCount = ignoredCount, - suitePassed = true + suitePassed = suitePassed ) } diff --git a/plugins/src/test/kotlin/com/jraska/github/client/firebase/report/FirebaseResultExtractorTest.kt b/plugins/src/test/kotlin/com/jraska/github/client/firebase/report/FirebaseResultExtractorTest.kt index 2215f539..4c13456f 100644 --- a/plugins/src/test/kotlin/com/jraska/github/client/firebase/report/FirebaseResultExtractorTest.kt +++ b/plugins/src/test/kotlin/com/jraska/github/client/firebase/report/FirebaseResultExtractorTest.kt @@ -50,7 +50,7 @@ class FirebaseResultExtractorTest { assertThat(suiteResult.ignoredCount).isZero() assertThat(suiteResult.testsCount).isEqualTo(14) assertThat(suiteResult.flakyCount).isZero() - assertThat(suiteResult.suitePassed).isTrue() + assertThat(suiteResult.suitePassed).isFalse() assertThat(suiteResult.time).isEqualTo(13.846) assertThat(suiteResult.testResults).hasSize(14) From 1faa697382d053a854bc24b799fda4924333f4b7 Mon Sep 17 00:00:00 2001 From: Josef Raska <6277721+jraska@users.noreply.github.com> Date: Sat, 14 Nov 2020 23:45:14 +0100 Subject: [PATCH 03/14] Bette formatting into method --- .../report/FirebaseResultExtractor.kt | 51 ++++++++++--------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/plugins/src/main/java/com/jraska/github/client/firebase/report/FirebaseResultExtractor.kt b/plugins/src/main/java/com/jraska/github/client/firebase/report/FirebaseResultExtractor.kt index 6a3ef27f..06dfd7b7 100644 --- a/plugins/src/main/java/com/jraska/github/client/firebase/report/FirebaseResultExtractor.kt +++ b/plugins/src/main/java/com/jraska/github/client/firebase/report/FirebaseResultExtractor.kt @@ -26,31 +26,7 @@ class FirebaseResultExtractor( val tests = (testSuiteNode.get("testcase") as NodeList) .map { it as Node } .filter { it.attributeString("name") != "null" } - .map { testNode -> - - val flaky = testNode.attributeBoolean("flaky") - val failure = ((testNode.get("failure") as NodeList?)?.firstOrNull() as Node?)?.text() ?: "" - - val outcome = when { - flaky -> TestOutcome.FLAKY - failure.isNotEmpty() -> TestOutcome.FAILED - else -> TestOutcome.PASSED - } - - val methodName = testNode.attributeString("name") - val className = testNode.attributeString("classname") - TestResult( - methodName = methodName, - className = className, - time = testNode.attributeDouble("time"), - failure = failure, - outcome = outcome, - firebaseUrl = firebaseUrl, - gitInfo = gitInfo, - device = device, - fullName = "$className#$methodName" - ) - } + .map { parseTestResult(it) } val suitePassed = errorsCount == 0 && failedCount == 0 @@ -69,6 +45,31 @@ class FirebaseResultExtractor( ) } + private fun parseTestResult(testNode: Node): TestResult { + val flaky = testNode.attributeBoolean("flaky") + val failure = ((testNode.get("failure") as NodeList?)?.firstOrNull() as Node?)?.text() ?: "" + + val outcome = when { + flaky -> TestOutcome.FLAKY + failure.isNotEmpty() -> TestOutcome.FAILED + else -> TestOutcome.PASSED + } + + val methodName = testNode.attributeString("name") + val className = testNode.attributeString("classname") + return TestResult( + methodName = methodName, + className = className, + time = testNode.attributeDouble("time"), + failure = failure, + outcome = outcome, + firebaseUrl = firebaseUrl, + gitInfo = gitInfo, + device = device, + fullName = "$className#$methodName" + ) + } + private fun Node.attributeInt(name: String): Int { return attribute(name)?.toString()?.toInt() ?: 0 } From 1b95438b9e416d35d5475d029838a3463fb503c6 Mon Sep 17 00:00:00 2001 From: Josef Raska <6277721+jraska@users.noreply.github.com> Date: Sat, 14 Nov 2020 23:45:49 +0100 Subject: [PATCH 04/14] Error to make tests fail --- .../com/jraska/github/client/users/UsersActivityFlowTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/androidTest/java/com/jraska/github/client/users/UsersActivityFlowTest.kt b/app/src/androidTest/java/com/jraska/github/client/users/UsersActivityFlowTest.kt index 38359a49..7dbb8016 100644 --- a/app/src/androidTest/java/com/jraska/github/client/users/UsersActivityFlowTest.kt +++ b/app/src/androidTest/java/com/jraska/github/client/users/UsersActivityFlowTest.kt @@ -35,7 +35,7 @@ class UsersActivityFlowTest { onView(withText("defunkt")).perform(click()) onView(withText("dotjs")).check(matches(isDisplayed())) onView(withText("facebox")).perform(click()) - onView(withText("1941")).check(matches(isDisplayed())) + onView(withText("1942")).check(matches(isDisplayed())) } @Test @@ -43,7 +43,7 @@ class UsersActivityFlowTest { fun whenSettings_thenReportsEvent() { onView(withId(R.id.action_settings)).perform(click()) onView(withHint("Value")).perform(ViewActions.typeText("0.01")) - onView(withText("Purchase")).perform(click()) + onView(withText("Purchas")).perform(click()) val event = recordedEvents().findLast { event -> event.name == FirebaseAnalytics.Event.ECOMMERCE_PURCHASE } assertThat(event).isNotNull From 15692bdda3532efc052b26120f2d562bc13e04b7 Mon Sep 17 00:00:00 2001 From: Josef Raska <6277721+jraska@users.noreply.github.com> Date: Sat, 14 Nov 2020 23:50:16 +0100 Subject: [PATCH 05/14] Fixed failed test --- .../com/jraska/github/client/users/UsersActivityFlowTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/androidTest/java/com/jraska/github/client/users/UsersActivityFlowTest.kt b/app/src/androidTest/java/com/jraska/github/client/users/UsersActivityFlowTest.kt index 7dbb8016..38359a49 100644 --- a/app/src/androidTest/java/com/jraska/github/client/users/UsersActivityFlowTest.kt +++ b/app/src/androidTest/java/com/jraska/github/client/users/UsersActivityFlowTest.kt @@ -35,7 +35,7 @@ class UsersActivityFlowTest { onView(withText("defunkt")).perform(click()) onView(withText("dotjs")).check(matches(isDisplayed())) onView(withText("facebox")).perform(click()) - onView(withText("1942")).check(matches(isDisplayed())) + onView(withText("1941")).check(matches(isDisplayed())) } @Test @@ -43,7 +43,7 @@ class UsersActivityFlowTest { fun whenSettings_thenReportsEvent() { onView(withId(R.id.action_settings)).perform(click()) onView(withHint("Value")).perform(ViewActions.typeText("0.01")) - onView(withText("Purchas")).perform(click()) + onView(withText("Purchase")).perform(click()) val event = recordedEvents().findLast { event -> event.name == FirebaseAnalytics.Event.ECOMMERCE_PURCHASE } assertThat(event).isNotNull From 0dd5005a0034be6c85c97db8448d2331305d4845 Mon Sep 17 00:00:00 2001 From: Josef Raska <6277721+jraska@users.noreply.github.com> Date: Sat, 14 Nov 2020 23:56:32 +0100 Subject: [PATCH 06/14] Add passsed and tests count --- .../java/com/jraska/github/client/firebase/TestSuiteResult.kt | 1 + .../github/client/firebase/report/FirebaseResultExtractor.kt | 2 ++ .../client/firebase/report/MixpanelTestResultsReporter.kt | 3 ++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/src/main/java/com/jraska/github/client/firebase/TestSuiteResult.kt b/plugins/src/main/java/com/jraska/github/client/firebase/TestSuiteResult.kt index 2095ef88..7b151c31 100644 --- a/plugins/src/main/java/com/jraska/github/client/firebase/TestSuiteResult.kt +++ b/plugins/src/main/java/com/jraska/github/client/firebase/TestSuiteResult.kt @@ -9,6 +9,7 @@ data class TestSuiteResult( val testsCount: Int, val failedCount: Int, val errorsCount: Int, + val passedCount: Int, val ignoredCount: Int, val flakyCount: Int, val firebaseUrl: String, diff --git a/plugins/src/main/java/com/jraska/github/client/firebase/report/FirebaseResultExtractor.kt b/plugins/src/main/java/com/jraska/github/client/firebase/report/FirebaseResultExtractor.kt index 06dfd7b7..1c025e5a 100644 --- a/plugins/src/main/java/com/jraska/github/client/firebase/report/FirebaseResultExtractor.kt +++ b/plugins/src/main/java/com/jraska/github/client/firebase/report/FirebaseResultExtractor.kt @@ -22,6 +22,7 @@ class FirebaseResultExtractor( val failedCount = testSuiteNode.attributeInt("failures") val errorsCount = testSuiteNode.attributeInt("errors") val time = testSuiteNode.attributeDouble("time") + val passedCount = testsCount - ignoredCount - failedCount - errorsCount val tests = (testSuiteNode.get("testcase") as NodeList) .map { it as Node } @@ -38,6 +39,7 @@ class FirebaseResultExtractor( gitInfo = gitInfo, firebaseUrl = firebaseUrl, errorsCount = errorsCount, + passedCount = passedCount, failedCount = failedCount, flakyCount = flakyTests, ignoredCount = ignoredCount, diff --git a/plugins/src/main/java/com/jraska/github/client/firebase/report/MixpanelTestResultsReporter.kt b/plugins/src/main/java/com/jraska/github/client/firebase/report/MixpanelTestResultsReporter.kt index 23bbc7c2..900cc25b 100644 --- a/plugins/src/main/java/com/jraska/github/client/firebase/report/MixpanelTestResultsReporter.kt +++ b/plugins/src/main/java/com/jraska/github/client/firebase/report/MixpanelTestResultsReporter.kt @@ -53,7 +53,8 @@ class MixpanelTestResultsReporter( "suiteTime" to results.time, "device" to results.device, "firebaseUrl" to results.firebaseUrl, - "passedCount" to results.testsCount, + "passedCount" to results.passedCount, + "testsCount" to results.testsCount, "ignoredCount" to results.ignoredCount, "flakyCount" to results.flakyCount, "failedCount" to results.failedCount, From bd6da8c8f7803ae9d8b41b4de34480251ffac7e0 Mon Sep 17 00:00:00 2001 From: Josef Raska <6277721+jraska@users.noreply.github.com> Date: Sat, 14 Nov 2020 23:57:29 +0100 Subject: [PATCH 07/14] Asserting on exit code --- .../jraska/github/client/firebase/FirebaseTestLabPlugin.kt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/plugins/src/main/java/com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt b/plugins/src/main/java/com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt index 3c0005d6..e5dadfc8 100644 --- a/plugins/src/main/java/com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt +++ b/plugins/src/main/java/com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt @@ -62,10 +62,7 @@ class FirebaseTestLabPlugin : Plugin { reporter.report(result) - val execResult = firebaseTask.execResult!! - if (execResult.exitValue != 0) { - execResult.rethrowFailure() - } + firebaseTask.execResult!!.assertNormalExitValue() } firebaseTask.dependsOn(project.tasks.named("assembleDebugAndroidTest")) From da537d21ff972db6acdab6fceb66d252171df471 Mon Sep 17 00:00:00 2001 From: Josef Raska <6277721+jraska@users.noreply.github.com> Date: Sat, 14 Nov 2020 23:57:56 +0100 Subject: [PATCH 08/14] Intoduce test failure --- .../com/jraska/github/client/users/UsersActivityFlowTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/androidTest/java/com/jraska/github/client/users/UsersActivityFlowTest.kt b/app/src/androidTest/java/com/jraska/github/client/users/UsersActivityFlowTest.kt index 38359a49..705abc82 100644 --- a/app/src/androidTest/java/com/jraska/github/client/users/UsersActivityFlowTest.kt +++ b/app/src/androidTest/java/com/jraska/github/client/users/UsersActivityFlowTest.kt @@ -55,7 +55,7 @@ class UsersActivityFlowTest { fun whenAbout_thenOpensAbout() { onView(withId(R.id.action_about)).perform(click()) - onView(withText("by Josef Raska")).check(matches(isDisplayed())) + onView(withText("by Josf Raska")).check(matches(isDisplayed())) } @Test From 0d8c24be636eccdc25a1f38dcfa2ebcb9a239b38 Mon Sep 17 00:00:00 2001 From: Josef Raska <6277721+jraska@users.noreply.github.com> Date: Sun, 15 Nov 2020 00:00:21 +0100 Subject: [PATCH 09/14] Print exit code --- .../com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/src/main/java/com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt b/plugins/src/main/java/com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt index e5dadfc8..1ebe7bdb 100644 --- a/plugins/src/main/java/com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt +++ b/plugins/src/main/java/com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt @@ -62,6 +62,7 @@ class FirebaseTestLabPlugin : Plugin { reporter.report(result) + println("Exit code is: ${firebaseTask.execResult!!.exitValue}") firebaseTask.execResult!!.assertNormalExitValue() } From f2cec04e50150ccb15771ef79ff7e876d4979342 Mon Sep 17 00:00:00 2001 From: Josef Raska <6277721+jraska@users.noreply.github.com> Date: Sun, 15 Nov 2020 00:19:16 +0100 Subject: [PATCH 10/14] Extract the Firebase link --- .../client/firebase/FirebaseTestLabPlugin.kt | 12 +++- .../firebase/report/FirebaseUrlParser.kt | 12 ++++ .../firebase/report/FirebaseUrlParserTest.kt | 64 +++++++++++++++++++ 3 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 plugins/src/main/java/com/jraska/github/client/firebase/report/FirebaseUrlParser.kt create mode 100644 plugins/src/test/kotlin/com/jraska/github/client/firebase/report/FirebaseUrlParserTest.kt diff --git a/plugins/src/main/java/com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt b/plugins/src/main/java/com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt index 1ebe7bdb..1cbbd283 100644 --- a/plugins/src/main/java/com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt +++ b/plugins/src/main/java/com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt @@ -2,13 +2,16 @@ package com.jraska.github.client.firebase import com.jraska.github.client.firebase.report.ConsoleTestResultReporter import com.jraska.github.client.firebase.report.FirebaseResultExtractor +import com.jraska.github.client.firebase.report.FirebaseUrlParser import com.jraska.github.client.firebase.report.MixpanelTestResultsReporter import com.jraska.gradle.git.GitInfoProvider import com.mixpanel.mixpanelapi.MixpanelAPI +import org.apache.tools.ant.util.TeeOutputStream import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.tasks.Exec import org.gradle.process.ExecResult +import java.io.ByteArrayOutputStream import java.io.File import java.time.LocalDateTime import java.time.format.DateTimeFormatter @@ -47,11 +50,16 @@ class FirebaseTestLabPlugin : Plugin { .split(' ') firebaseTask.isIgnoreExitValue = true + val decorativeStream = ByteArrayOutputStream() + firebaseTask.standardOutput = TeeOutputStream(decorativeStream, firebaseTask.standardOutput) + firebaseTask.doLast { val outputFile = "${project.buildDir}/test-results/firebase-tests-results.xml" project.exec("gsutil cp $resultsFileToPull $outputFile") - val result = FirebaseResultExtractor("noUrlYet", GitInfoProvider.gitInfo(project), device).extract(File(outputFile).readText()) + val firebaseUrl = FirebaseUrlParser.parse(decorativeStream.toString()) + + val result = FirebaseResultExtractor(firebaseUrl, GitInfoProvider.gitInfo(project), device).extract(File(outputFile).readText()) val mixpanelToken: String? = System.getenv("GITHUB_CLIENT_MIXPANEL_API_KEY") val reporter = if (mixpanelToken == null) { println("'GITHUB_CLIENT_MIXPANEL_API_KEY' not set, data will be reported to console only") @@ -61,8 +69,6 @@ class FirebaseTestLabPlugin : Plugin { } reporter.report(result) - - println("Exit code is: ${firebaseTask.execResult!!.exitValue}") firebaseTask.execResult!!.assertNormalExitValue() } diff --git a/plugins/src/main/java/com/jraska/github/client/firebase/report/FirebaseUrlParser.kt b/plugins/src/main/java/com/jraska/github/client/firebase/report/FirebaseUrlParser.kt new file mode 100644 index 00000000..184999b0 --- /dev/null +++ b/plugins/src/main/java/com/jraska/github/client/firebase/report/FirebaseUrlParser.kt @@ -0,0 +1,12 @@ +package com.jraska.github.client.firebase.report + +object FirebaseUrlParser { + private val urlPattern = """Test results will be streamed to \[(\S*)\]""".toPattern() + + fun parse(output: String): String { + val matcher = urlPattern.matcher(output) + + matcher.find() + return matcher.group(1) + } +} diff --git a/plugins/src/test/kotlin/com/jraska/github/client/firebase/report/FirebaseUrlParserTest.kt b/plugins/src/test/kotlin/com/jraska/github/client/firebase/report/FirebaseUrlParserTest.kt new file mode 100644 index 00000000..23efae1f --- /dev/null +++ b/plugins/src/test/kotlin/com/jraska/github/client/firebase/report/FirebaseUrlParserTest.kt @@ -0,0 +1,64 @@ +package com.jraska.github.client.firebase.report + +import org.assertj.core.api.Assertions.assertThat +import org.junit.Test + +class FirebaseUrlParserTest { + @Test + fun findsUrlProperly() { + val url = FirebaseUrlParser.parse(EXAMPLE_OUTPUT) + + assertThat(url).isEqualTo("https://console.firebase.google.com/project/github-client-25b47/testlab/histories/bh.45e06288a93d3fad/matrices/4937539158600939569") + } + + companion object { + val EXAMPLE_OUTPUT = """ + Have questions, feedback, or issues? Get support by visiting: + https://firebase.google.com/support/ + + Uploading [/home/circleci/code/app/build/outputs/apk/debug/app-debug.apk] to Firebase Test Lab... + Uploading [/home/circleci/code/app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk] to Firebase Test Lab... + Raw results will be stored in your GCS bucket at [https://console.developers.google.com/storage/browser/test-lab-twsawhz0hy5am-h35y3vymzadax/2020-11-14T23:02:48.776162/] + + Test [matrix-1vohggy3nox8r] has been created in the Google Cloud. + Firebase Test Lab will execute your instrumentation test on 1 device(s). + Creating individual test executions... + ..............................................done. + + Test results will be streamed to [https://console.firebase.google.com/project/github-client-25b47/testlab/histories/bh.45e06288a93d3fad/matrices/4937539158600939569]. + 23:03:51 Test is Pending + 23:04:27 Starting attempt 1. + 23:04:27 Started logcat recording. + 23:04:27 Started crash monitoring. + 23:04:27 Preparing device. + 23:04:27 Test is Running + 23:04:39 Logging in to Google account on device. + 23:04:39 Installing apps. + 23:04:39 Retrieving Pre-Test Package Stats information from the device. + 23:04:39 Retrieving Performance Environment information from the device. + 23:04:39 Started crash detection. + 23:04:39 Started Out of memory detection + 23:04:39 Started video recording. + 23:04:39 Starting instrumentation test. + 23:05:04 Completed instrumentation test. + 23:05:04 Stopped video recording. + 23:05:04 Retrieving Post-test Package Stats information from the device. + 23:05:04 Logging out of Google account on device. + 23:05:04 Stopped crash monitoring. + 23:05:04 Stopped logcat recording. + 23:05:04 Done. Test time = 20 (secs) + 23:05:04 Starting results processing. Attempt: 1 + 23:05:16 Completed results processing. Time taken = 6 (secs) + 23:05:16 Test is Finished + + Instrumentation testing complete. + + More details are available at [https://console.firebase.google.com/project/github-client-25b47/testlab/histories/bh.45e06288a93d3fad/matrices/4937539158600939569]. + ┌─────────┬──────────────────────┬────────────────────────────────┐ + │ OUTCOME │ TEST_AXIS_VALUE │ TEST_DETAILS │ + ├─────────┼──────────────────────┼────────────────────────────────┤ + │ Failed │ flame-29-en-portrait │ 1 test cases failed, 13 passed │ + └─────────┴──────────────────────┴────────────────────────────────┘ + """.trimIndent() + } +} From c2feff32c510a28e3ce7f9d5093e91f343b51060 Mon Sep 17 00:00:00 2001 From: Josef Raska <6277721+jraska@users.noreply.github.com> Date: Sun, 15 Nov 2020 00:21:19 +0100 Subject: [PATCH 11/14] Fir error test --- .../com/jraska/github/client/users/UsersActivityFlowTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/androidTest/java/com/jraska/github/client/users/UsersActivityFlowTest.kt b/app/src/androidTest/java/com/jraska/github/client/users/UsersActivityFlowTest.kt index 705abc82..38359a49 100644 --- a/app/src/androidTest/java/com/jraska/github/client/users/UsersActivityFlowTest.kt +++ b/app/src/androidTest/java/com/jraska/github/client/users/UsersActivityFlowTest.kt @@ -55,7 +55,7 @@ class UsersActivityFlowTest { fun whenAbout_thenOpensAbout() { onView(withId(R.id.action_about)).perform(click()) - onView(withText("by Josf Raska")).check(matches(isDisplayed())) + onView(withText("by Josef Raska")).check(matches(isDisplayed())) } @Test From dfb779edfc81f0398f676fde96e4c69cf6a3bfd4 Mon Sep 17 00:00:00 2001 From: Josef Raska <6277721+jraska@users.noreply.github.com> Date: Sun, 15 Nov 2020 00:26:06 +0100 Subject: [PATCH 12/14] Try to fix the TeeOutputStream --- .../com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/src/main/java/com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt b/plugins/src/main/java/com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt index 1cbbd283..26bf4fbc 100644 --- a/plugins/src/main/java/com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt +++ b/plugins/src/main/java/com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt @@ -51,7 +51,7 @@ class FirebaseTestLabPlugin : Plugin { firebaseTask.isIgnoreExitValue = true val decorativeStream = ByteArrayOutputStream() - firebaseTask.standardOutput = TeeOutputStream(decorativeStream, firebaseTask.standardOutput) + firebaseTask.standardOutput = TeeOutputStream(decorativeStream, System.out) firebaseTask.doLast { val outputFile = "${project.buildDir}/test-results/firebase-tests-results.xml" From 47ce3a72a32c37f1341fd88497ecf4d2df256e6c Mon Sep 17 00:00:00 2001 From: Josef Raska <6277721+jraska@users.noreply.github.com> Date: Sun, 15 Nov 2020 00:33:29 +0100 Subject: [PATCH 13/14] Set error streamas well --- .../com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/src/main/java/com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt b/plugins/src/main/java/com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt index 26bf4fbc..ff48e581 100644 --- a/plugins/src/main/java/com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt +++ b/plugins/src/main/java/com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt @@ -52,6 +52,7 @@ class FirebaseTestLabPlugin : Plugin { val decorativeStream = ByteArrayOutputStream() firebaseTask.standardOutput = TeeOutputStream(decorativeStream, System.out) + firebaseTask.errorOutput = TeeOutputStream(decorativeStream, System.err) firebaseTask.doLast { val outputFile = "${project.buildDir}/test-results/firebase-tests-results.xml" From 0e30d08e77889d27dcaaccbb1b81e8fa7c913481 Mon Sep 17 00:00:00 2001 From: Josef Raska <6277721+jraska@users.noreply.github.com> Date: Sun, 15 Nov 2020 00:34:11 +0100 Subject: [PATCH 14/14] Setting only error stream --- .../com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/src/main/java/com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt b/plugins/src/main/java/com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt index ff48e581..e267c595 100644 --- a/plugins/src/main/java/com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt +++ b/plugins/src/main/java/com/jraska/github/client/firebase/FirebaseTestLabPlugin.kt @@ -51,7 +51,6 @@ class FirebaseTestLabPlugin : Plugin { firebaseTask.isIgnoreExitValue = true val decorativeStream = ByteArrayOutputStream() - firebaseTask.standardOutput = TeeOutputStream(decorativeStream, System.out) firebaseTask.errorOutput = TeeOutputStream(decorativeStream, System.err) firebaseTask.doLast {