diff --git a/.gitignore b/.gitignore index 23c65c1cc1..69c142baae 100644 --- a/.gitignore +++ b/.gitignore @@ -68,3 +68,4 @@ libvlc.pc libvlc.pc.backup libvlcpp.pc lib/ +/buildsystem/automation/certificates/ diff --git a/application/app/build.gradle b/application/app/build.gradle index 6a8d8bd655..8e00b591de 100644 --- a/application/app/build.gradle +++ b/application/app/build.gradle @@ -2,8 +2,21 @@ apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' android { + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + kotlinOptions { + jvmTarget = JavaVersion.VERSION_1_8.toString() + } + packagingOptions { exclude 'META-INF/main.kotlin_module' + exclude 'META-INF/donations_debug.kotlin_module' + exclude 'META-INF/mediadb_debug.kotlin_module' + exclude 'META-INF/resources_debug.kotlin_module' + exclude 'META-INF/television_debug.kotlin_module' pickFirst 'lib/armeabi-v7a/libc++_shared.so' pickFirst 'lib/armeabi/libc++_shared.so' pickFirst 'lib/arm64-v8a/libc++_shared.so' @@ -40,7 +53,11 @@ android { vectorDrawables.useSupportLibrary = true multiDexEnabled true - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + testInstrumentationRunner "org.videolan.vlc.MultidexTestRunner" + // The following argument makes the Android Test Orchestrator run its + // "pm clear" command after each test invocation. This command ensures + // that the app's state is completely cleared between tests. + testInstrumentationRunnerArguments clearPackageData: 'true' } signingConfigs { @@ -135,4 +152,27 @@ android { dependencies { implementation project(':application:vlc-android') implementation project(':application:television') + testImplementation project(':application:television') + + androidTestApi "androidx.test.espresso:espresso-contrib:$rootProject.espressoVersion" + androidTestApi "androidx.test.espresso:espresso-core:$rootProject.espressoVersion" + androidTestApi "androidx.test.espresso:espresso-intents:$rootProject.espressoVersion" + testApi "junit:junit:$rootProject.ext.junitVersion" + androidTestApi "androidx.room:room-testing:$rootProject.ext.roomVersion" + testApi "androidx.arch.core:core-testing:$rootProject.ext.archVersion" + androidTestApi "androidx.arch.core:core-testing:$rootProject.ext.archVersion" + androidTestApi "androidx.test.ext:junit:$rootProject.ext.supportTest" + androidTestUtil "androidx.test:orchestrator:$rootProject.ext.orchestrator" + testApi "androidx.test:core:$rootProject.ext.testCore" + testApi "org.jetbrains.kotlinx:kotlinx-coroutines-test:$rootProject.ext.kotlinx_version" + testApi "org.mockito:mockito-core:$rootProject.ext.mockito" + testApi "io.mockk:mockk:$rootProject.ext.mockk" + testApi "org.powermock:powermock-api-mockito2:$rootProject.ext.powerMock" + testApi "org.powermock:powermock-module-junit4:$rootProject.ext.powerMock" + testApi "com.jraska.livedata:testing-ktx:$rootProject.ext.livedataTest" + testApi "org.robolectric:robolectric:$rootProject.ext.robolectric" + androidTestApi "com.android.support:multidex:1.0.3" + androidTestImplementation "androidx.test.uiautomator:uiautomator:2.2.0" + androidTestApi 'androidx.test:rules:1.3.0' + androidTestImplementation 'tools.fastlane:screengrab:2.0.0' } diff --git a/application/app/src/androidTest/AndroidManifest.xml b/application/app/src/androidTest/AndroidManifest.xml new file mode 100644 index 0000000000..f436f147a7 --- /dev/null +++ b/application/app/src/androidTest/AndroidManifest.xml @@ -0,0 +1,30 @@ + + + + + + \ No newline at end of file diff --git a/application/app/src/androidTest/java/org/videolan/mobile/app/ExampleInstrumentedTest.kt b/application/app/src/androidTest/java/org/videolan/mobile/app/ExampleInstrumentedTest.kt deleted file mode 100644 index be3b297be3..0000000000 --- a/application/app/src/androidTest/java/org/videolan/mobile/app/ExampleInstrumentedTest.kt +++ /dev/null @@ -1,24 +0,0 @@ -package org.videolan.mobile.app - -import androidx.test.platform.app.InstrumentationRegistry -import androidx.test.ext.junit.runners.AndroidJUnit4 - -import org.junit.Test -import org.junit.runner.RunWith - -import org.junit.Assert.* - -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -@RunWith(AndroidJUnit4::class) -class ExampleInstrumentedTest { - @Test - fun useAppContext() { - // Context of the app under test. - val appContext = InstrumentationRegistry.getInstrumentation().targetContext - assertEquals("org.videolan.mobile.app", appContext.packageName) - } -} diff --git a/application/vlc-android/androidTest/org/videolan/vlc/BaseUITest.kt b/application/app/src/androidTest/java/org/videolan/vlc/BaseUITest.kt similarity index 99% rename from application/vlc-android/androidTest/org/videolan/vlc/BaseUITest.kt rename to application/app/src/androidTest/java/org/videolan/vlc/BaseUITest.kt index 7dfde28d94..842ab2de70 100644 --- a/application/vlc-android/androidTest/org/videolan/vlc/BaseUITest.kt +++ b/application/app/src/androidTest/java/org/videolan/vlc/BaseUITest.kt @@ -10,7 +10,6 @@ import org.junit.runner.RunWith import org.videolan.resources.util.startMedialibrary import org.videolan.vlc.util.TestCoroutineContextProvider - @RunWith(AndroidJUnit4::class) abstract class BaseUITest { @Rule @@ -18,7 +17,6 @@ abstract class BaseUITest { val storagePermissionGrant = GrantPermissionRule.grant( "android.permission.READ_EXTERNAL_STORAGE") - val context: Context = ApplicationProvider.getApplicationContext() @Before diff --git a/application/app/src/androidTest/java/org/videolan/vlc/DemoModeEnabler.kt b/application/app/src/androidTest/java/org/videolan/vlc/DemoModeEnabler.kt new file mode 100644 index 0000000000..2ca07fd66d --- /dev/null +++ b/application/app/src/androidTest/java/org/videolan/vlc/DemoModeEnabler.kt @@ -0,0 +1,67 @@ +/* + * ************************************************************************ + * DemoModeEnabler.kt + * ************************************************************************* + * Copyright © 2020 VLC authors and VideoLAN + * Author: Nicolas POMEPUY + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + * ************************************************************************** + * + * + */ + +package org.videolan.vlc + +import android.os.ParcelFileDescriptor +import androidx.test.platform.app.InstrumentationRegistry +import java.io.BufferedReader +import java.io.InputStreamReader + +class DemoModeEnabler { + + fun enable() { + executeShellCommand("settings put global sysui_demo_allowed 1") + sendCommand("exit") + sendCommand("enter") + sendCommand("notifications", "visible" to "false") + sendCommand("network", "wifi" to "show", "level" to "4", "fully" to "true") + sendCommand("network", "mobile" to "show", "level" to "4", "datatype" to "4g") + sendCommand("battery", "level" to "100", "plugged" to "true") + sendCommand("clock", "hhmm" to "1000") + } + + fun disable() { + sendCommand("exit") + } + + private fun sendCommand(command: String, vararg extras: Pair) { + val exec = StringBuilder("am broadcast -a com.android.systemui.demo -e command $command") + for ((key, value) in extras) { + exec.append(" -e $key $value") + } + executeShellCommand(exec.toString()) + } + + private fun executeShellCommand(command: String) { + waitForCompletion(InstrumentationRegistry.getInstrumentation().uiAutomation.executeShellCommand(command)) + } + + private fun waitForCompletion(descriptor: ParcelFileDescriptor) { + val reader = BufferedReader(InputStreamReader(ParcelFileDescriptor.AutoCloseInputStream(descriptor))) + reader.use { + it.readText() + } + } +} \ No newline at end of file diff --git a/application/app/src/androidTest/java/org/videolan/vlc/DemoModeRule.kt b/application/app/src/androidTest/java/org/videolan/vlc/DemoModeRule.kt new file mode 100644 index 0000000000..e8991a30e4 --- /dev/null +++ b/application/app/src/androidTest/java/org/videolan/vlc/DemoModeRule.kt @@ -0,0 +1,44 @@ +/* + * ************************************************************************ + * DemoModeRule.kt + * ************************************************************************* + * Copyright © 2020 VLC authors and VideoLAN + * Author: Nicolas POMEPUY + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + * ************************************************************************** + * + * + */ + +package org.videolan.vlc + +import org.junit.rules.TestRule +import org.junit.runner.Description +import org.junit.runners.model.Statement + +class DemoModeRule : TestRule { + + private val helper = DemoModeEnabler() + + override fun apply(base: Statement, description: Description): Statement = DemoModeStatement(base) + + private inner class DemoModeStatement(private val base: Statement) : Statement() { + override fun evaluate() { + helper.enable() + base.evaluate() + helper.disable() + } + } +} \ No newline at end of file diff --git a/application/vlc-android/androidTest/org/videolan/vlc/MultidexTestRunner.kt b/application/app/src/androidTest/java/org/videolan/vlc/MultidexTestRunner.kt similarity index 100% rename from application/vlc-android/androidTest/org/videolan/vlc/MultidexTestRunner.kt rename to application/app/src/androidTest/java/org/videolan/vlc/MultidexTestRunner.kt diff --git a/application/app/src/androidTest/java/org/videolan/vlc/PhoneScreenhotsInstrumentedTest.kt b/application/app/src/androidTest/java/org/videolan/vlc/PhoneScreenhotsInstrumentedTest.kt new file mode 100644 index 0000000000..f162abdd6f --- /dev/null +++ b/application/app/src/androidTest/java/org/videolan/vlc/PhoneScreenhotsInstrumentedTest.kt @@ -0,0 +1,158 @@ +/* + * ************************************************************************ + * PhoneScreenhotsInstrumentedTest.kt + * ************************************************************************* + * Copyright © 2020 VLC authors and VideoLAN + * Author: Nicolas POMEPUY + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + * ************************************************************************** + * + * + */ + +package org.videolan.vlc + +import android.content.Intent +import android.os.SystemClock +import android.util.Log +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.Espresso.pressBack +import androidx.test.espresso.action.ViewActions.click +import androidx.test.espresso.matcher.ViewMatchers.isRoot +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.rule.ActivityTestRule +import androidx.test.uiautomator.UiDevice +import kotlinx.coroutines.ObsoleteCoroutinesApi +import org.junit.ClassRule +import org.junit.Rule +import org.junit.Test +import org.videolan.resources.EXTRA_TARGET +import org.videolan.tools.Settings +import org.videolan.vlc.gui.MainActivity +import org.videolan.vlc.util.DpadHelper.pressHome +import org.videolan.vlc.util.DpadHelper.pressPip +import org.videolan.vlc.util.DpadHelper.pressStop +import org.videolan.vlc.util.ScreenshotUtil +import org.videolan.vlc.util.UiUtils.waitId +import org.videolan.vlc.util.UiUtils.waitUntilLoaded +import tools.fastlane.screengrab.Screengrab +import tools.fastlane.screengrab.UiAutomatorScreenshotStrategy +import tools.fastlane.screengrab.locale.LocaleTestRule + +//@RunWith(AndroidJUnit4::class) +class PhoneScreenhotsInstrumentedTest : BaseUITest() { + @Rule + @JvmField + val activityTestRule = ActivityTestRule(MainActivity::class.java, true, false) + + @Rule + @JvmField + val demoModeRule = DemoModeRule() + + lateinit var activity: MainActivity + + @ObsoleteCoroutinesApi + @Test + fun testTakeScreenshot() { + onView(isRoot()).perform(waitId(R.id.audio_list, 5000)) + //Audio + // ScreenshotUtil.takeScreenshot("01_trash") + onView(withId(R.id.sliding_tabs)).perform(TabsMatcher(0)) + waitUntilLoaded { activity.findViewById(R.id.audio_list) } + SystemClock.sleep(300) + ScreenshotUtil.takeScreenshot(3, "audio_list") + onView(withId(R.id.sliding_tabs)).perform(TabsMatcher(2)) + waitUntilLoaded { activity.findViewById(R.id.audio_list) } + + onView(withId(R.id.ml_menu_last_playlist)).perform(click()) + onView(isRoot()).perform(waitId(R.id.header, 5000)) +// ScreenshotUtil.takeScreenshot(7,"audio_player_collapsed") + onView(withId(R.id.header)).perform(click()) + SystemClock.sleep(300) + ScreenshotUtil.takeScreenshot(6,"audio_player_playlist") + onView(withId(R.id.playlist_switch)).perform(click()) + ScreenshotUtil.takeScreenshot(5,"audio_player") + onView(withId(R.id.playlist_switch)).perform(click()) + //close audio player + onView(withId(R.id.header)).perform(click()) + pressStop() + } + + @ObsoleteCoroutinesApi + @Test + fun testTakeScreenshotVideo() { + onView(withId(R.id.nav_video)) + .perform(click()) + Log.d("Espresso", "0") + waitUntilLoaded { activity.findViewById(R.id.video_grid) } + Log.d("Espresso", "1") + + ScreenshotUtil.takeScreenshot(1, "video_list") + + val rvMatcher = withRecyclerView(R.id.video_grid) + Log.d("Espresso", "2") + onView(rvMatcher.atPosition(3)).perform(click()) + Log.d("Espresso", "3") + + rotateLandscape() + onView(isRoot()).perform(orientationLandscape()) + onView(isRoot()).perform(waitId(R.id.player_root, 5000)) + + SystemClock.sleep(1500) + onView(withId(R.id.player_root)).perform(click()) + SystemClock.sleep(500) + ScreenshotUtil.takeScreenshot(2, "video_player") + onView(withId(R.id.player_overlay_adv_function)).perform(ForceClickAction()) + SystemClock.sleep(500) + ScreenshotUtil.takeScreenshot(7,"video_player_advanced_options") + disableRotateLandscape() + SystemClock.sleep(500) + onView(withRecyclerView(R.id.options_list).atPositionOnView(4, R.id.option_title)).perform(click()) +// ScreenshotUtil.takeScreenshot(9,"video_player_equalizer") + pressBack() + pressPip() + pressHome() + pressPip() + ScreenshotUtil.takeScreenshot(8,"pip") + } + + @ObsoleteCoroutinesApi + @Test + fun testTakeScreenshotBrowser() { + onView(withId(R.id.nav_directories)) + .perform(click()) + ScreenshotUtil.takeScreenshot(4,"browser") + } + + private fun rotateLandscape() = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()).setOrientationLeft() + private fun disableRotateLandscape() = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()).setOrientationNatural() + + companion object { + @ClassRule + @JvmField + val localeTestRule = LocaleTestRule() + } + + override fun beforeTest() { + Screengrab.setDefaultScreenshotStrategy(UiAutomatorScreenshotStrategy()) + Settings.getInstance(context).edit().putBoolean("auto_rescan", false).putBoolean("audio_resume_card", false).commit() + val intent = Intent().apply { + putExtra(EXTRA_TARGET, R.id.nav_audio) + } + activityTestRule.launchActivity(intent) + activity = activityTestRule.activity + } +} diff --git a/application/vlc-android/androidTest/org/videolan/vlc/PreferenceMatcher.kt b/application/app/src/androidTest/java/org/videolan/vlc/PreferenceMatcher.kt similarity index 99% rename from application/vlc-android/androidTest/org/videolan/vlc/PreferenceMatcher.kt rename to application/app/src/androidTest/java/org/videolan/vlc/PreferenceMatcher.kt index 5d1022ac3c..5c11e0229b 100644 --- a/application/vlc-android/androidTest/org/videolan/vlc/PreferenceMatcher.kt +++ b/application/app/src/androidTest/java/org/videolan/vlc/PreferenceMatcher.kt @@ -107,7 +107,6 @@ object PreferenceMatchers { } catch (ignored: Resources.NotFoundException) { /* view could be from a context unaware of the resource id. */ } - } return if (null != expectedText && preference.title != null) { expectedText == preference.title.toString() diff --git a/application/app/src/androidTest/java/org/videolan/vlc/TvScreenhotsInstrumentedTest.kt b/application/app/src/androidTest/java/org/videolan/vlc/TvScreenhotsInstrumentedTest.kt new file mode 100644 index 0000000000..48f753729f --- /dev/null +++ b/application/app/src/androidTest/java/org/videolan/vlc/TvScreenhotsInstrumentedTest.kt @@ -0,0 +1,156 @@ +/* + * ************************************************************************ + * TvScreenhotsInstrumentedTest.kt + * ************************************************************************* + * Copyright © 2020 VLC authors and VideoLAN + * Author: Nicolas POMEPUY + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + * ************************************************************************** + * + * + */ + +package org.videolan.vlc + +import android.app.Activity +import android.content.Intent +import android.os.SystemClock +import androidx.test.espresso.Espresso +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.action.ViewActions.click +import androidx.test.espresso.matcher.ViewMatchers.* +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.rule.ActivityTestRule +import androidx.test.runner.lifecycle.ActivityLifecycleMonitorRegistry +import androidx.test.runner.lifecycle.Stage +import androidx.test.uiautomator.Direction +import kotlinx.coroutines.ObsoleteCoroutinesApi +import org.hamcrest.Matchers.allOf +import org.junit.ClassRule +import org.junit.Rule +import org.junit.Test +import org.videolan.resources.EXTRA_TARGET +import org.videolan.television.ui.MainTvActivity +import org.videolan.television.ui.audioplayer.AudioPlayerActivity +import org.videolan.television.ui.browser.VerticalGridActivity +import org.videolan.tools.Settings +import org.videolan.vlc.util.DpadHelper.pressBack +import org.videolan.vlc.util.DpadHelper.pressDPad +import org.videolan.vlc.util.DpadHelper.pressDPadCenter +import org.videolan.vlc.util.DpadHelper.pressHome +import org.videolan.vlc.util.DpadHelper.pressPip +import org.videolan.vlc.util.ScreenshotUtil +import org.videolan.vlc.util.UiUtils +import org.videolan.vlc.util.UiUtils.waitForActivity +import org.videolan.vlc.util.UiUtils.waitId +import tools.fastlane.screengrab.Screengrab +import tools.fastlane.screengrab.UiAutomatorScreenshotStrategy +import tools.fastlane.screengrab.locale.LocaleTestRule + +//@RunWith(AndroidJUnit4::class) +class TvScreenhotsInstrumentedTest : BaseUITest() { + @Rule + @JvmField + val activityTestRule = ActivityTestRule(MainTvActivity::class.java, true, false) + + @Rule + @JvmField + val demoModeRule = DemoModeRule() + + lateinit var activity: MainTvActivity + + companion object { + @ClassRule + @JvmField + val localeTestRule = LocaleTestRule() + } + + override fun beforeTest() { + Screengrab.setDefaultScreenshotStrategy(UiAutomatorScreenshotStrategy()) + Settings.getInstance(context).edit().putBoolean("auto_rescan", false).putBoolean("audio_resume_card", false).commit() + val intent = Intent().apply { + putExtra(EXTRA_TARGET, R.id.nav_audio) + } + activityTestRule.launchActivity(intent) + activity = activityTestRule.activity + } + + fun getCurrentActivity(): Activity? { + var currentActivity: Activity? = null + InstrumentationRegistry.getInstrumentation().runOnMainSync { run { currentActivity = ActivityLifecycleMonitorRegistry.getInstance().getActivitiesInStage(Stage.RESUMED).elementAtOrNull(0) } } + return currentActivity + } + + @ObsoleteCoroutinesApi + @Test + fun testTakeScreenshot() { + SystemClock.sleep(1500) + //Audio + ScreenshotUtil.takeScreenshot(1, "tv_home") + + onView(allOf(withId(R.id.row_header), withText(activity.getString(R.string.audio)), withEffectiveVisibility(Visibility.VISIBLE))).perform(click()) + pressDPad(Direction.RIGHT, 4) + pressDPadCenter() + + waitForActivity(VerticalGridActivity::class.java) + waitId(org.videolan.television.R.id.list, 5000) + + getCurrentActivity()?.let { activity -> + UiUtils.waitUntilLoaded { activity.findViewById(org.videolan.television.R.id.list) } + } ?: throw IllegalStateException("Cannot find activity") + + ScreenshotUtil.takeScreenshot(4,"tv_audio_list") + pressDPad(Direction.DOWN, 4) + pressDPadCenter() + waitForActivity(AudioPlayerActivity::class.java) + + waitId(org.videolan.television.R.id.album_cover, 5000) + ScreenshotUtil.takeScreenshot(6,"tv_audio_player") + pressBack() + pressBack() + pressDPad(Direction.DOWN, 2) + pressDPadCenter() + + waitForActivity(VerticalGridActivity::class.java) + waitId(org.videolan.television.R.id.list, 5000) + getCurrentActivity()?.let { activity -> + UiUtils.waitUntilLoaded { activity.findViewById(org.videolan.television.R.id.list) } + } + ScreenshotUtil.takeScreenshot(5,"tv_files") + pressBack() + pressDPad(Direction.LEFT) + onView(allOf(withId(R.id.row_header), withText(activity.getString(R.string.video)), withEffectiveVisibility(Visibility.VISIBLE))).perform(click()) + pressDPadCenter() + pressDPadCenter() + waitForActivity(VerticalGridActivity::class.java) + waitId(org.videolan.television.R.id.list, 5000) + getCurrentActivity()?.let { activity -> + UiUtils.waitUntilLoaded { activity.findViewById(org.videolan.television.R.id.list) } + } + ScreenshotUtil.takeScreenshot(2,"tv_video_list") + pressDPad(Direction.DOWN, 3) + pressDPadCenter() + SystemClock.sleep(1500) + pressDPad(Direction.DOWN) + SystemClock.sleep(600) + ScreenshotUtil.takeScreenshot(3,"tv_video_player") + Espresso.pressBack() + pressPip() + pressHome() + pressPip() + SystemClock.sleep(1500) + ScreenshotUtil.takeScreenshot(7,"tv_pip") + } +} diff --git a/application/vlc-android/androidTest/org/videolan/vlc/UtilAdapterMatcher.kt b/application/app/src/androidTest/java/org/videolan/vlc/UtilAdapterMatcher.kt similarity index 98% rename from application/vlc-android/androidTest/org/videolan/vlc/UtilAdapterMatcher.kt rename to application/app/src/androidTest/java/org/videolan/vlc/UtilAdapterMatcher.kt index e6218c698f..dce9f66d51 100644 --- a/application/vlc-android/androidTest/org/videolan/vlc/UtilAdapterMatcher.kt +++ b/application/app/src/androidTest/java/org/videolan/vlc/UtilAdapterMatcher.kt @@ -85,7 +85,7 @@ fun findFirstPreferencePosition(@IdRes recyclerViewId: Int, vararg matchers: Mat return -1 to count } -fun onPreferenceRow(@IdRes recyclerViewId: Int, vararg matchers: Matcher): ViewInteraction? = findFirstPreferencePosition(recyclerViewId, *matchers).let {(i, count) -> +fun onPreferenceRow(@IdRes recyclerViewId: Int, vararg matchers: Matcher): ViewInteraction? = findFirstPreferencePosition(recyclerViewId, *matchers).let { (i, count) -> if (i != -1) { // FIXME: Fails to scroll to the bottom of recycler view onView(withId(recyclerViewId)) diff --git a/application/vlc-android/androidTest/org/videolan/vlc/UtilViewActions.kt b/application/app/src/androidTest/java/org/videolan/vlc/UtilViewActions.kt similarity index 89% rename from application/vlc-android/androidTest/org/videolan/vlc/UtilViewActions.kt rename to application/app/src/androidTest/java/org/videolan/vlc/UtilViewActions.kt index 8492d86b29..4f5062ec20 100644 --- a/application/vlc-android/androidTest/org/videolan/vlc/UtilViewActions.kt +++ b/application/app/src/androidTest/java/org/videolan/vlc/UtilViewActions.kt @@ -1,13 +1,14 @@ package org.videolan.vlc -import android.content.pm.ActivityInfo -import androidx.test.espresso.ViewAction import android.app.Activity import android.content.Context import android.content.ContextWrapper +import android.content.pm.ActivityInfo import android.view.View import android.view.ViewGroup import androidx.test.espresso.UiController +import androidx.test.espresso.ViewAction +import androidx.test.espresso.matcher.ViewMatchers.isEnabled import androidx.test.espresso.matcher.ViewMatchers.isRoot import androidx.test.runner.lifecycle.ActivityLifecycleMonitorRegistry import androidx.test.runner.lifecycle.Stage @@ -75,12 +76,21 @@ class OrientationChangeAction internal constructor(private val orientation: Int) if (context is Activity) { return context } - context = (context as ContextWrapper).baseContext + context = context.baseContext } return null } } +class ForceClickAction : ViewAction { + override fun getConstraints() = isEnabled() + override fun getDescription() = "Force click a view even if 90% condition is not satisfied" + + override fun perform(uiController: UiController?, view: View?) { + view?.performClick() + } +} + fun orientationLandscape(): ViewAction { return OrientationChangeAction(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) } diff --git a/application/vlc-android/androidTest/org/videolan/vlc/UtilViewMatchers.kt b/application/app/src/androidTest/java/org/videolan/vlc/UtilViewMatchers.kt similarity index 93% rename from application/vlc-android/androidTest/org/videolan/vlc/UtilViewMatchers.kt rename to application/app/src/androidTest/java/org/videolan/vlc/UtilViewMatchers.kt index 48ab41a8e9..bf2b577acd 100644 --- a/application/vlc-android/androidTest/org/videolan/vlc/UtilViewMatchers.kt +++ b/application/app/src/androidTest/java/org/videolan/vlc/UtilViewMatchers.kt @@ -17,15 +17,17 @@ import androidx.appcompat.view.menu.ActionMenuItemView import androidx.core.content.ContextCompat import androidx.databinding.ViewDataBinding import androidx.recyclerview.widget.RecyclerView +import androidx.test.espresso.UiController +import androidx.test.espresso.ViewAction import androidx.test.espresso.matcher.BoundedMatcher +import androidx.test.espresso.matcher.ViewMatchers.isDisplayed +import com.google.android.material.tabs.TabLayout import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ObsoleteCoroutinesApi import org.hamcrest.BaseMatcher import org.hamcrest.Description import org.hamcrest.Matcher import org.hamcrest.TypeSafeMatcher -import org.videolan.medialibrary.interfaces.media.MediaWrapper -import org.videolan.vlc.gui.browser.BaseBrowserAdapter import org.videolan.vlc.gui.helpers.SelectorViewHolder import org.videolan.vlc.gui.helpers.ThreeStatesCheckbox @@ -106,10 +108,7 @@ class MediaRecyclerViewMatcher>(@Id override fun matchesSafely(view: View): Boolean { if (!fillMatchesIfRequired(mapVH, view.rootView) { vh -> - if (vh is BaseBrowserAdapter.MediaViewHolder) { - val item = (vh as BaseBrowserAdapter.MediaViewHolder).binding.item as? MediaWrapper - item?.type == mediaType - } else false + false }) return false return mapVH[view]?.let { @@ -147,6 +146,23 @@ class MediaRecyclerViewMatcher>(@Id } } +class TabsMatcher internal constructor(var position: Int) : ViewAction { + + override fun getConstraints(): Matcher = isDisplayed() + + override fun getDescription(): String = "Click on tab" + + override fun perform(uiController: UiController?, view: View) { + if (view is TabLayout) { + val tabLayout: TabLayout = view as TabLayout + val tab: TabLayout.Tab? = tabLayout.getTabAt(position) + if (tab != null) { + tab.select() + } + } + } +} + class FirstViewMatcher : BaseMatcher() { var matchedBefore = false diff --git a/application/vlc-android/androidTest/org/videolan/vlc/database/BrowserFavDaoTest.kt b/application/app/src/androidTest/java/org/videolan/vlc/database/BrowserFavDaoTest.kt similarity index 100% rename from application/vlc-android/androidTest/org/videolan/vlc/database/BrowserFavDaoTest.kt rename to application/app/src/androidTest/java/org/videolan/vlc/database/BrowserFavDaoTest.kt index 7edde69500..7500e4ce3a 100644 --- a/application/vlc-android/androidTest/org/videolan/vlc/database/BrowserFavDaoTest.kt +++ b/application/app/src/androidTest/java/org/videolan/vlc/database/BrowserFavDaoTest.kt @@ -25,8 +25,8 @@ import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.* import org.junit.Test import org.junit.runner.RunWith -import org.videolan.vlc.util.getValue import org.videolan.vlc.util.TestUtil +import org.videolan.vlc.util.getValue @RunWith(AndroidJUnit4::class) diff --git a/application/vlc-android/androidTest/org/videolan/vlc/database/CustomDirectoryDaoTest.kt b/application/app/src/androidTest/java/org/videolan/vlc/database/CustomDirectoryDaoTest.kt similarity index 100% rename from application/vlc-android/androidTest/org/videolan/vlc/database/CustomDirectoryDaoTest.kt rename to application/app/src/androidTest/java/org/videolan/vlc/database/CustomDirectoryDaoTest.kt diff --git a/application/vlc-android/androidTest/org/videolan/vlc/database/DbTest.kt b/application/app/src/androidTest/java/org/videolan/vlc/database/DbTest.kt similarity index 100% rename from application/vlc-android/androidTest/org/videolan/vlc/database/DbTest.kt rename to application/app/src/androidTest/java/org/videolan/vlc/database/DbTest.kt diff --git a/application/vlc-android/androidTest/org/videolan/vlc/database/ExternalSubDaoTest.kt b/application/app/src/androidTest/java/org/videolan/vlc/database/ExternalSubDaoTest.kt similarity index 100% rename from application/vlc-android/androidTest/org/videolan/vlc/database/ExternalSubDaoTest.kt rename to application/app/src/androidTest/java/org/videolan/vlc/database/ExternalSubDaoTest.kt diff --git a/application/vlc-android/androidTest/org/videolan/vlc/database/MigrationTest.kt b/application/app/src/androidTest/java/org/videolan/vlc/database/MigrationTest.kt similarity index 84% rename from application/vlc-android/androidTest/org/videolan/vlc/database/MigrationTest.kt rename to application/app/src/androidTest/java/org/videolan/vlc/database/MigrationTest.kt index 5b72abaaf5..1ab91a9f6a 100644 --- a/application/vlc-android/androidTest/org/videolan/vlc/database/MigrationTest.kt +++ b/application/app/src/androidTest/java/org/videolan/vlc/database/MigrationTest.kt @@ -1,3 +1,27 @@ +/* + * ************************************************************************ + * MigrationTest.kt + * ************************************************************************* + * Copyright © 2020 VLC authors and VideoLAN + * Author: Nicolas POMEPUY + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + * ************************************************************************** + * + * + */ + /******************************************************************************* * MigrationTest.kt * **************************************************************************** @@ -120,7 +144,7 @@ class MigrationTest { fun getMigratedRoomDatabase(vararg migrations:Migration): MediaDatabase { val database: MediaDatabase = Room.databaseBuilder( InstrumentationRegistry.getTargetContext(), - MediaDatabase::class.java, TEST_DB_NAME ) + MediaDatabase::class.java, TEST_DB_NAME) .addMigrations(*migrations) .build() diff --git a/application/vlc-android/androidTest/org/videolan/vlc/database/SlaveDaoTest.kt b/application/app/src/androidTest/java/org/videolan/vlc/database/SlaveDaoTest.kt similarity index 100% rename from application/vlc-android/androidTest/org/videolan/vlc/database/SlaveDaoTest.kt rename to application/app/src/androidTest/java/org/videolan/vlc/database/SlaveDaoTest.kt diff --git a/application/vlc-android/androidTest/org/videolan/vlc/database/helpers/SqliteDatabaseTestHelper.kt b/application/app/src/androidTest/java/org/videolan/vlc/database/helpers/SqliteDatabaseTestHelper.kt similarity index 100% rename from application/vlc-android/androidTest/org/videolan/vlc/database/helpers/SqliteDatabaseTestHelper.kt rename to application/app/src/androidTest/java/org/videolan/vlc/database/helpers/SqliteDatabaseTestHelper.kt diff --git a/application/vlc-android/androidTest/org/videolan/vlc/database/helpers/SqliteTestDbOpenHelper.kt b/application/app/src/androidTest/java/org/videolan/vlc/database/helpers/SqliteTestDbOpenHelper.kt similarity index 100% rename from application/vlc-android/androidTest/org/videolan/vlc/database/helpers/SqliteTestDbOpenHelper.kt rename to application/app/src/androidTest/java/org/videolan/vlc/database/helpers/SqliteTestDbOpenHelper.kt diff --git a/application/vlc-android/androidTest/org/videolan/vlc/gui/PlaylistActivityUITest.kt b/application/app/src/androidTest/java/org/videolan/vlc/gui/PlaylistActivityUITest.kt similarity index 100% rename from application/vlc-android/androidTest/org/videolan/vlc/gui/PlaylistActivityUITest.kt rename to application/app/src/androidTest/java/org/videolan/vlc/gui/PlaylistActivityUITest.kt diff --git a/application/vlc-android/androidTest/org/videolan/vlc/gui/PlaylistFragmentUITest.kt b/application/app/src/androidTest/java/org/videolan/vlc/gui/PlaylistFragmentUITest.kt similarity index 97% rename from application/vlc-android/androidTest/org/videolan/vlc/gui/PlaylistFragmentUITest.kt rename to application/app/src/androidTest/java/org/videolan/vlc/gui/PlaylistFragmentUITest.kt index f47d907f92..fa53fbdece 100644 --- a/application/vlc-android/androidTest/org/videolan/vlc/gui/PlaylistFragmentUITest.kt +++ b/application/app/src/androidTest/java/org/videolan/vlc/gui/PlaylistFragmentUITest.kt @@ -66,8 +66,8 @@ class PlaylistFragmentUITest: BaseUITest() { @Test fun whenPlaylistAddedFromDirectoriesView_checkPlaylistUpdated() { // Navigate to directories view - onView(withId(R.id.root_container)) - .perform(open()) +// onView(withId(R.id.root_container)) +// .perform(open()) onView(allOf(instanceOf(NavigationMenuItemView::class.java), hasDescendant(withText(R.string.directories)))) .check(matches(isDisplayed())) @@ -85,8 +85,8 @@ class PlaylistFragmentUITest: BaseUITest() { .perform(click()) // Navigate back to playlists view - onView(withId(R.id.root_container)) - .perform(open()) +// onView(withId(R.id.root_container)) +// .perform(open()) onView(allOf(instanceOf(NavigationMenuItemView::class.java), hasDescendant(withText(R.string.playlists)))) .check(matches(isDisplayed())) diff --git a/application/vlc-android/androidTest/org/videolan/vlc/gui/browser/FileBrowserFragmentUITest.kt b/application/app/src/androidTest/java/org/videolan/vlc/gui/browser/FileBrowserFragmentUITest.kt similarity index 100% rename from application/vlc-android/androidTest/org/videolan/vlc/gui/browser/FileBrowserFragmentUITest.kt rename to application/app/src/androidTest/java/org/videolan/vlc/gui/browser/FileBrowserFragmentUITest.kt diff --git a/application/app/src/androidTest/java/org/videolan/vlc/gui/browser/FilePickerFragmentUITest.kt b/application/app/src/androidTest/java/org/videolan/vlc/gui/browser/FilePickerFragmentUITest.kt new file mode 100644 index 0000000000..a66bf6e1c8 --- /dev/null +++ b/application/app/src/androidTest/java/org/videolan/vlc/gui/browser/FilePickerFragmentUITest.kt @@ -0,0 +1,61 @@ +/* + * ************************************************************************ + * FilePickerFragmentUITest.kt + * ************************************************************************* + * Copyright © 2020 VLC authors and VideoLAN + * Author: Nicolas POMEPUY + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + * ************************************************************************** + * + * + */ + +package org.videolan.vlc.gui.browser + +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.action.ViewActions.click +import androidx.test.espresso.assertion.ViewAssertions.matches +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.rule.ActivityTestRule +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.ObsoleteCoroutinesApi +import org.hamcrest.Matchers.equalTo +import org.hamcrest.Matchers.greaterThan +import org.junit.Rule +import org.junit.Test +import org.videolan.vlc.R + +@ObsoleteCoroutinesApi +@ExperimentalCoroutinesApi +class FilePickerFragmentUITest : org.videolan.vlc.BaseUITest() { + @Rule + @JvmField + val activityTestRule = ActivityTestRule(FilePickerActivity::class.java) + + lateinit var activity: FilePickerActivity + + override fun beforeTest() { + activity = activityTestRule.activity + } + + @Test + fun whenAtSomeFolder_clickOnHomeIconReturnsBackToRoot() { + onView(org.videolan.vlc.withRecyclerView(R.id.network_list).atPosition(0)).perform(click()) + onView(org.videolan.vlc.withRecyclerView(R.id.network_list).atPosition(0)).perform(click()) + + onView(withId(R.id.network_list)).check(matches(org.videolan.vlc.withCount(greaterThan(2)))) + + } +} diff --git a/application/vlc-android/androidTest/org/videolan/vlc/gui/browser/StorageBrowserFragmentUITest.kt b/application/app/src/androidTest/java/org/videolan/vlc/gui/browser/StorageBrowserFragmentUITest.kt similarity index 100% rename from application/vlc-android/androidTest/org/videolan/vlc/gui/browser/StorageBrowserFragmentUITest.kt rename to application/app/src/androidTest/java/org/videolan/vlc/gui/browser/StorageBrowserFragmentUITest.kt diff --git a/application/vlc-android/androidTest/org/videolan/vlc/gui/preferences/BasePreferenceUITest.kt b/application/app/src/androidTest/java/org/videolan/vlc/gui/preferences/BasePreferenceUITest.kt similarity index 100% rename from application/vlc-android/androidTest/org/videolan/vlc/gui/preferences/BasePreferenceUITest.kt rename to application/app/src/androidTest/java/org/videolan/vlc/gui/preferences/BasePreferenceUITest.kt index 4c7e01c8b2..1d100c4b2d 100644 --- a/application/vlc-android/androidTest/org/videolan/vlc/gui/preferences/BasePreferenceUITest.kt +++ b/application/app/src/androidTest/java/org/videolan/vlc/gui/preferences/BasePreferenceUITest.kt @@ -9,11 +9,11 @@ import androidx.test.espresso.assertion.ViewAssertions import androidx.test.espresso.matcher.ViewMatchers import org.hamcrest.Matchers import org.hamcrest.Matchers.allOf +import org.videolan.tools.Settings import org.videolan.vlc.BaseUITest import org.videolan.vlc.PreferenceMatchers import org.videolan.vlc.R import org.videolan.vlc.onPreferenceRow -import org.videolan.tools.Settings abstract class BasePreferenceUITest : BaseUITest() { val settings: SharedPreferences = Settings.getInstance(context) diff --git a/application/vlc-android/androidTest/org/videolan/vlc/gui/preferences/PreferencesAudioUITest.kt b/application/app/src/androidTest/java/org/videolan/vlc/gui/preferences/PreferencesAudioUITest.kt similarity index 100% rename from application/vlc-android/androidTest/org/videolan/vlc/gui/preferences/PreferencesAudioUITest.kt rename to application/app/src/androidTest/java/org/videolan/vlc/gui/preferences/PreferencesAudioUITest.kt diff --git a/application/vlc-android/androidTest/org/videolan/vlc/gui/preferences/PreferencesCastingUITest.kt b/application/app/src/androidTest/java/org/videolan/vlc/gui/preferences/PreferencesCastingUITest.kt similarity index 100% rename from application/vlc-android/androidTest/org/videolan/vlc/gui/preferences/PreferencesCastingUITest.kt rename to application/app/src/androidTest/java/org/videolan/vlc/gui/preferences/PreferencesCastingUITest.kt diff --git a/application/vlc-android/androidTest/org/videolan/vlc/gui/preferences/PreferencesFragmentUITest.kt b/application/app/src/androidTest/java/org/videolan/vlc/gui/preferences/PreferencesFragmentUITest.kt similarity index 100% rename from application/vlc-android/androidTest/org/videolan/vlc/gui/preferences/PreferencesFragmentUITest.kt rename to application/app/src/androidTest/java/org/videolan/vlc/gui/preferences/PreferencesFragmentUITest.kt diff --git a/application/vlc-android/androidTest/org/videolan/vlc/gui/preferences/PreferencesSubtitlesUITest.kt b/application/app/src/androidTest/java/org/videolan/vlc/gui/preferences/PreferencesSubtitlesUITest.kt similarity index 100% rename from application/vlc-android/androidTest/org/videolan/vlc/gui/preferences/PreferencesSubtitlesUITest.kt rename to application/app/src/androidTest/java/org/videolan/vlc/gui/preferences/PreferencesSubtitlesUITest.kt diff --git a/application/vlc-android/androidTest/org/videolan/vlc/gui/preferences/PreferencesUIUITest.kt b/application/app/src/androidTest/java/org/videolan/vlc/gui/preferences/PreferencesUIUITest.kt similarity index 100% rename from application/vlc-android/androidTest/org/videolan/vlc/gui/preferences/PreferencesUIUITest.kt rename to application/app/src/androidTest/java/org/videolan/vlc/gui/preferences/PreferencesUIUITest.kt diff --git a/application/vlc-android/androidTest/org/videolan/vlc/gui/preferences/PreferencesVideoUITest.kt b/application/app/src/androidTest/java/org/videolan/vlc/gui/preferences/PreferencesVideoUITest.kt similarity index 100% rename from application/vlc-android/androidTest/org/videolan/vlc/gui/preferences/PreferencesVideoUITest.kt rename to application/app/src/androidTest/java/org/videolan/vlc/gui/preferences/PreferencesVideoUITest.kt diff --git a/application/app/src/androidTest/java/org/videolan/vlc/util/DpadHelper.kt b/application/app/src/androidTest/java/org/videolan/vlc/util/DpadHelper.kt new file mode 100644 index 0000000000..b17e8744f6 --- /dev/null +++ b/application/app/src/androidTest/java/org/videolan/vlc/util/DpadHelper.kt @@ -0,0 +1,53 @@ +/* + * ************************************************************************ + * DpadHelper.kt + * ************************************************************************* + * Copyright © 2020 VLC authors and VideoLAN + * Author: Nicolas POMEPUY + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + * ************************************************************************** + * + * + */ + +package org.videolan.vlc.util + +import android.os.SystemClock +import android.view.KeyEvent +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.uiautomator.Direction +import androidx.test.uiautomator.UiDevice + +object DpadHelper { + private val device: UiDevice by lazy { UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) } + + fun pressDPad(direction: Direction?, nbTimes: Int = 1) { + for (i in 0 until nbTimes) { + when (direction) { + Direction.DOWN -> device.pressDPadDown() + Direction.LEFT -> device.pressDPadLeft() + Direction.UP -> device.pressDPadUp() + Direction.RIGHT -> device.pressDPadRight() + } + if (i < nbTimes - 1) SystemClock.sleep(300) + } + } + + fun pressHome() = device.pressHome() + fun pressPip() = device.pressKeyCode(KeyEvent.KEYCODE_WINDOW) + fun pressStop() = device.pressKeyCode(KeyEvent.KEYCODE_MEDIA_STOP) + fun pressBack() = device.pressBack() + fun pressDPadCenter() = device.pressDPadCenter() +} \ No newline at end of file diff --git a/application/vlc-android/test-common/org/videolan/vlc/util/KExtensions.kt b/application/app/src/androidTest/java/org/videolan/vlc/util/KExtensions.kt similarity index 100% rename from application/vlc-android/test-common/org/videolan/vlc/util/KExtensions.kt rename to application/app/src/androidTest/java/org/videolan/vlc/util/KExtensions.kt diff --git a/application/vlc-android/test-common/org/videolan/vlc/util/LiveDataTestUtil.kt b/application/app/src/androidTest/java/org/videolan/vlc/util/LiveDataTestUtil.kt similarity index 83% rename from application/vlc-android/test-common/org/videolan/vlc/util/LiveDataTestUtil.kt rename to application/app/src/androidTest/java/org/videolan/vlc/util/LiveDataTestUtil.kt index 3945c1a4da..8828410ff8 100644 --- a/application/vlc-android/test-common/org/videolan/vlc/util/LiveDataTestUtil.kt +++ b/application/app/src/androidTest/java/org/videolan/vlc/util/LiveDataTestUtil.kt @@ -21,6 +21,8 @@ package org.videolan.vlc.util import androidx.lifecycle.LiveData +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.onEach import java.util.concurrent.CountDownLatch import java.util.concurrent.TimeUnit @@ -43,6 +45,20 @@ fun getValue(liveData: LiveData): T { } latch.await(2, TimeUnit.SECONDS) + @Suppress("UNCHECKED_CAST") + return data[0] as T +} + +@Throws(InterruptedException::class) +fun getValue(liveData: Flow): T { + val data = arrayOfNulls(1) + val latch = CountDownLatch(1) + liveData.onEach { o -> + data[0] = o + latch.countDown() + } + latch.await(2, TimeUnit.SECONDS) + @Suppress("UNCHECKED_CAST") return data[0] as T } \ No newline at end of file diff --git a/application/vlc-android/test-common/org/videolan/vlc/util/MockitoExt.kt b/application/app/src/androidTest/java/org/videolan/vlc/util/MockitoExt.kt similarity index 100% rename from application/vlc-android/test-common/org/videolan/vlc/util/MockitoExt.kt rename to application/app/src/androidTest/java/org/videolan/vlc/util/MockitoExt.kt diff --git a/application/app/src/androidTest/java/org/videolan/vlc/util/ScreenshotUtil.kt b/application/app/src/androidTest/java/org/videolan/vlc/util/ScreenshotUtil.kt new file mode 100644 index 0000000000..806c703777 --- /dev/null +++ b/application/app/src/androidTest/java/org/videolan/vlc/util/ScreenshotUtil.kt @@ -0,0 +1,36 @@ +/* + * ************************************************************************ + * ScreenshotUtil.kt + * ************************************************************************* + * Copyright © 2020 VLC authors and VideoLAN + * Author: Nicolas POMEPUY + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + * ************************************************************************** + * + * + */ + +package org.videolan.vlc.util + +import tools.fastlane.screengrab.Screengrab + +object ScreenshotUtil { + + fun takeScreenshot(number:Int, title:String) { + Screengrab.screenshot("${normalizeNumber(number)}_$title") + } + + private fun normalizeNumber(number:Int) = if (number < 10) "0$number" else "$number" +} \ No newline at end of file diff --git a/application/vlc-android/test-common/org/videolan/vlc/util/TestCoroutineContextProvider.kt b/application/app/src/androidTest/java/org/videolan/vlc/util/TestCoroutineContextProvider.kt similarity index 100% rename from application/vlc-android/test-common/org/videolan/vlc/util/TestCoroutineContextProvider.kt rename to application/app/src/androidTest/java/org/videolan/vlc/util/TestCoroutineContextProvider.kt diff --git a/application/vlc-android/test-common/org/videolan/vlc/util/TestUtil.kt b/application/app/src/androidTest/java/org/videolan/vlc/util/TestUtil.kt similarity index 100% rename from application/vlc-android/test-common/org/videolan/vlc/util/TestUtil.kt rename to application/app/src/androidTest/java/org/videolan/vlc/util/TestUtil.kt diff --git a/application/app/src/androidTest/java/org/videolan/vlc/util/UiUtils.kt b/application/app/src/androidTest/java/org/videolan/vlc/util/UiUtils.kt new file mode 100644 index 0000000000..b25c4aa983 --- /dev/null +++ b/application/app/src/androidTest/java/org/videolan/vlc/util/UiUtils.kt @@ -0,0 +1,150 @@ +/* + * ************************************************************************ + * UiUtils.kt + * ************************************************************************* + * Copyright © 2020 VLC authors and VideoLAN + * Author: Nicolas POMEPUY + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + * ************************************************************************** + * + * + */ + +package org.videolan.vlc.util + +import android.app.Activity +import android.os.SystemClock +import android.view.View +import androidx.recyclerview.widget.RecyclerView +import androidx.test.espresso.Espresso +import androidx.test.espresso.PerformException +import androidx.test.espresso.UiController +import androidx.test.espresso.ViewAction +import androidx.test.espresso.matcher.ViewMatchers +import androidx.test.espresso.util.HumanReadables +import androidx.test.espresso.util.TreeIterables +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.runner.lifecycle.ActivityLifecycleMonitorRegistry +import androidx.test.runner.lifecycle.Stage +import org.hamcrest.Matcher +import java.util.concurrent.TimeoutException + +object UiUtils { + /** + * Perform action of waiting for a specific view id. + * @param viewId The id of the view to wait for. + * @param millis The timeout of until when to wait for. + */ + fun waitId(viewId: Int, millis: Long): ViewAction? { + return object : ViewAction { + override fun getConstraints(): Matcher = ViewMatchers.isEnabled() + + override fun getDescription() = "wait for a specific view with id <$viewId> during $millis millis." + + override fun perform(uiController: UiController, view: View?) { + uiController.loopMainThreadUntilIdle() + val startTime = System.currentTimeMillis() + val endTime = startTime + millis + val viewMatcher: Matcher = ViewMatchers.withId(viewId) + val alphaViewMatcher = ViewMatchers.withAlpha(1F) + do { + for (child in TreeIterables.breadthFirstViewTraversal(view)) { // found view with required ID + if (viewMatcher.matches(child)) { + if (alphaViewMatcher.matches(child)) + return + } + } + uiController.loopMainThreadForAtLeast(50) + } while (System.currentTimeMillis() < endTime) + throw PerformException.Builder() + .withActionDescription(description) + .withViewDescription(HumanReadables.describe(view)) + .withCause(TimeoutException()) + .build() + } + } + } + + /** + * Stop the test until RecyclerView's data gets loaded. + * + * Passed [recyclerProvider] will be activated in UI thread, allowing you to retrieve the View. + * + * Workaround for https://issuetracker.google.com/issues/123653014 + */ + inline fun waitUntilLoaded(crossinline recyclerProvider: () -> RecyclerView) { + Espresso.onIdle() + + lateinit var recycler: RecyclerView + + InstrumentationRegistry.getInstrumentation().runOnMainSync { + recycler = recyclerProvider() + } + + while (recycler.hasPendingAdapterUpdates()) { + Thread.sleep(10) + } + } + + fun waitForActivity(activityType: Class, timeout: Int = 10): Boolean { + val endTime = System.currentTimeMillis() + (timeout * 1000) + + do { + val currentActivity = getActivityInstance() + + // THIS LINE IS MY ISSUE ********************************************** + if (currentActivity != null && activityType.isInstance(currentActivity::class.java)) + return true + // ******************************************************************** + + SystemClock.sleep(100) + } while (System.currentTimeMillis() < endTime) + return false + } + + private fun getActivityInstance(): Activity? { + val activity = arrayOfNulls(1) + InstrumentationRegistry.getInstrumentation().runOnMainSync { + val currentActivity: Activity? + val resumedActivities = ActivityLifecycleMonitorRegistry.getInstance().getActivitiesInStage(Stage.RESUMED) + if (resumedActivities.iterator().hasNext()) { + currentActivity = resumedActivities.iterator().next() as Activity + activity[0] = currentActivity + } + } + return activity[0] + } + + /** + * Stop the test until RecyclerView's has children. + * + * Passed [recyclerProvider] will be activated in UI thread, allowing you to retrieve the View. + * + * Workaround for https://issuetracker.google.com/issues/123653014 + */ + inline fun waitUntilHasChildren(crossinline recyclerProvider: () -> RecyclerView) { + Espresso.onIdle() + + lateinit var recycler: RecyclerView + + InstrumentationRegistry.getInstrumentation().runOnMainSync { + recycler = recyclerProvider() + } + + while (recycler.childCount == 0) { + Thread.sleep(10) + } + } +} \ No newline at end of file diff --git a/application/resources/build.gradle b/application/resources/build.gradle index c0400af752..f7f116eb71 100644 --- a/application/resources/build.gradle +++ b/application/resources/build.gradle @@ -66,6 +66,8 @@ dependencies { api "com.squareup.moshi:moshi-adapters:$rootProject.ext.moshi" api "androidx.core:core-ktx:$rootProject.ext.androidxCoreVersion" + testApi "androidx.test:core:$rootProject.ext.testCore" + androidTestApi "androidx.test.ext:junit:$rootProject.ext.supportTest" } repositories { mavenCentral() diff --git a/application/television/build.gradle b/application/television/build.gradle index 1e8806fe06..750a16933f 100644 --- a/application/television/build.gradle +++ b/application/television/build.gradle @@ -45,4 +45,6 @@ android { dependencies { implementation project(':application:vlc-android') api project(':application:moviepedia') + testApi "androidx.test:core:$rootProject.ext.testCore" + androidTestApi "androidx.test.ext:junit:$rootProject.ext.supportTest" } diff --git a/application/vlc-android/AndroidManifest.xml b/application/vlc-android/AndroidManifest.xml index a018dfc5ef..97269742d6 100644 --- a/application/vlc-android/AndroidManifest.xml +++ b/application/vlc-android/AndroidManifest.xml @@ -3,7 +3,7 @@ xmlns:tools="http://schemas.android.com/tools" package="org.videolan.vlc"> - + - - - - - - \ No newline at end of file diff --git a/application/vlc-android/src/debug/AndroidManifest.xml b/application/vlc-android/src/debug/AndroidManifest.xml new file mode 100644 index 0000000000..e61891c821 --- /dev/null +++ b/application/vlc-android/src/debug/AndroidManifest.xml @@ -0,0 +1,10 @@ + + + + + + + \ No newline at end of file diff --git a/application/vlc-android/src/org/videolan/vlc/gui/MainActivity.kt b/application/vlc-android/src/org/videolan/vlc/gui/MainActivity.kt index ef1a1036b6..d753dca75e 100644 --- a/application/vlc-android/src/org/videolan/vlc/gui/MainActivity.kt +++ b/application/vlc-android/src/org/videolan/vlc/gui/MainActivity.kt @@ -73,7 +73,6 @@ class MainActivity : ContentActivity(), { var refreshing: Boolean = false set(value) { - mainLoading.visibility = if (value) View.VISIBLE else View.GONE field = value } private lateinit var mediaLibrary: Medialibrary @@ -96,11 +95,6 @@ class MainActivity : ContentActivity(), if (BuildConfig.DEBUG) extensionsManager = ExtensionsManager.getInstance() mediaLibrary = Medialibrary.getInstance() - val color = TypedValue().run { - theme.resolveAttribute(R.attr.progress_indeterminate_tint, this, true) - data - } - mainLoadingProgress.indeterminateDrawable.setColorFilter(color, android.graphics.PorterDuff.Mode.SRC_IN) VLCBilling.getInstance(application).retrieveSkus() } diff --git a/application/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserAdapter.kt b/application/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserAdapter.kt index 8881bf0a81..43eccff584 100644 --- a/application/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserAdapter.kt +++ b/application/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserAdapter.kt @@ -183,7 +183,7 @@ open class BaseBrowserAdapter(val browserContainer: BrowserContainer(bindingContainer.binding), MarqueeViewHolder { + inner class MediaViewHolder(val bindingContainer: BrowserItemBindingContainer) : ViewHolder(bindingContainer.binding), MarqueeViewHolder { override val titleView: TextView? = bindingContainer.title var job : Job? = null diff --git a/application/vlc-android/test/org/videolan/vlc/viewmodels/HistoryModelTest.kt b/application/vlc-android/test/org/videolan/vlc/viewmodels/HistoryModelTest.kt index d8d3579fa6..23dad51f27 100644 --- a/application/vlc-android/test/org/videolan/vlc/viewmodels/HistoryModelTest.kt +++ b/application/vlc-android/test/org/videolan/vlc/viewmodels/HistoryModelTest.kt @@ -22,12 +22,12 @@ class HistoryModelTest : BaseTest() { override fun beforeTest() { super.beforeTest() mediaLibrary.clearHistory() - historyModel = HistoryModel(context, TestCoroutineContextProvider()) + historyModel = HistoryModel(context, org.videolan.vlc.util.TestCoroutineContextProvider()) } @Test fun whenRefreshCalled_ListIsUpdated() { - val fakeMediaStrings = TestUtil.createLocalUris(2) + val fakeMediaStrings = org.videolan.vlc.util.TestUtil.createLocalUris(2) historyModel.refresh() @@ -54,7 +54,7 @@ class HistoryModelTest : BaseTest() { @Test fun whenListHasTwoItemsAndLastIsMovedUp_ListHasUpdatedItemsOrder() { - val fakeMediaStrings = TestUtil.createLocalUris(2) + val fakeMediaStrings = org.videolan.vlc.util.TestUtil.createLocalUris(2) val result = fakeMediaStrings.map { val media = MLServiceLocator.getAbstractMediaWrapper(it.toUri()).apply { type = MediaWrapper.TYPE_VIDEO } diff --git a/application/vlc-android/test/org/videolan/vlc/viewmodels/browser/FilePickerModelTest.kt b/application/vlc-android/test/org/videolan/vlc/viewmodels/browser/FilePickerModelTest.kt index 3437348185..12819e7997 100644 --- a/application/vlc-android/test/org/videolan/vlc/viewmodels/browser/FilePickerModelTest.kt +++ b/application/vlc-android/test/org/videolan/vlc/viewmodels/browser/FilePickerModelTest.kt @@ -46,14 +46,14 @@ class FilePickerModelTest : BaseTest() { mediaBrowser = spyk(MediaBrowser(mockedLibVlc, null, handler)) mediaBrowser } - BrowserProvider.registerCreator(clazz = CoroutineContextProvider::class.java) { TestCoroutineContextProvider() } + BrowserProvider.registerCreator(clazz = CoroutineContextProvider::class.java) { org.videolan.vlc.util.TestCoroutineContextProvider() } } override fun beforeTest() { super.beforeTest() dummyUrl = temporaryFolder.root.absolutePath - browserModel = BrowserModel(application, dummyUrl, TYPE_PICKER, false, true, TestCoroutineContextProvider()) + browserModel = BrowserModel(application, dummyUrl, TYPE_PICKER, false, true, org.videolan.vlc.util.TestCoroutineContextProvider()) browserProvider = browserModel.provider setupTestFiles() diff --git a/build.gradle b/build.gradle index ec1506451d..1d90673ed4 100644 --- a/build.gradle +++ b/build.gradle @@ -60,16 +60,18 @@ ext { archVersion = '2.1.0' roomVersion = '2.2.5' pagingVersion = '2.1.2' - junitVersion = '4.12' - mockito = '2.8.9' + junitVersion = '4.13' + mockito = '2.25.0' retrofit = '2.6.1' moshi = '1.8.0' powerMock = '2.0.2' - espressoVersion = '3.1.1' + espressoVersion = '3.3.0' livedataTest = '1.1.0' robolectric = '4.3.1' mockk = '1.9.3' - supportTest = '1.1.0' + supportTest = '1.1.2' + orchestrator = '1.1.0' + testCore = '1.3.0' // versionCode scheme is T M NN RR AA // T: Target/Flavour (1 for Android, 2 for Chrome?) // M: Major version from 0 to 9 diff --git a/buildsystem/automation/Gemfile b/buildsystem/automation/Gemfile new file mode 100644 index 0000000000..b734015f82 --- /dev/null +++ b/buildsystem/automation/Gemfile @@ -0,0 +1,10 @@ +# Autogenerated by fastlane +# +# Ensure this file is checked in to source control! + +source "https://rubygems.org" + +gem 'fastlane' + +plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') +eval_gemfile(plugins_path) if File.exist?(plugins_path) diff --git a/buildsystem/automation/README.md b/buildsystem/automation/README.md new file mode 100644 index 0000000000..79b19110f1 --- /dev/null +++ b/buildsystem/automation/README.md @@ -0,0 +1,87 @@ +# Automating screenshots + +## Installation + +### fastlane + +Install [fastlane](https://docs.fastlane.tools/) + +Even if Linux is not officially supported, it can be installed easily. + +`sudo apt install ruby ruby-dev` + +`export LC_ALL=en_US.UTF-8` + +`export LANG=en_US.UTF-8` + +`sudo gem install fastlane` + +### Android SDK + +The Android SDK has to be installed and you have to set an env variable to its path + +`export ANDROID_SDK=/path/to/sdk/` + +## Usage + +To launch a fastlane command, run `bundle exec fastlane [command] [option_key1]:[option_value_1] ...` + +Available lanes: + +### Deployment + +Once the build is done by the CI and signed, copy the apks into this directory + +#### Play Store: + +**Prerequisites**: + + Get the Play Store certificate and copy the file at `./certificates/vlc.json` + + Export an env variable named `K8S_SECRET_VLC_PLAYSTORE_PUBLIC_API_KEY` with the Play Stire API key + + Export an env variable named `SLACK_URL` with the slack webhook URL + + +- `deploy_release` sends a release to the Play Store in draft +- `deploy_beta` sends a beta to the Play Store in draft + +Options: `version` is the version string in the apk name. + +For example: `bundle exec fastlane deploy_beta version:"3.3.1-Beta-1"` creates a draft beta version on the Play Store for apks: + +``` +VLC-Android-3.3.1-Beta-1-arm64-v8a.apk +VLC-Android-3.3.1-Beta-1-armeabi-v7a.apk +VLC-Android-3.3.1-Beta-1-x86.apk +VLC-Android-3.3.1-Beta-1-x86_64.apk +``` + +#### Huawei + +**Prerequisites**: + +you need to export 3 env variables: HUAWEI_CLIENT_ID, HUAWEI_CLIENT_SECRET and HUAWEI_APP_ID + +- `deploy_huawei` sends a release to the Huawei AppGallery in draft + +Options: `version` is the version string in the apk name. + + +### Screenshots + +#### Take screenshots + +**Prerequisites**: + +In order to make the script work, you have to **create 3 AVDs**, **install VLC** and **add the samples** + +You should also skip the welcome screens and let the scanning occur. + +- `screenshots`, `screenshots_seven`, `screenshots_ten`, `screenshots_tv` lanes launch respectively the screenshot UI tests for mobile, 7" tablets, 10" tablets and TV + +Before running, the app and the test apks will be generated automatically + +#### Upload the screenshots + +- `deploy_screenshots` \ No newline at end of file diff --git a/buildsystem/automation/certificates b/buildsystem/automation/certificates new file mode 120000 index 0000000000..c3149007c4 --- /dev/null +++ b/buildsystem/automation/certificates @@ -0,0 +1 @@ +/home/nicolas/Documents/vlc/release \ No newline at end of file diff --git a/buildsystem/automation/fastlane/Appfile b/buildsystem/automation/fastlane/Appfile new file mode 100644 index 0000000000..a193e503ca --- /dev/null +++ b/buildsystem/automation/fastlane/Appfile @@ -0,0 +1,2 @@ +json_key_file("certificates/vlc.json") # Path to the json secret file - Follow https://docs.fastlane.tools/actions/supply/#setup to get one +package_name("org.videolan.vlc") diff --git a/buildsystem/automation/fastlane/Fastfile b/buildsystem/automation/fastlane/Fastfile new file mode 100644 index 0000000000..378ad74334 --- /dev/null +++ b/buildsystem/automation/fastlane/Fastfile @@ -0,0 +1,84 @@ +# This file contains the fastlane.tools configuration +# You can find the documentation at https://docs.fastlane.tools +# +# For a list of all available actions, check out +# +# https://docs.fastlane.tools/actions +# +# For a list of all available plugins, check out +# +# https://docs.fastlane.tools/plugins/available-plugins +# + +# Uncomment the line if you want fastlane to automatically update itself +# update_fastlane + +default_platform(:android) + +platform :android do + desc "Runs all the tests" + lane :test do + gradle(task: "test") + end + + desc "Deploy a new version to the Google Play" + lane :deploy_release do |options| + upload_to_play_store(skip_upload_changelogs:true, skip_upload_images:true, skip_upload_screenshots:true, release_status:"draft", apk_paths:["VLC-Android-"+options[:version]+"-arm64-v8a.apk", "VLC-Android-"+options[:version]+"-armeabi-v7a.apk", "VLC-Android-"+options[:version]+"-x86.apk", "VLC-Android-"+options[:version]+"-x86_64.apk"]) + slack(message: 'Successfully created a new draft for '+options[:version]) + end + + lane :deploy_screenshots do + upload_to_play_store(skip_upload_changelogs:true, skip_upload_images:true, skip_upload_apk:true, release_status:"draft", apk_paths:["VLC-Android-3.3.0-arm64-v8a.apk", "VLC-Android-3.3.0-armeabi-v7a.apk", "VLC-Android-3.3.0-x86.apk", "VLC-Android-3.3.0-x86_64.apk"]) + slack(message: 'Successfully uploaded screenshots to Play Store') + end + + lane :deploy_beta do |options| + upload_to_play_store(skip_upload_changelogs:true, track: 'beta', skip_upload_images:true, skip_upload_screenshots:true, skip_upload_apk:false, release_status:"draft", apk_paths:["VLC-Android-"+options[:version]+"-arm64-v8a.apk", "VLC-Android-"+options[:version]+"-armeabi-v7a.apk", "VLC-Android-"+options[:version]+"-x86.apk", "VLC-Android-"+options[:version]+"-x86_64.apk"]) + slack(message: 'Successfully created a new beta draft for '+options[:version]) + end + + lane :screenshots do + gradle(task: 'assemble', build_type: 'Debug', project_dir:'../..') + gradle(task: ':application:app:assemble', build_type: 'DebugAndroidTest', project_dir:'../..') + capture_android_screenshots(app_apk_path:"../../application/app/build/outputs/apk/debug/VLC-Android-3.3.0-debug-all.apk", tests_apk_path:"../../application/app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk") + end + + lane :screenshots_seven do + gradle(task: 'assemble', build_type: 'Debug', project_dir:'../..') + gradle(task: ':application:app:assemble', build_type: 'DebugAndroidTest', project_dir:'../..') + capture_android_screenshots(device_type:"sevenInch" ,app_apk_path:"../../application/app/build/outputs/apk/debug/VLC-Android-3.3.0-debug-all.apk", tests_apk_path:"../../application/app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk") + end + + lane :screenshots_ten do + gradle(task: 'assemble', build_type: 'Debug', project_dir:'../..') + gradle(task: ':application:app:assemble', build_type: 'DebugAndroidTest', project_dir:'../..') + capture_android_screenshots(device_type:"tenInch" ,app_apk_path:"../../application/app/build/outputs/apk/debug/VLC-Android-3.3.0-debug-all.apk", tests_apk_path:"../../application/app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk") + end + + lane :screenshots_tv do + gradle(task: 'assemble', build_type: 'Debug', project_dir:'../..') + gradle(task: ':application:app:assemble', build_type: 'DebugAndroidTest', project_dir:'../..') + capture_android_screenshots(device_type:"tv",use_tests_in_classes:'org.videolan.vlc.TvScreenhotsInstrumentedTest', app_apk_path:"../../application/app/build/outputs/apk/debug/VLC-Android-3.3.0-debug-all.apk", tests_apk_path:"../../application/app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk") + end + + lane :huawei_info do + huawei_appgallery_connect_get_app_info( + client_id: ENV["HUAWEI_CLIENT_ID"], + client_secret: ENV["HUAWEI_CLIENT_SECRET"], + app_id: ENV["HUAWEI_APP_ID"] + ) + end + + lane :deploy_huawei do |options| + #gradle(task: 'assemble', build_type: 'Release') + huawei_appgallery_connect( + client_id: ENV["HUAWEI_CLIENT_ID"], + client_secret: ENV["HUAWEI_CLIENT_SECRET"], + app_id: ENV["HUAWEI_APP_ID"], + apk_path: "VLC-Android-"+options[:version]+"-arm64-v8a.apk", + submit_for_review: false, + ) + slack(message: 'Successfully created a new draft for '+options[:version]+' on Huawei AppGallery') + end + +end diff --git a/buildsystem/automation/fastlane/Pluginfile b/buildsystem/automation/fastlane/Pluginfile new file mode 100644 index 0000000000..67ece58375 --- /dev/null +++ b/buildsystem/automation/fastlane/Pluginfile @@ -0,0 +1,5 @@ +# Autogenerated by fastlane +# +# Ensure this file is checked in to source control! + +gem 'fastlane-plugin-huawei_appgallery_connect' diff --git a/buildsystem/automation/fastlane/Screengrabfile b/buildsystem/automation/fastlane/Screengrabfile new file mode 100644 index 0000000000..a94840ec72 --- /dev/null +++ b/buildsystem/automation/fastlane/Screengrabfile @@ -0,0 +1,15 @@ +# remove the leading '#' to uncomment lines + + app_package_name("org.videolan.vlc.debug") + use_tests_in_classes(['org.videolan.vlc.PhoneScreenhotsInstrumentedTest']) + +use_adb_root(true) +test_instrumentation_runner("org.videolan.vlc.MultidexTestRunner") +#locales(['en-US', 'fr-FR', 'it-IT', 'ko-KR', 'ja-JP']) +locales(['en-US', 'fr-FR', 'it-IT']) + +# clear all previously generated screenshots in your local output directory before creating new ones +clear_previous_screenshots(true) + +# For more information about all available options run +# fastlane screengrab --help diff --git a/extension-api/src/androidTest/java/org/videolan/vlc/plugin/api/ApplicationTest.java b/extension-api/src/androidTest/java/org/videolan/vlc/plugin/api/ApplicationTest.java deleted file mode 100644 index 75c1555764..0000000000 --- a/extension-api/src/androidTest/java/org/videolan/vlc/plugin/api/ApplicationTest.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * ************************************************************************* - * ApplicationTest.java - * ************************************************************************** - * Copyright © 2015 VLC authors and VideoLAN - * Author: Geoffrey Métais - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. - * *************************************************************************** - */ - -package org.videolan.vlc.extensions.api; - -import android.app.Application; -import android.test.ApplicationTestCase; - -/** - * Testing Fundamentals - */ -public class ApplicationTest extends ApplicationTestCase { - public ApplicationTest() { - super(Application.class); - } -} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index a4223faa30..9a71bd8217 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,5 +4,5 @@ android.databinding.incremental=true kapt.incremental.apt=true kapt.use.worker.api=true kapt.include.compile.classpath=false -org.gradle.jvmargs=-Xmx4g -XX:MaxPermSize=2048m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 +org.gradle.jvmargs=-Xms512M -Xmx4g -XX:MaxPermSize=2048m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 org.gradle.parallel=true