diff --git a/app/.classpath b/app/.classpath index 51769745b2c3fa7f59c0b88bad65762059ee0812..4a04201ca2839bf43ab901d599c311dafcc5754b 100644 --- a/app/.classpath +++ b/app/.classpath @@ -1,9 +1,6 @@ - - - - - - + + + diff --git a/app/.project b/app/.project index b3936bdbae536d4a40bc31f88cee7fd26125a808..dfb7557e4b5eed3aa13fddbbb9d95417d834c287 100644 --- a/app/.project +++ b/app/.project @@ -1,22 +1,27 @@ - OwnCloudNotes + app - com.android.ide.eclipse.adt.ResourceManagerBuilder + org.eclipse.jdt.core.javabuilder - com.android.ide.eclipse.adt.PreCompilerBuilder + org.eclipse.buildship.core.gradleprojectbuilder - org.eclipse.jdt.core.javabuilder + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder @@ -29,5 +34,6 @@ com.android.ide.eclipse.adt.AndroidNature org.eclipse.jdt.core.javanature + org.eclipse.buildship.core.gradleprojectnature diff --git a/app/.settings/org.eclipse.buildship.core.prefs b/app/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 0000000000000000000000000000000000000000..b1886adb46c085de842f1283c1a3c25151bfc988 --- /dev/null +++ b/app/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,2 @@ +connection.project.dir=.. +eclipse.preferences.version=1 diff --git a/app/build.gradle b/app/build.gradle index 4fd4de88de9be15f38d6e736e316c078bf162842..34cdb4f2fafd65d6726aaab10eacd43bfaf9997b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,9 +1,32 @@ apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' + +//screenshot testing +apply plugin: 'com.facebook.testing.screenshot' + + + +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + //for screenshot testing + + } +} android { compileSdkVersion 28 buildToolsVersion '29.0.1' + useLibrary 'android.test.runner' + useLibrary 'android.test.base' + useLibrary 'android.test.mock' + + compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 @@ -13,8 +36,10 @@ android { applicationId "foundation.e.notes" minSdkVersion 24 targetSdkVersion 28 - versionCode 49 + versionCode 49 versionName "1.0.1" + + testInstrumentationRunner "com.facebook.testing.screenshot.ScreenshotTestRunner" } buildTypes { release { @@ -32,7 +57,7 @@ android { } dependencies { - implementation project(':cert4android') + implementation project(':cert4android') //changed implementation 'io.reactivex:rxandroid:1.2.1' implementation 'io.reactivex:rxjava:1.3.8' @@ -53,4 +78,31 @@ dependencies { implementation "com.google.android.material:material:1.0.0" implementation fileTree(dir: 'libs', include: ['*.jar']) + + androidTestImplementation 'androidx.test:runner:1.1.0' + androidTestImplementation 'androidx.test:rules:1.1.0' + // Optional -- Hamcrest library + androidTestImplementation 'org.hamcrest:hamcrest-library:1.3' + // Optional -- UI testing with Espresso + androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0' + // Optional -- UI testing with UI Automator + androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0' + + // Standard Android View Plugins (TextView, etc) + implementation 'com.facebook.testing.screenshot:layout-hierarchy-common:0.13.0' + + // Litho Component Plugins + implementation 'com.facebook.testing.screenshot:layout-hierarchy-litho:0.13.0' + + // Core library + androidTestImplementation 'androidx.test:core:1.0.0' + implementation "androidx.core:core-ktx:+" + //implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + androidTestImplementation "androidx.appcompat:appcompat:1.1.0" + + +} +repositories { + maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' } + mavenCentral() } diff --git a/app/src/androidTest/java/com/facebook/testing/screenshot/ExampleScreenshotTest.java b/app/src/androidTest/java/com/facebook/testing/screenshot/ExampleScreenshotTest.java new file mode 100644 index 0000000000000000000000000000000000000000..b2e4d0327fd123767e510f3f084a2b7d06340d5d --- /dev/null +++ b/app/src/androidTest/java/com/facebook/testing/screenshot/ExampleScreenshotTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.facebook.testing.screenshot; + +import android.content.Context; +import android.test.InstrumentationTestCase; +import android.view.LayoutInflater; +import androidx.test.platform.app.InstrumentationRegistry; +import com.facebook.litho.LithoView; +import com.facebook.testing.screenshot.Screenshot; +import com.facebook.testing.screenshot.ViewHelpers; +import org.junit.Test; + +import static androidx.test.core.app.ApplicationProvider.getApplicationContext; +import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; +import androidx.test.core.app.ApplicationProvider; + +import foundation.e.notes.R; //in order to use the right R.layout + +public class ExampleScreenshotTest { + @Test + public void doScreenshot() { + /* + * Create and set up your view some how. This might be inflating, + * or creating from a view class. You might want to set properties + * on the view. + */ + LayoutInflater inflater = LayoutInflater.from(getApplicationContext()); //removed the first argument getInstrumentation(), + getApplicationContext().setTheme(R.style.AppTheme); + android.view.View view = inflater.inflate(R.layout.activity_account, null, false); + + /* + * Measure and layout the view. In this example we give an exact + * width but all the height to be WRAP_CONTENT. + */ + ViewHelpers.setupView(view).setExactWidthDp(300).layout(); + + /* + * Take the actual screenshot. At the end of this call the screenshot + * is stored on the device, and the gradle plugin takes care of + * pulling it and displaying it to you in nice ways. + */ + Screenshot.snap(view).record(); + } +} \ No newline at end of file diff --git a/app/src/androidTest/java/com/facebook/testing/screenshot/ScreenshotTestRunner.kt b/app/src/androidTest/java/com/facebook/testing/screenshot/ScreenshotTestRunner.kt new file mode 100644 index 0000000000000000000000000000000000000000..ff603a5e2bca18a44bef561b55489842b8280356 --- /dev/null +++ b/app/src/androidTest/java/com/facebook/testing/screenshot/ScreenshotTestRunner.kt @@ -0,0 +1,45 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.facebook.testing.screenshot + +import android.os.Bundle +import androidx.test.runner.AndroidJUnitRunner +import com.facebook.litho.config.ComponentsConfiguration +import com.facebook.testing.screenshot.ScreenshotRunner +import com.facebook.testing.screenshot.layouthierarchy.LayoutHierarchyDumper +import com.facebook.testing.screenshot.layouthierarchy.litho.LithoAttributePlugin +import com.facebook.testing.screenshot.layouthierarchy.litho.LithoHierarchyPlugin + +class ScreenshotTestRunner : AndroidJUnitRunner() { + companion object { + init { + ComponentsConfiguration.isDebugModeEnabled = true + LayoutHierarchyDumper.addGlobalHierarchyPlugin(LithoHierarchyPlugin.getInstance()) + LayoutHierarchyDumper.addGlobalAttributePlugin(LithoAttributePlugin.getInstance()) + } + } + + override fun onCreate(arguments: Bundle) { + ScreenshotRunner.onCreate(this, arguments) + super.onCreate(arguments) + } + + override fun finish(resultCode: Int, results: Bundle) { + ScreenshotRunner.onDestroy() + super.finish(resultCode, results) + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7ba39cb7a200fdad66295db0836c1a683a79f048..c3d42ae0cbe64324a3e12cb7c08abb6c6ce8a00b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,5 +1,6 @@ @@ -8,6 +9,12 @@ + + + + + + + android:theme="@style/AppTheme" + android:debuggable="true" + tools:ignore="HardcodedDebugMode"> @@ -158,4 +167,4 @@ - \ No newline at end of file + diff --git a/build.gradle b/build.gradle index 129f07648ff3a607ef6b8e3ed9f6bae5a97e3a84..b2f7d4cb81c92f117621e3c6f2debc41513126c1 100644 --- a/build.gradle +++ b/build.gradle @@ -1,20 +1,29 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { + ext.kotlin_version = '1.4.0-rc' repositories { google() jcenter() + maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' } } dependencies { apply plugin: 'maven' - classpath 'com.android.tools.build:gradle:3.5.2' + classpath 'com.android.tools.build:gradle:4.0.1' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files + + //for screenshot testing + classpath 'com.facebook.testing.screenshot:plugin:0.13.0' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + + } } + allprojects { repositories { google() @@ -22,3 +31,9 @@ allprojects { } } + +task integrationTest(dependsOn: ':app:runDebugAndroidTestScreenshotTest') { + doLast { + assert taskLogOutput.toString().contains('Found 12 screenshots') + } +} diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0d7b6bf4795b35228634bdcaccca7dcee0c3b9f3..6c331a7dfdfb32755c45e542a30c785005b0311e 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.5.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip diff --git a/wiki/keystore_issue.md b/wiki/keystore_issue.md new file mode 100644 index 0000000000000000000000000000000000000000..5a3b4c922d1cc2b9242ba3feaf8e35d31614b2a6 --- /dev/null +++ b/wiki/keystore_issue.md @@ -0,0 +1,14 @@ +# **Problem with APK's signkey when trying to run notes app** + +## **Romain's explaination** + +The default applications of a smartphone are stored on the partition system, while the ones installed by the users are on the partition data. If I have problems trying to run the *notes* app on my device (*Xiaomi redmi 3s (land)*) it's because there is a conflict between the new app I'm trying to install on the partition data, and the default app on the partition system. +This can be an important issue for later uses of this testing plugin. I have to try to modify the *_runDebugAndroidTestScreenshotTest_* task to sign the APK before it's installed. + +## **Config documentation** + +**"Import PEM into Java Key Store"**: *https://stackoverflow.com/questions/2138940/import-pem-into-java-key-store* + +**"Android signing error: trusted certificate entries are not password-protected"**: *https://stackoverflow.com/questions/47152473/android-signing-error-trusted-certificate-entries-are-not-password-protected* + + diff --git a/wiki/record_verify_issue.md b/wiki/record_verify_issue.md new file mode 100644 index 0000000000000000000000000000000000000000..5a09e46221d57ad158c0e4ecc138e3fb07f9364d --- /dev/null +++ b/wiki/record_verify_issue.md @@ -0,0 +1,8 @@ +# **Problem with the record/verify method** +The classical use of Facebook screenshot testing is the following: +* run the **_record_** task after an update which modifies the view you test to generate a new screenshot to be compared later +* run the **_verify_** task after an update which is not supposed to modify the view in order to see if it's the case: if a difference is detected between this new screenshot and the one saved, the test should fail. + +The problem is that when I run the **_record_** task, then modify some margin and run the **_verify_** task, I do obtain differences when I pull the screenshots, but no exception is thrown. +See the test report: *record_verify_issue_report.png* +and the two views generated: *record_verify_issue_screenshot_1.png* and *record_verify_issue_screenshot_2.png*. diff --git a/wiki/record_verify_issue_report.png b/wiki/record_verify_issue_report.png new file mode 100644 index 0000000000000000000000000000000000000000..120a4347f8013d9f1617babcad17c2a3079e1715 Binary files /dev/null and b/wiki/record_verify_issue_report.png differ diff --git a/wiki/record_verify_issue_screenshot_1.png b/wiki/record_verify_issue_screenshot_1.png new file mode 100644 index 0000000000000000000000000000000000000000..b5d8cfcdab05ba19371848568f822ecdbca137ec Binary files /dev/null and b/wiki/record_verify_issue_screenshot_1.png differ diff --git a/wiki/record_verify_issue_screenshot_2.png b/wiki/record_verify_issue_screenshot_2.png new file mode 100644 index 0000000000000000000000000000000000000000..9f5bae1c9a4bf43bed823849a5e60d6768a64307 Binary files /dev/null and b/wiki/record_verify_issue_screenshot_2.png differ