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