diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c979798b8..881e9d54e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -35,12 +35,15 @@ android test: - start-emulator.sh # run normal and screenshot tests together (exclude Large tests) - ./gradlew -Djava.security.egd=file:/dev/urandom connectedAndroidTest -Pandroid.testInstrumentationRunnerArguments.notAnnotation=androidx.test.filters.LargeTest + after_script: + - adb pull /sdcard/Pictures/screenshots artifacts: name: "${CI_PROJECT_PATH}_${CI_JOB_STAGE}_${CI_COMMIT_REF_NAME}_${CI_COMMIT_SHA}" paths: - kernel.log - logcat.txt - briar-android/build/reports/androidTests/connected/flavors/* + - screenshots expire_in: 3 days when: on_failure when: manual diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/ScreenshotOnFailureRule.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/ScreenshotOnFailureRule.java new file mode 100644 index 000000000..87b8b7833 --- /dev/null +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/ScreenshotOnFailureRule.java @@ -0,0 +1,65 @@ +package org.briarproject.briar.android; + +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +import java.io.IOException; +import java.util.HashSet; +import java.util.concurrent.atomic.AtomicBoolean; + +import androidx.test.espresso.Espresso; +import androidx.test.espresso.FailureHandler; +import androidx.test.espresso.base.DefaultFailureHandler; +import androidx.test.runner.screenshot.BasicScreenCaptureProcessor; +import androidx.test.runner.screenshot.ScreenCapture; +import androidx.test.runner.screenshot.ScreenCaptureProcessor; +import androidx.test.runner.screenshot.Screenshot; + +import static androidx.test.core.app.ApplicationProvider.getApplicationContext; + +@NotNullByDefault +public class ScreenshotOnFailureRule implements TestRule { + + FailureHandler defaultFailureHandler = + new DefaultFailureHandler(getApplicationContext()); + + @Override + public Statement apply(Statement base, Description description) { + HashSet processors = new HashSet<>(1); + processors.add(new BasicScreenCaptureProcessor()); + Screenshot.addScreenCaptureProcessors(processors); + return new Statement() { + @Override + public void evaluate() throws Throwable { + AtomicBoolean errorHandled = new AtomicBoolean(false); + Espresso.setFailureHandler((throwable, matcher) -> { + takeScreenshot(description); + errorHandled.set(true); + defaultFailureHandler.handle(throwable, matcher); + }); + try { + base.evaluate(); + } catch (Throwable t) { + if (!errorHandled.get()) { + takeScreenshot(description); + } + throw t; + } + } + }; + } + + private void takeScreenshot(Description description) { + String name = description.getTestClass().getSimpleName(); + ScreenCapture capture = Screenshot.capture(); + capture.setName(name); + try { + capture.process(); + } catch (IOException e) { + e.printStackTrace(); + } + } + +} diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/UiTest.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/UiTest.java index 030b68dc9..63691223d 100644 --- a/briar-android/src/androidTest/java/org/briarproject/briar/android/UiTest.java +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/UiTest.java @@ -10,6 +10,7 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.settings.Settings; import org.briarproject.bramble.api.settings.SettingsManager; import org.briarproject.briar.R; +import org.junit.ClassRule; import javax.inject.Inject; @@ -23,6 +24,10 @@ import static org.briarproject.briar.android.settings.SettingsFragment.SETTINGS_ @SuppressWarnings("WeakerAccess") public abstract class UiTest { + @ClassRule + public static final ScreenshotOnFailureRule screenshotOnFailureRule = + new ScreenshotOnFailureRule(); + protected final String USERNAME = getApplicationContext().getString(R.string.screenshot_alice); protected static final String PASSWORD = "123456";