From f7ae08325b35498beb56d71d64aef316ac1ec818 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Thu, 28 Nov 2019 10:00:53 +0100 Subject: Added Android emulator test --- .github/workflows/android-emulator.yml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 .github/workflows/android-emulator.yml diff --git a/.github/workflows/android-emulator.yml b/.github/workflows/android-emulator.yml new file mode 100644 index 000000000..963b084f7 --- /dev/null +++ b/.github/workflows/android-emulator.yml @@ -0,0 +1,29 @@ +name: Android Emulator test + +on: [push] + +jobs: + build: + + runs-on: macOS-latest + + steps: + - uses: actions/checkout@v1 + - name: set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: Build with Gradle + run: ./gradlew assemblePlayDebugAndroidTest + - name: Android Emulator test + uses: ReactiveCircus/android-emulator-runner@v1.0.1 + with: + api-level: 28 + headless: true + disable-animations: true + script: ./gradlew connectedPlayDebugAndroidTest + - uses: actions/upload-artifact@v1 + if: failure() + with: + name: test-report + path: app/build/reports/androidTests/connected/flavors/PLAY/ -- cgit v1.2.3 From e51a107083101b64614b30324ae6cc2226a3f835 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Thu, 28 Nov 2019 23:34:26 +0100 Subject: Fixed tests on small screens In general, made some tests more stable --- .../java/de/test/antennapod/EspressoTestUtils.java | 31 ++++++++++++++++++---- .../java/de/test/antennapod/NthMatcher.java | 7 ++--- .../de/test/antennapod/playback/PlaybackTest.java | 28 ++++++------------- .../service/download/DownloadServiceTest.java | 5 +++- .../test/antennapod/storage/AutoDownloadTest.java | 11 +++----- .../de/test/antennapod/ui/MainActivityTest.java | 4 +-- .../de/test/antennapod/ui/PreferencesTest.java | 21 ++++++++------- 7 files changed, 58 insertions(+), 49 deletions(-) diff --git a/app/src/androidTest/java/de/test/antennapod/EspressoTestUtils.java b/app/src/androidTest/java/de/test/antennapod/EspressoTestUtils.java index c76cd2032..d4d589859 100644 --- a/app/src/androidTest/java/de/test/antennapod/EspressoTestUtils.java +++ b/app/src/androidTest/java/de/test/antennapod/EspressoTestUtils.java @@ -1,6 +1,7 @@ package de.test.antennapod; import android.content.Context; +import androidx.annotation.IdRes; import androidx.annotation.StringRes; import androidx.test.InstrumentationRegistry; import androidx.test.espresso.PerformException; @@ -76,6 +77,31 @@ public class EspressoTestUtils { }; } + /** + * Perform action of waiting for a specific view id. + * https://stackoverflow.com/a/30338665/ + * @param id The id of the child to click. + */ + public static ViewAction clickChildViewWithId(final @IdRes int id) { + return new ViewAction() { + @Override + public Matcher getConstraints() { + return null; + } + + @Override + public String getDescription() { + return "Click on a child view with specified id."; + } + + @Override + public void perform(UiController uiController, View view) { + View v = view.findViewById(id); + v.performClick(); + } + }; + } + /** * Clear all app databases */ @@ -127,11 +153,6 @@ public class EspressoTestUtils { onView(withId(R.id.drawer_layout)).perform(DrawerActions.open()); } - public static void closeNavDrawer() { - onView(isRoot()).perform(waitForView(withId(R.id.drawer_layout), 1000)); - onView(withId(R.id.drawer_layout)).perform(DrawerActions.close()); - } - public static ViewInteraction onDrawerItem(Matcher viewMatcher) { return onView(allOf(viewMatcher, withId(R.id.txtvTitle))); } diff --git a/app/src/androidTest/java/de/test/antennapod/NthMatcher.java b/app/src/androidTest/java/de/test/antennapod/NthMatcher.java index 3f2b83a26..85eabcc63 100644 --- a/app/src/androidTest/java/de/test/antennapod/NthMatcher.java +++ b/app/src/androidTest/java/de/test/antennapod/NthMatcher.java @@ -11,10 +11,6 @@ public class NthMatcher { return nth(matcher, 1); } - public static Matcher second(final Matcher matcher) { - return nth(matcher, 2); - } - public static Matcher nth(final Matcher matcher, final int index) { return new BaseMatcher() { AtomicInteger count = new AtomicInteger(0); @@ -31,7 +27,8 @@ public class NthMatcher { @Override public void describeTo(final Description description) { - description.appendText("should return first matching item"); + description.appendText("Item #" + index + " "); + description.appendDescriptionOf(matcher); } }; } diff --git a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java index be2fc432c..3809d767b 100644 --- a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java +++ b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java @@ -27,18 +27,18 @@ import java.util.concurrent.TimeUnit; import static androidx.test.espresso.Espresso.onView; import static androidx.test.espresso.action.ViewActions.click; +import static androidx.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition; import static androidx.test.espresso.matcher.ViewMatchers.isRoot; import static androidx.test.espresso.matcher.ViewMatchers.withId; import static androidx.test.espresso.matcher.ViewMatchers.withText; +import static de.test.antennapod.EspressoTestUtils.clickChildViewWithId; import static de.test.antennapod.EspressoTestUtils.onDrawerItem; import static de.test.antennapod.EspressoTestUtils.openNavDrawer; import static de.test.antennapod.EspressoTestUtils.waitForView; import static de.test.antennapod.NthMatcher.first; -import static de.test.antennapod.NthMatcher.nth; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static org.hamcrest.Matchers.hasItems; import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; @@ -78,23 +78,9 @@ public abstract class PlaybackTest { setContinuousPlaybackPreference(false); uiTestUtils.addLocalFeedData(true); activityTestRule.launchActivity(new Intent()); - List queue = DBReader.getQueue(); - final FeedItem first = queue.get(0); playFromQueue(0); - Awaitility.await().atMost(5, TimeUnit.SECONDS).until(() -> { - if (uiTestUtils.getPlaybackController(getActivity()).getStatus() - != PlayerStatus.PLAYING) { - return true; - } else if (uiTestUtils.getCurrentMedia(getActivity()) != null) { - return uiTestUtils.getCurrentMedia(getActivity()).getId() - != first.getMedia().getId(); - } else { - return true; - } - }); - - Thread.sleep(1000); - assertNotEquals(PlayerStatus.PLAYING, uiTestUtils.getPlaybackController(getActivity()).getStatus()); + Awaitility.await().atMost(5, TimeUnit.SECONDS).until( + () -> uiTestUtils.getPlaybackController(getActivity()).getStatus() == PlayerStatus.INITIALIZED); } @Test @@ -225,7 +211,7 @@ public abstract class PlaybackTest { protected void startLocalPlayback() { openNavDrawer(); onDrawerItem(withText(R.string.episodes_label)).perform(click()); - onView(isRoot()).perform(waitForView(withId(R.id.emptyViewTitle), 1000)); + onView(isRoot()).perform(waitForView(withText(R.string.all_episodes_short_label), 1000)); onView(withText(R.string.all_episodes_short_label)).perform(click()); final List episodes = DBReader.getRecentlyPublishedEpisodes(0, 10); @@ -249,7 +235,9 @@ public abstract class PlaybackTest { protected void playFromQueue(int itemIdx) { final List queue = DBReader.getQueue(); - onView(nth(withId(R.id.butSecondaryAction), itemIdx + 1)).perform(click()); + onView(withId(R.id.recyclerView)).perform( + actionOnItemAtPosition(itemIdx, clickChildViewWithId(R.id.butSecondaryAction))); + onView(isRoot()).perform(waitForView(withId(R.id.butPlay), 1000)); long mediaId = queue.get(itemIdx).getMedia().getId(); Awaitility.await().atMost(1, TimeUnit.SECONDS).until(() -> { diff --git a/app/src/androidTest/java/de/test/antennapod/service/download/DownloadServiceTest.java b/app/src/androidTest/java/de/test/antennapod/service/download/DownloadServiceTest.java index d0e14d70a..6b020efcb 100644 --- a/app/src/androidTest/java/de/test/antennapod/service/download/DownloadServiceTest.java +++ b/app/src/androidTest/java/de/test/antennapod/service/download/DownloadServiceTest.java @@ -5,6 +5,7 @@ import androidx.annotation.Nullable; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; +import de.test.antennapod.EspressoTestUtils; import org.awaitility.Awaitility; import org.awaitility.core.ConditionTimeoutException; import org.junit.After; @@ -53,6 +54,8 @@ public class DownloadServiceTest { @Before public void setUp() throws Exception { + EspressoTestUtils.clearDatabase(); + EspressoTestUtils.clearPreferences(); origFactory = DownloadService.getDownloaderFactory(); testFeed = setUpTestFeeds(); testMedia11 = testFeed.getItemAtIndex(0).getMedia(); @@ -171,7 +174,7 @@ public class DownloadServiceTest { final int totalNumEventsExpected = itemAlreadyInQueue ? 1 : 3; Awaitility.await("item dequeue event + download termination event") .atMost(1000, TimeUnit.MILLISECONDS) - .until(() ->feedItemEventListener.getEvents().size() >= totalNumEventsExpected); + .until(() -> feedItemEventListener.getEvents().size() >= totalNumEventsExpected); assertFalse("The download should have been canceled", DBReader.getFeedMedia(testMedia11.getId()).isDownloaded()); if (itemAlreadyInQueue) { diff --git a/app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java b/app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java index 00eef5c8d..471717393 100644 --- a/app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java +++ b/app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java @@ -7,6 +7,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.test.core.app.ApplicationProvider; +import de.test.antennapod.EspressoTestUtils; import org.awaitility.Awaitility; import org.awaitility.core.ConditionTimeoutException; import org.junit.After; @@ -49,12 +50,8 @@ public class AutoDownloadTest { dbTasksCallbacksOrig = ClientConfig.dbTasksCallbacks; - // create new database - PodDBAdapter.init(context); - PodDBAdapter.deleteDatabase(); - PodDBAdapter adapter = PodDBAdapter.getInstance(); - adapter.open(); - adapter.close(); + EspressoTestUtils.clearPreferences(); + EspressoTestUtils.clearDatabase(); } @After @@ -126,7 +123,7 @@ public class AutoDownloadTest { if (playable == null) { return null; } - return ((FeedMedia)playable).getItem(); + return ((FeedMedia) playable).getItem(); } private void useDownloadAlgorithm(final AutomaticDownloadAlgorithm downloadAlgorithm) { diff --git a/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java b/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java index 42c770df9..bdcad215d 100644 --- a/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java +++ b/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java @@ -75,8 +75,8 @@ public class MainActivityTest { final Feed feed = uiTestUtils.hostedFeeds.get(0); openNavDrawer(); onView(withText(R.string.add_feed_label)).perform(click()); - onView(withId(R.id.etxtFeedurl)).perform(typeText(feed.getDownload_url())); - onView(withText(R.string.confirm_label)).perform(scrollTo()).perform(click()); + onView(withId(R.id.etxtFeedurl)).perform(scrollTo(), typeText(feed.getDownload_url())); + onView(withText(R.string.confirm_label)).perform(scrollTo(), click()); Espresso.closeSoftKeyboard(); onView(withText(R.string.subscribe_label)).perform(click()); intended(hasComponent(MainActivity.class.getName()), times(2)); diff --git a/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java b/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java index e734e4a67..a68afbc2e 100644 --- a/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java +++ b/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java @@ -32,6 +32,7 @@ import static androidx.test.espresso.Espresso.onView; import static androidx.test.espresso.action.ViewActions.click; import static androidx.test.espresso.action.ViewActions.replaceText; import static androidx.test.espresso.action.ViewActions.scrollTo; +import static androidx.test.espresso.action.ViewActions.swipeDown; import static androidx.test.espresso.action.ViewActions.swipeUp; import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist; import static androidx.test.espresso.assertion.ViewAssertions.matches; @@ -246,10 +247,10 @@ public class PreferencesTest { public void testPauseForInterruptions() { onView(withText(R.string.playback_pref)).perform(click()); final boolean pauseForFocusLoss = UserPreferences.shouldPauseForFocusLoss(); - onView(withText(R.string.pref_pausePlaybackForFocusLoss_title)).perform(click()); + clickPreference(R.string.pref_pausePlaybackForFocusLoss_title); Awaitility.await().atMost(1000, MILLISECONDS) .until(() -> pauseForFocusLoss != UserPreferences.shouldPauseForFocusLoss()); - onView(withText(R.string.pref_pausePlaybackForFocusLoss_title)).perform(click()); + clickPreference(R.string.pref_pausePlaybackForFocusLoss_title); Awaitility.await().atMost(1000, MILLISECONDS) .until(() -> pauseForFocusLoss == UserPreferences.shouldPauseForFocusLoss()); } @@ -332,7 +333,8 @@ public class PreferencesTest { clickPreference(R.string.network_pref); clickPreference(R.string.pref_automatic_download_title); clickPreference(R.string.pref_episode_cache_title); - onView(withText(minEntry)).perform(scrollTo()).perform(click()); + onView(withId(R.id.select_dialog_listview)).perform(swipeDown()); + onView(withText(minEntry)).perform(click()); Awaitility.await().atMost(1000, MILLISECONDS) .until(() -> UserPreferences.getEpisodeCacheSize() == minValue); } @@ -346,6 +348,7 @@ public class PreferencesTest { onView(withText(R.string.network_pref)).perform(click()); onView(withText(R.string.pref_automatic_download_title)).perform(click()); onView(withText(R.string.pref_episode_cache_title)).perform(click()); + onView(withId(R.id.select_dialog_listview)).perform(swipeUp()); onView(withText(maxEntry)).perform(click()); Awaitility.await().atMost(1000, MILLISECONDS) .until(() -> UserPreferences.getEpisodeCacheSize() == maxValue); @@ -365,17 +368,17 @@ public class PreferencesTest { Awaitility.await().atMost(1000, MILLISECONDS) .until(UserPreferences::isEnableAutodownload); final boolean enableAutodownloadOnBattery = UserPreferences.isEnableAutodownloadOnBattery(); - onView(withText(R.string.pref_automatic_download_on_battery_title)).perform(click()); + clickPreference(R.string.pref_automatic_download_on_battery_title); Awaitility.await().atMost(1000, MILLISECONDS) .until(() -> enableAutodownloadOnBattery != UserPreferences.isEnableAutodownloadOnBattery()); - onView(withText(R.string.pref_automatic_download_on_battery_title)).perform(click()); + clickPreference(R.string.pref_automatic_download_on_battery_title); Awaitility.await().atMost(1000, MILLISECONDS) .until(() -> enableAutodownloadOnBattery == UserPreferences.isEnableAutodownloadOnBattery()); final boolean enableWifiFilter = UserPreferences.isEnableAutodownloadWifiFilter(); - onView(withText(R.string.pref_autodl_wifi_filter_title)).perform(click()); + clickPreference(R.string.pref_autodl_wifi_filter_title); Awaitility.await().atMost(1000, MILLISECONDS) .until(() -> enableWifiFilter != UserPreferences.isEnableAutodownloadWifiFilter()); - onView(withText(R.string.pref_autodl_wifi_filter_title)).perform(click()); + clickPreference(R.string.pref_autodl_wifi_filter_title); Awaitility.await().atMost(1000, MILLISECONDS) .until(() -> enableWifiFilter == UserPreferences.isEnableAutodownloadWifiFilter()); } @@ -425,7 +428,7 @@ public class PreferencesTest { clickPreference(R.string.network_pref); clickPreference(R.string.pref_automatic_download_title); clickPreference(R.string.pref_episode_cleanup_title); - String search = res.getQuantityString(R.plurals.episode_cleanup_days_after_listening, 5, 5); + String search = res.getQuantityString(R.plurals.episode_cleanup_days_after_listening, 3, 3); onView(isRoot()).perform(waitForView(withText(search), 1000)); onView(withText(search)).perform(click()); Awaitility.await().atMost(1000, MILLISECONDS) @@ -433,7 +436,7 @@ public class PreferencesTest { EpisodeCleanupAlgorithm alg = UserPreferences.getEpisodeCleanupAlgorithm(); if (alg instanceof APCleanupAlgorithm) { APCleanupAlgorithm cleanupAlg = (APCleanupAlgorithm) alg; - return cleanupAlg.getNumberOfHoursAfterPlayback() == 120; // 5 days + return cleanupAlg.getNumberOfHoursAfterPlayback() == 72; // 5 days } return false; }); -- cgit v1.2.3 From 75754ba0f81c399979ea5ccd5fd30d7b1e55a490 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Sun, 1 Dec 2019 23:06:59 +0100 Subject: Give the test some more time Also, use 30sec to prevent passing because of playback finished instead of skipping --- app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java index 3809d767b..6ea8a1833 100644 --- a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java +++ b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java @@ -287,6 +287,7 @@ public abstract class PlaybackTest { setSmartMarkAsPlayedPreference(60); // ensure when an episode is skipped, it is removed due to smart as played setSkipKeepsEpisodePreference(false); + uiTestUtils.setMediaFileName("30sec.mp3"); uiTestUtils.addLocalFeedData(true); int fiIdx; @@ -304,7 +305,7 @@ public abstract class PlaybackTest { // assert item no longer in queue (needs to wait till skip is asynchronously processed) Awaitility.await() - .atMost(1000, MILLISECONDS) + .atMost(3000, MILLISECONDS) .until(() -> !DBReader.getQueue().contains(feedItem)); assertTrue(DBReader.getFeedItem(feedItem.getId()).isPlayed()); } -- cgit v1.2.3 From 0d5e3307b0f5ffe7623158aefbfabb034fdd88af Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Mon, 2 Dec 2019 09:29:43 +0100 Subject: Making sure that activity is finished when deleting feed data --- .../java/de/test/antennapod/playback/PlaybackTest.java | 7 ++++--- .../java/de/test/antennapod/storage/AutoDownloadTest.java | 12 +++++++----- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java index 6ea8a1833..9732ac215 100644 --- a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java +++ b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java @@ -67,10 +67,11 @@ public abstract class PlaybackTest { @After public void tearDown() throws Exception { activityTestRule.finishActivity(); + Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); + context.stopService(new Intent(context, PlaybackService.class)); + Awaitility.await().atMost(5, TimeUnit.SECONDS).until(() -> !PlaybackService.isRunning); + InstrumentationRegistry.getInstrumentation().waitForIdleSync(); uiTestUtils.tearDown(); - // shut down playback service - context.sendBroadcast(new Intent(PlaybackService.ACTION_SHUTDOWN_PLAYBACK_SERVICE)); - Awaitility.await().until(() -> !PlaybackService.isRunning); } @Test diff --git a/app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java b/app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java index 471717393..3a4858e98 100644 --- a/app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java +++ b/app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java @@ -7,6 +7,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.test.core.app.ApplicationProvider; +import androidx.test.platform.app.InstrumentationRegistry; import de.test.antennapod.EspressoTestUtils; import org.awaitility.Awaitility; import org.awaitility.core.ConditionTimeoutException; @@ -15,6 +16,7 @@ import org.junit.Before; import org.junit.Test; import java.util.List; +import java.util.concurrent.TimeUnit; import de.danoeh.antennapod.core.ClientConfig; import de.danoeh.antennapod.core.DBTasksCallbacks; @@ -56,11 +58,11 @@ public class AutoDownloadTest { @After public void tearDown() throws Exception { - stubFeedsServer.tearDown(); ClientConfig.dbTasksCallbacks = dbTasksCallbacksOrig; - - context.sendBroadcast(new Intent(PlaybackService.ACTION_SHUTDOWN_PLAYBACK_SERVICE)); - Awaitility.await().until(() -> !PlaybackService.isRunning); + context.stopService(new Intent(context, PlaybackService.class)); + Awaitility.await().atMost(5, TimeUnit.SECONDS).until(() -> !PlaybackService.isRunning); + InstrumentationRegistry.getInstrumentation().waitForIdleSync(); + stubFeedsServer.tearDown(); } /** @@ -114,7 +116,7 @@ public class AutoDownloadTest { FeedMedia media = item.getMedia(); DBTasks.playMedia(context, media, false, true, true); Awaitility.await("episode is playing") - .atMost(1000, MILLISECONDS) + .atMost(2000, MILLISECONDS) .until(() -> item.equals(getCurrentlyPlaying())); } -- cgit v1.2.3 From e77ecda206c36cc0743b470e4f9f286325ceaba6 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Mon, 2 Dec 2019 09:37:33 +0100 Subject: Fixed cases where one failing test broke all following tests Select a random port for the http server, so we do not get EADDRINUSE --- .../service/download/HttpDownloaderTest.java | 29 ++++++++++------------ .../playback/PlaybackServiceMediaPlayerTest.java | 28 ++++++++++----------- .../java/de/test/antennapod/ui/UITestUtils.java | 4 +-- .../antennapod/util/service/download/HTTPBin.java | 9 ++++--- 4 files changed, 34 insertions(+), 36 deletions(-) diff --git a/app/src/androidTest/java/de/test/antennapod/service/download/HttpDownloaderTest.java b/app/src/androidTest/java/de/test/antennapod/service/download/HttpDownloaderTest.java index 4530b7679..7d9ec7c98 100644 --- a/app/src/androidTest/java/de/test/antennapod/service/download/HttpDownloaderTest.java +++ b/app/src/androidTest/java/de/test/antennapod/service/download/HttpDownloaderTest.java @@ -29,10 +29,9 @@ public class HttpDownloaderTest { private static final String TAG = "HttpDownloaderTest"; private static final String DOWNLOAD_DIR = "testdownloads"; - private static boolean successful = true; - + private String url404; + private String urlAuth; private File destDir; - private HTTPBin httpServer; public HttpDownloaderTest() { @@ -57,6 +56,8 @@ public class HttpDownloaderTest { assertTrue(destDir.exists()); httpServer = new HTTPBin(); httpServer.start(); + url404 = httpServer.getBaseUrl() + "/status/404"; + urlAuth = httpServer.getBaseUrl() + "/basic-auth/user/passwd"; } private FeedFileImpl setupFeedFile(String downloadUrl, String title, boolean deleteExisting) { @@ -88,33 +89,29 @@ public class HttpDownloaderTest { return downloader; } - - private static final String URL_404 = HTTPBin.BASE_URL + "/status/404"; - private static final String URL_AUTH = HTTPBin.BASE_URL + "/basic-auth/user/passwd"; - @Test public void testPassingHttp() { - download(HTTPBin.BASE_URL + "/status/200", "test200", true); + download(httpServer.getBaseUrl() + "/status/200", "test200", true); } @Test public void testRedirect() { - download(HTTPBin.BASE_URL + "/redirect/4", "testRedirect", true); + download(httpServer.getBaseUrl() + "/redirect/4", "testRedirect", true); } @Test public void testGzip() { - download(HTTPBin.BASE_URL + "/gzip/100", "testGzip", true); + download(httpServer.getBaseUrl() + "/gzip/100", "testGzip", true); } @Test public void test404() { - download(URL_404, "test404", false); + download(url404, "test404", false); } @Test public void testCancel() { - final String url = HTTPBin.BASE_URL + "/delay/3"; + final String url = httpServer.getBaseUrl() + "/delay/3"; FeedFileImpl feedFile = setupFeedFile(url, "delay", true); final Downloader downloader = new HttpDownloader(new DownloadRequest(feedFile.getFile_url(), url, "delay", 0, feedFile.getTypeAsInt())); Thread t = new Thread() { @@ -139,7 +136,7 @@ public class HttpDownloaderTest { @Test public void testDeleteOnFailShouldDelete() { - Downloader downloader = download(URL_404, "testDeleteOnFailShouldDelete", false, true, null, null, true); + Downloader downloader = download(url404, "testDeleteOnFailShouldDelete", false, true, null, null, true); assertFalse(new File(downloader.getDownloadRequest().getDestination()).exists()); } @@ -149,18 +146,18 @@ public class HttpDownloaderTest { File dest = new File(destDir, filename); dest.delete(); assertTrue(dest.createNewFile()); - Downloader downloader = download(URL_404, filename, false, false, null, null, false); + Downloader downloader = download(url404, filename, false, false, null, null, false); assertTrue(new File(downloader.getDownloadRequest().getDestination()).exists()); } @Test public void testAuthenticationShouldSucceed() throws InterruptedException { - download(URL_AUTH, "testAuthSuccess", true, true, "user", "passwd", true); + download(urlAuth, "testAuthSuccess", true, true, "user", "passwd", true); } @Test public void testAuthenticationShouldFail() { - Downloader downloader = download(URL_AUTH, "testAuthSuccess", false, true, "user", "Wrong passwd", true); + Downloader downloader = download(urlAuth, "testAuthSuccess", false, true, "user", "Wrong passwd", true); assertEquals(DownloadError.ERROR_UNAUTHORIZED, downloader.getResult().getReason()); } diff --git a/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java b/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java index 3511fd0b1..00fc68598 100644 --- a/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java +++ b/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java @@ -45,13 +45,12 @@ import static org.junit.Assert.fail; */ @MediumTest public class PlaybackServiceMediaPlayerTest { - private static final String PLAYABLE_FILE_URL = "http://127.0.0.1:" + HTTPBin.PORT + "/files/0"; private static final String PLAYABLE_DEST_URL = "psmptestfile.mp3"; private String PLAYABLE_LOCAL_URL = null; private static final int LATCH_TIMEOUT_SECONDS = 3; private HTTPBin httpServer; - + private String playableFileUrl; private volatile AssertionFailedError assertionError; @After @@ -71,6 +70,7 @@ public class PlaybackServiceMediaPlayerTest { httpServer = new HTTPBin(); httpServer.start(); + playableFileUrl = httpServer.getBaseUrl() + "/files/0"; File cacheDir = context.getExternalFilesDir("testFiles"); if (cacheDir == null) @@ -167,7 +167,7 @@ public class PlaybackServiceMediaPlayerTest { } }); PlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback); - Playable p = writeTestPlayable(PLAYABLE_FILE_URL, null); + Playable p = writeTestPlayable(playableFileUrl, null); psmp.playMediaObject(p, true, false, false); boolean res = countDownLatch.await(LATCH_TIMEOUT_SECONDS, TimeUnit.SECONDS); if (assertionError != null) @@ -207,7 +207,7 @@ public class PlaybackServiceMediaPlayerTest { } }); PlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback); - Playable p = writeTestPlayable(PLAYABLE_FILE_URL, null); + Playable p = writeTestPlayable(playableFileUrl, null); psmp.playMediaObject(p, true, true, false); boolean res = countDownLatch.await(LATCH_TIMEOUT_SECONDS, TimeUnit.SECONDS); @@ -251,7 +251,7 @@ public class PlaybackServiceMediaPlayerTest { } }); PlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback); - Playable p = writeTestPlayable(PLAYABLE_FILE_URL, null); + Playable p = writeTestPlayable(playableFileUrl, null); psmp.playMediaObject(p, true, false, true); boolean res = countDownLatch.await(LATCH_TIMEOUT_SECONDS, TimeUnit.SECONDS); if (assertionError != null) @@ -296,7 +296,7 @@ public class PlaybackServiceMediaPlayerTest { } }); PlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback); - Playable p = writeTestPlayable(PLAYABLE_FILE_URL, null); + Playable p = writeTestPlayable(playableFileUrl, null); psmp.playMediaObject(p, true, true, true); boolean res = countDownLatch.await(LATCH_TIMEOUT_SECONDS, TimeUnit.SECONDS); if (assertionError != null) @@ -334,7 +334,7 @@ public class PlaybackServiceMediaPlayerTest { } }); PlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback); - Playable p = writeTestPlayable(PLAYABLE_FILE_URL, PLAYABLE_LOCAL_URL); + Playable p = writeTestPlayable(playableFileUrl, PLAYABLE_LOCAL_URL); psmp.playMediaObject(p, false, false, false); boolean res = countDownLatch.await(LATCH_TIMEOUT_SECONDS, TimeUnit.SECONDS); if (assertionError != null) @@ -373,7 +373,7 @@ public class PlaybackServiceMediaPlayerTest { } }); PlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback); - Playable p = writeTestPlayable(PLAYABLE_FILE_URL, PLAYABLE_LOCAL_URL); + Playable p = writeTestPlayable(playableFileUrl, PLAYABLE_LOCAL_URL); psmp.playMediaObject(p, false, true, false); boolean res = countDownLatch.await(LATCH_TIMEOUT_SECONDS, TimeUnit.SECONDS); if (assertionError != null) @@ -415,7 +415,7 @@ public class PlaybackServiceMediaPlayerTest { } }); PlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback); - Playable p = writeTestPlayable(PLAYABLE_FILE_URL, PLAYABLE_LOCAL_URL); + Playable p = writeTestPlayable(playableFileUrl, PLAYABLE_LOCAL_URL); psmp.playMediaObject(p, false, false, true); boolean res = countDownLatch.await(LATCH_TIMEOUT_SECONDS, TimeUnit.SECONDS); if (assertionError != null) @@ -460,7 +460,7 @@ public class PlaybackServiceMediaPlayerTest { } }); PlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback); - Playable p = writeTestPlayable(PLAYABLE_FILE_URL, PLAYABLE_LOCAL_URL); + Playable p = writeTestPlayable(playableFileUrl, PLAYABLE_LOCAL_URL); psmp.playMediaObject(p, false, true, true); boolean res = countDownLatch.await(LATCH_TIMEOUT_SECONDS, TimeUnit.SECONDS); if (assertionError != null) @@ -523,7 +523,7 @@ public class PlaybackServiceMediaPlayerTest { } }); PlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback); - Playable p = writeTestPlayable(PLAYABLE_FILE_URL, PLAYABLE_LOCAL_URL); + Playable p = writeTestPlayable(playableFileUrl, PLAYABLE_LOCAL_URL); if (initialState == PlayerStatus.PLAYING) { psmp.playMediaObject(p, stream, true, true); } @@ -616,7 +616,7 @@ public class PlaybackServiceMediaPlayerTest { PlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback); if (initialState == PlayerStatus.PREPARED || initialState == PlayerStatus.PLAYING || initialState == PlayerStatus.PAUSED) { boolean startWhenPrepared = (initialState != PlayerStatus.PREPARED); - psmp.playMediaObject(writeTestPlayable(PLAYABLE_FILE_URL, PLAYABLE_LOCAL_URL), false, startWhenPrepared, true); + psmp.playMediaObject(writeTestPlayable(playableFileUrl, PLAYABLE_LOCAL_URL), false, startWhenPrepared, true); } if (initialState == PlayerStatus.PAUSED) { psmp.pause(false, false); @@ -673,7 +673,7 @@ public class PlaybackServiceMediaPlayerTest { } }); PlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback); - Playable p = writeTestPlayable(PLAYABLE_FILE_URL, PLAYABLE_LOCAL_URL); + Playable p = writeTestPlayable(playableFileUrl, PLAYABLE_LOCAL_URL); if (initialState == PlayerStatus.INITIALIZED || initialState == PlayerStatus.PLAYING || initialState == PlayerStatus.PREPARED @@ -747,7 +747,7 @@ public class PlaybackServiceMediaPlayerTest { } }); PlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback); - Playable p = writeTestPlayable(PLAYABLE_FILE_URL, PLAYABLE_LOCAL_URL); + Playable p = writeTestPlayable(playableFileUrl, PLAYABLE_LOCAL_URL); boolean prepareImmediately = initialState != PlayerStatus.INITIALIZED; boolean startImmediately = initialState != PlayerStatus.PREPARED; psmp.playMediaObject(p, false, startImmediately, prepareImmediately); diff --git a/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java b/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java index 66404e2a8..5e3f66f43 100644 --- a/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java +++ b/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java @@ -87,13 +87,13 @@ public class UITestUtils { out.close(); int id = server.serveFile(feedFile); Assert.assertTrue(id != -1); - return String.format("%s/files/%d", HTTPBin.BASE_URL, id); + return String.format("%s/files/%d", server.getBaseUrl(), id); } private String hostFile(File file) { int id = server.serveFile(file); Assert.assertTrue(id != -1); - return String.format("%s/files/%d", HTTPBin.BASE_URL, id); + return String.format("%s/files/%d", server.getBaseUrl(), id); } private File newBitmapFile(String name) throws IOException { diff --git a/app/src/androidTest/java/de/test/antennapod/util/service/download/HTTPBin.java b/app/src/androidTest/java/de/test/antennapod/util/service/download/HTTPBin.java index 49befd775..c588cdbc2 100644 --- a/app/src/androidTest/java/de/test/antennapod/util/service/download/HTTPBin.java +++ b/app/src/androidTest/java/de/test/antennapod/util/service/download/HTTPBin.java @@ -39,9 +39,6 @@ import de.danoeh.antennapod.BuildConfig; */ public class HTTPBin extends NanoHTTPD { private static final String TAG = "HTTPBin"; - public static final int PORT = 8124; - public static final String BASE_URL = "http://127.0.0.1:" + HTTPBin.PORT; - private static final String MIME_HTML = "text/html"; private static final String MIME_PLAIN = "text/plain"; @@ -49,10 +46,14 @@ public class HTTPBin extends NanoHTTPD { private final List servedFiles; public HTTPBin() { - super(PORT); + super(0); // Let system pick a free port this.servedFiles = new ArrayList<>(); } + public String getBaseUrl() { + return "http://127.0.0.1:" + getListeningPort(); + } + /** * Adds the given file to the server. * -- cgit v1.2.3 From a9987aeaa6ca07e628ade135403a8978c95aece2 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Mon, 2 Dec 2019 10:06:16 +0100 Subject: Replaced inheritance with parameterized test --- .../antennapod/playback/PlaybackBuiltinTest.java | 17 ----------------- .../antennapod/playback/PlaybackExoplayerTest.java | 17 ----------------- .../test/antennapod/playback/PlaybackSonicTest.java | 17 ----------------- .../de/test/antennapod/playback/PlaybackTest.java | 20 ++++++++++++++++++-- 4 files changed, 18 insertions(+), 53 deletions(-) delete mode 100644 app/src/androidTest/java/de/test/antennapod/playback/PlaybackBuiltinTest.java delete mode 100644 app/src/androidTest/java/de/test/antennapod/playback/PlaybackExoplayerTest.java delete mode 100644 app/src/androidTest/java/de/test/antennapod/playback/PlaybackSonicTest.java diff --git a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackBuiltinTest.java b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackBuiltinTest.java deleted file mode 100644 index a80ee41d7..000000000 --- a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackBuiltinTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package de.test.antennapod.playback; - -import androidx.test.filters.LargeTest; -import de.danoeh.antennapod.core.preferences.UserPreferences; -import org.junit.Before; - -/** - * Test cases for starting and ending playback from the MainActivity and AudioPlayerActivity. - */ -@LargeTest -public class PlaybackBuiltinTest extends PlaybackTest { - @Before - public void setUp() throws Exception { - super.setUp(); - UserPreferences.enableBuiltin(); - } -} diff --git a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackExoplayerTest.java b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackExoplayerTest.java deleted file mode 100644 index 0cf73f069..000000000 --- a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackExoplayerTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package de.test.antennapod.playback; - -import androidx.test.filters.LargeTest; -import de.danoeh.antennapod.core.preferences.UserPreferences; -import org.junit.Before; - -/** - * Test cases for starting and ending playback from the MainActivity and AudioPlayerActivity. - */ -@LargeTest -public class PlaybackExoplayerTest extends PlaybackTest { - @Before - public void setUp() throws Exception { - super.setUp(); - UserPreferences.enableExoplayer(); - } -} diff --git a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackSonicTest.java b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackSonicTest.java deleted file mode 100644 index a0fb74809..000000000 --- a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackSonicTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package de.test.antennapod.playback; - -import androidx.test.filters.LargeTest; -import de.danoeh.antennapod.core.preferences.UserPreferences; -import org.junit.Before; - -/** - * Test cases for starting and ending playback from the MainActivity and AudioPlayerActivity. - */ -@LargeTest -public class PlaybackSonicTest extends PlaybackTest { - @Before - public void setUp() throws Exception { - super.setUp(); - UserPreferences.enableSonic(); - } -} diff --git a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java index 9732ac215..f04d30a76 100644 --- a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java +++ b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java @@ -4,6 +4,7 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.preference.PreferenceManager; +import androidx.test.filters.LargeTest; import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.rule.ActivityTestRule; import de.danoeh.antennapod.R; @@ -21,7 +22,11 @@ import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import java.util.Arrays; +import java.util.Collection; import java.util.List; import java.util.concurrent.TimeUnit; @@ -45,14 +50,22 @@ import static org.junit.Assert.assertTrue; /** * Test cases for starting and ending playback from the MainActivity and AudioPlayerActivity. */ -public abstract class PlaybackTest { - +@LargeTest +@RunWith(Parameterized.class) +public class PlaybackTest { @Rule public ActivityTestRule activityTestRule = new ActivityTestRule<>(MainActivity.class, false, false); + @Parameterized.Parameter(value = 0) + public String playerToUse; private UITestUtils uiTestUtils; protected Context context; + @Parameterized.Parameters(name = "{0}") + public static Collection initParameters() { + return Arrays.asList(new Object[][] { { "exoplayer" }, { "builtin" }, { "sonic" } }); + } + @Before public void setUp() throws Exception { context = InstrumentationRegistry.getInstrumentation().getTargetContext(); @@ -60,6 +73,9 @@ public abstract class PlaybackTest { EspressoTestUtils.clearDatabase(); EspressoTestUtils.makeNotFirstRun(); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + prefs.edit().putString(UserPreferences.PREF_MEDIA_PLAYER, playerToUse).apply(); + uiTestUtils = new UITestUtils(context); uiTestUtils.setup(); } -- cgit v1.2.3 From a20ef049e1776672a8508eb9e960d730e015c375 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Mon, 2 Dec 2019 10:09:04 +0100 Subject: Fixed test if wifi is disabled --- .../androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java b/app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java index 3a4858e98..a00dc6517 100644 --- a/app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java +++ b/app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java @@ -54,6 +54,7 @@ public class AutoDownloadTest { EspressoTestUtils.clearPreferences(); EspressoTestUtils.clearDatabase(); + UserPreferences.setAllowMobileStreaming(true); } @After -- cgit v1.2.3 From 09dc16c6519bdd40841c445c42b2f40293621b34 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Mon, 2 Dec 2019 10:44:06 +0100 Subject: Fixed asset not being found --- .../service/playback/PlaybackServiceMediaPlayerTest.java | 8 ++++---- .../androidTest/java/de/test/antennapod/ui/SpeedChangeTest.java | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java b/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java index 00fc68598..c17324750 100644 --- a/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java +++ b/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java @@ -2,8 +2,8 @@ package de.test.antennapod.service.playback; import android.content.Context; -import androidx.test.InstrumentationRegistry; import androidx.test.filters.MediumTest; +import androidx.test.platform.app.InstrumentationRegistry; import de.test.antennapod.EspressoTestUtils; import junit.framework.AssertionFailedError; @@ -32,7 +32,7 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; -import static androidx.test.InstrumentationRegistry.getInstrumentation; +import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -66,7 +66,7 @@ public class PlaybackServiceMediaPlayerTest { EspressoTestUtils.makeNotFirstRun(); EspressoTestUtils.clearDatabase(); - final Context context = InstrumentationRegistry.getTargetContext(); + final Context context = getInstrumentation().getTargetContext(); httpServer = new HTTPBin(); httpServer.start(); @@ -81,7 +81,7 @@ public class PlaybackServiceMediaPlayerTest { assertTrue(cacheDir.canWrite()); assertTrue(cacheDir.canRead()); if (!dest.exists()) { - InputStream i = InstrumentationRegistry.getContext().getAssets().open("3sec.mp3"); + InputStream i = getInstrumentation().getTargetContext().getAssets().open("3sec.mp3"); OutputStream o = new FileOutputStream(new File(cacheDir, PLAYABLE_DEST_URL)); IOUtils.copy(i, o); o.flush(); diff --git a/app/src/androidTest/java/de/test/antennapod/ui/SpeedChangeTest.java b/app/src/androidTest/java/de/test/antennapod/ui/SpeedChangeTest.java index d28858f72..84a7a23bb 100644 --- a/app/src/androidTest/java/de/test/antennapod/ui/SpeedChangeTest.java +++ b/app/src/androidTest/java/de/test/antennapod/ui/SpeedChangeTest.java @@ -88,7 +88,7 @@ public class SpeedChangeTest { public void testChangeSpeedPlaying() { onView(isRoot()).perform(waitForView(withId(R.id.butPlay), 1000)); onView(withId(R.id.butPlay)).perform(click()); - Awaitility.await().atMost(1, TimeUnit.SECONDS).until(() + Awaitility.await().atMost(2, TimeUnit.SECONDS).until(() -> activityRule.getActivity().getPlaybackController().getStatus() == PlayerStatus.PLAYING); clickThroughSpeeds(); } @@ -97,10 +97,10 @@ public class SpeedChangeTest { public void testChangeSpeedPaused() { onView(isRoot()).perform(waitForView(withId(R.id.butPlay), 1000)); onView(withId(R.id.butPlay)).perform(click()); - Awaitility.await().atMost(1, TimeUnit.SECONDS).until(() + Awaitility.await().atMost(2, TimeUnit.SECONDS).until(() -> activityRule.getActivity().getPlaybackController().getStatus() == PlayerStatus.PLAYING); onView(withId(R.id.butPlay)).perform(click()); - Awaitility.await().atMost(1, TimeUnit.SECONDS).until(() + Awaitility.await().atMost(2, TimeUnit.SECONDS).until(() -> activityRule.getActivity().getPlaybackController().getStatus() == PlayerStatus.PAUSED); clickThroughSpeeds(); } -- cgit v1.2.3 From ca16dddef1d451a5583dc5e3f2b31679ee4f628b Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Mon, 2 Dec 2019 11:12:51 +0100 Subject: Don't load queue multiple times --- .../java/de/test/antennapod/playback/PlaybackTest.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java index f04d30a76..2133b787c 100644 --- a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java +++ b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java @@ -15,6 +15,7 @@ import de.danoeh.antennapod.core.service.playback.PlaybackService; import de.danoeh.antennapod.core.service.playback.PlayerStatus; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBWriter; +import de.danoeh.antennapod.core.util.LongList; import de.test.antennapod.EspressoTestUtils; import de.test.antennapod.ui.UITestUtils; import org.awaitility.Awaitility; @@ -44,6 +45,7 @@ import static de.test.antennapod.NthMatcher.first; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static org.hamcrest.Matchers.hasItems; import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; @@ -307,13 +309,16 @@ public class PlaybackTest { uiTestUtils.setMediaFileName("30sec.mp3"); uiTestUtils.addLocalFeedData(true); + LongList queue = DBReader.getQueueIDList(); int fiIdx; if (itemIdxNegAllowed >= 0) { fiIdx = itemIdxNegAllowed; } else { // negative index: count from the end, with -1 being the last one, etc. - fiIdx = DBReader.getQueue().size() + itemIdxNegAllowed; + fiIdx = queue.size() + itemIdxNegAllowed; } - final FeedItem feedItem = DBReader.getQueue().get(fiIdx); + final long feedItemId = queue.get(fiIdx); + queue.removeIndex(fiIdx); + assertFalse(queue.contains(feedItemId)); // Verify that episode is in queue only once activityTestRule.launchActivity(new Intent()); playFromQueue(fiIdx); @@ -322,8 +327,8 @@ public class PlaybackTest { // assert item no longer in queue (needs to wait till skip is asynchronously processed) Awaitility.await() - .atMost(3000, MILLISECONDS) - .until(() -> !DBReader.getQueue().contains(feedItem)); - assertTrue(DBReader.getFeedItem(feedItem.getId()).isPlayed()); + .atMost(5000, MILLISECONDS) + .until(() -> !DBReader.getQueueIDList().contains(feedItemId)); + assertTrue(DBReader.getFeedItem(feedItemId).isPlayed()); } } -- cgit v1.2.3 From 44f5cad4e6e8cf46315010e2857b9b3e0f565bef Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Mon, 2 Dec 2019 11:45:10 +0100 Subject: Do not try to click play in off-screen list --- .../java/de/test/antennapod/playback/PlaybackTest.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java index 2133b787c..036eda3aa 100644 --- a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java +++ b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java @@ -15,6 +15,7 @@ import de.danoeh.antennapod.core.service.playback.PlaybackService; import de.danoeh.antennapod.core.service.playback.PlayerStatus; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBWriter; +import de.danoeh.antennapod.core.util.IntentUtils; import de.danoeh.antennapod.core.util.LongList; import de.test.antennapod.EspressoTestUtils; import de.test.antennapod.ui.UITestUtils; @@ -34,6 +35,7 @@ import java.util.concurrent.TimeUnit; import static androidx.test.espresso.Espresso.onView; import static androidx.test.espresso.action.ViewActions.click; import static androidx.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition; +import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; import static androidx.test.espresso.matcher.ViewMatchers.isRoot; import static androidx.test.espresso.matcher.ViewMatchers.withId; import static androidx.test.espresso.matcher.ViewMatchers.withText; @@ -41,8 +43,8 @@ import static de.test.antennapod.EspressoTestUtils.clickChildViewWithId; import static de.test.antennapod.EspressoTestUtils.onDrawerItem; import static de.test.antennapod.EspressoTestUtils.openNavDrawer; import static de.test.antennapod.EspressoTestUtils.waitForView; -import static de.test.antennapod.NthMatcher.first; import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.hasItems; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertFalse; @@ -218,13 +220,11 @@ public class PlaybackTest { } private void skipEpisode() { - Intent skipIntent = new Intent(PlaybackService.ACTION_SKIP_CURRENT_EPISODE); - context.sendBroadcast(skipIntent); + IntentUtils.sendLocalBroadcast(context, PlaybackService.ACTION_SKIP_CURRENT_EPISODE); } protected void pauseEpisode() { - Intent pauseIntent = new Intent(PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE); - context.sendBroadcast(pauseIntent); + IntentUtils.sendLocalBroadcast(context, PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE); } protected void startLocalPlayback() { @@ -234,9 +234,9 @@ public class PlaybackTest { onView(withText(R.string.all_episodes_short_label)).perform(click()); final List episodes = DBReader.getRecentlyPublishedEpisodes(0, 10); - onView(isRoot()).perform(waitForView(withId(R.id.butSecondaryAction), 1000)); + onView(allOf(withId(android.R.id.list), isDisplayed())).perform( + actionOnItemAtPosition(0, clickChildViewWithId(R.id.butSecondaryAction))); - onView(first(withId(R.id.butSecondaryAction))).perform(click()); long mediaId = episodes.get(0).getMedia().getId(); Awaitility.await().atMost(1, TimeUnit.SECONDS).until(() -> { if (uiTestUtils.getCurrentMedia(getActivity()) != null) { -- cgit v1.2.3 From e2aa83f047e8ca762c19290a620fe47d154b74eb Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Mon, 2 Dec 2019 12:00:21 +0100 Subject: Remove queue item without checking taskmanager first --- .../core/service/playback/PlaybackService.java | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java index b43e62519..d53f7d669 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java @@ -985,23 +985,15 @@ public class PlaybackService extends MediaBrowserServiceCompat { } if (item != null) { - if (ended || smartMarkAsPlayed || - (skipped && !UserPreferences.shouldSkipKeepEpisode())) { + if (ended || smartMarkAsPlayed + || (skipped && !UserPreferences.shouldSkipKeepEpisode())) { // only mark the item as played if we're not keeping it anyways DBWriter.markItemPlayed(item, FeedItem.PLAYED, ended); - try { - final List queue = taskManager.getQueue(); - if (QueueAccess.ItemListAccess(queue).contains(item.getId())) { - // don't know if it actually matters to not autodownload when smart mark as played is triggered - DBWriter.removeQueueItem(PlaybackService.this, ended, item); - } - } catch (InterruptedException e) { - e.printStackTrace(); - // isInQueue remains false - } + // don't know if it actually matters to not autodownload when smart mark as played is triggered + DBWriter.removeQueueItem(PlaybackService.this, ended, item); // Delete episode if enabled - if (item.getFeed().getPreferences().getCurrentAutoDelete() && - (!item.isTagged(FeedItem.TAG_FAVORITE) || !UserPreferences.shouldFavoriteKeepEpisode())) { + if (item.getFeed().getPreferences().getCurrentAutoDelete() + && (!item.isTagged(FeedItem.TAG_FAVORITE) || !UserPreferences.shouldFavoriteKeepEpisode())) { DBWriter.deleteFeedMediaOfItem(PlaybackService.this, media.getId()); Log.d(TAG, "Episode Deleted"); } -- cgit v1.2.3 From 44aa0a3239ee5fba3dc17f6f7e91fa5f24b737fc Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Mon, 2 Dec 2019 13:02:09 +0100 Subject: Try to kill playback service but do not fail if it does not stop Android has no reliable way to stop a service instantly. Calling stopSelf marks allows the system to destroy the service but the actual call to onDestroy takes until the next GC of the system, which we can not influence. Try to wait for the service at least a bit. --- .../java/de/test/antennapod/EspressoTestUtils.java | 20 ++++++++++++++++++++ .../de/test/antennapod/playback/PlaybackTest.java | 7 +++---- .../de/test/antennapod/storage/AutoDownloadTest.java | 4 +--- .../java/de/test/antennapod/ui/SpeedChangeTest.java | 4 +--- 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/app/src/androidTest/java/de/test/antennapod/EspressoTestUtils.java b/app/src/androidTest/java/de/test/antennapod/EspressoTestUtils.java index d4d589859..31543a94a 100644 --- a/app/src/androidTest/java/de/test/antennapod/EspressoTestUtils.java +++ b/app/src/androidTest/java/de/test/antennapod/EspressoTestUtils.java @@ -1,6 +1,7 @@ package de.test.antennapod; import android.content.Context; +import android.content.Intent; import androidx.annotation.IdRes; import androidx.annotation.StringRes; import androidx.test.InstrumentationRegistry; @@ -15,11 +16,15 @@ import androidx.test.espresso.util.TreeIterables; import android.view.View; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; +import de.danoeh.antennapod.core.service.playback.PlaybackService; import de.danoeh.antennapod.core.storage.PodDBAdapter; import de.danoeh.antennapod.dialog.RatingDialog; +import org.awaitility.Awaitility; +import org.awaitility.core.ConditionTimeoutException; import org.hamcrest.Matcher; import java.io.File; +import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import static androidx.test.espresso.Espresso.onView; @@ -156,4 +161,19 @@ public class EspressoTestUtils { public static ViewInteraction onDrawerItem(Matcher viewMatcher) { return onView(allOf(viewMatcher, withId(R.id.txtvTitle))); } + + public static void tryKillPlaybackService() { + Context context = InstrumentationRegistry.getTargetContext(); + context.stopService(new Intent(context, PlaybackService.class)); + try { + // Android has no reliable way to stop a service instantly. + // Calling stopSelf marks allows the system to destroy the service but the actual call + // to onDestroy takes until the next GC of the system, which we can not influence. + // Try to wait for the service at least a bit. + Awaitility.await().atMost(10, TimeUnit.SECONDS).until(() -> !PlaybackService.isRunning); + } catch (ConditionTimeoutException e) { + e.printStackTrace(); + } + androidx.test.platform.app.InstrumentationRegistry.getInstrumentation().waitForIdleSync(); + } } diff --git a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java index 036eda3aa..1a2a7e29e 100644 --- a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java +++ b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java @@ -4,6 +4,7 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.preference.PreferenceManager; +import android.view.KeyEvent; import androidx.test.filters.LargeTest; import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.rule.ActivityTestRule; @@ -11,6 +12,7 @@ import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.preferences.UserPreferences; +import de.danoeh.antennapod.core.receiver.MediaButtonReceiver; import de.danoeh.antennapod.core.service.playback.PlaybackService; import de.danoeh.antennapod.core.service.playback.PlayerStatus; import de.danoeh.antennapod.core.storage.DBReader; @@ -87,10 +89,7 @@ public class PlaybackTest { @After public void tearDown() throws Exception { activityTestRule.finishActivity(); - Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); - context.stopService(new Intent(context, PlaybackService.class)); - Awaitility.await().atMost(5, TimeUnit.SECONDS).until(() -> !PlaybackService.isRunning); - InstrumentationRegistry.getInstrumentation().waitForIdleSync(); + EspressoTestUtils.tryKillPlaybackService(); uiTestUtils.tearDown(); } diff --git a/app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java b/app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java index a00dc6517..b89f1b9bc 100644 --- a/app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java +++ b/app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java @@ -60,9 +60,7 @@ public class AutoDownloadTest { @After public void tearDown() throws Exception { ClientConfig.dbTasksCallbacks = dbTasksCallbacksOrig; - context.stopService(new Intent(context, PlaybackService.class)); - Awaitility.await().atMost(5, TimeUnit.SECONDS).until(() -> !PlaybackService.isRunning); - InstrumentationRegistry.getInstrumentation().waitForIdleSync(); + EspressoTestUtils.tryKillPlaybackService(); stubFeedsServer.tearDown(); } diff --git a/app/src/androidTest/java/de/test/antennapod/ui/SpeedChangeTest.java b/app/src/androidTest/java/de/test/antennapod/ui/SpeedChangeTest.java index 84a7a23bb..ff797b9bc 100644 --- a/app/src/androidTest/java/de/test/antennapod/ui/SpeedChangeTest.java +++ b/app/src/androidTest/java/de/test/antennapod/ui/SpeedChangeTest.java @@ -68,9 +68,7 @@ public class SpeedChangeTest { UserPreferences.setPlaybackSpeedArray(new String[] {"1.00", "2.00", "3.00"}); availableSpeeds = UserPreferences.getPlaybackSpeedArray(); - context.sendBroadcast(new Intent(PlaybackService.ACTION_SHUTDOWN_PLAYBACK_SERVICE)); - Awaitility.await().until(() -> !PlaybackService.isRunning); - + EspressoTestUtils.tryKillPlaybackService(); activityRule.launchActivity(new Intent()); } -- cgit v1.2.3 From 51442cb047ef47c0ddaf922ffb559804e4100fa8 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Mon, 2 Dec 2019 13:29:06 +0100 Subject: Making sure to not click the wrong list We might have multiple lists with the same ID in the hierarchy --- .../java/de/test/antennapod/playback/PlaybackTest.java | 13 +++++++++---- .../antennapod/core/service/download/DownloadService.java | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java index 1a2a7e29e..3d3e50ede 100644 --- a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java +++ b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java @@ -5,6 +5,7 @@ import android.content.Intent; import android.content.SharedPreferences; import android.preference.PreferenceManager; import android.view.KeyEvent; +import android.view.View; import androidx.test.filters.LargeTest; import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.rule.ActivityTestRule; @@ -22,6 +23,7 @@ import de.danoeh.antennapod.core.util.LongList; import de.test.antennapod.EspressoTestUtils; import de.test.antennapod.ui.UITestUtils; import org.awaitility.Awaitility; +import org.hamcrest.Matcher; import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -37,6 +39,7 @@ import java.util.concurrent.TimeUnit; import static androidx.test.espresso.Espresso.onView; import static androidx.test.espresso.action.ViewActions.click; import static androidx.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition; +import static androidx.test.espresso.matcher.ViewMatchers.hasMinimumChildCount; import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; import static androidx.test.espresso.matcher.ViewMatchers.isRoot; import static androidx.test.espresso.matcher.ViewMatchers.withId; @@ -233,8 +236,9 @@ public class PlaybackTest { onView(withText(R.string.all_episodes_short_label)).perform(click()); final List episodes = DBReader.getRecentlyPublishedEpisodes(0, 10); - onView(allOf(withId(android.R.id.list), isDisplayed())).perform( - actionOnItemAtPosition(0, clickChildViewWithId(R.id.butSecondaryAction))); + Matcher allEpisodesMatcher = allOf(withId(android.R.id.list), isDisplayed(), hasMinimumChildCount(2)); + onView(isRoot()).perform(waitForView(allEpisodesMatcher, 1000)); + onView(allEpisodesMatcher).perform(actionOnItemAtPosition(0, clickChildViewWithId(R.id.butSecondaryAction))); long mediaId = episodes.get(0).getMedia().getId(); Awaitility.await().atMost(1, TimeUnit.SECONDS).until(() -> { @@ -253,8 +257,9 @@ public class PlaybackTest { protected void playFromQueue(int itemIdx) { final List queue = DBReader.getQueue(); - onView(withId(R.id.recyclerView)).perform( - actionOnItemAtPosition(itemIdx, clickChildViewWithId(R.id.butSecondaryAction))); + Matcher queueMatcher = allOf(withId(R.id.recyclerView), isDisplayed(), hasMinimumChildCount(2)); + onView(isRoot()).perform(waitForView(queueMatcher, 1000)); + onView(queueMatcher).perform(actionOnItemAtPosition(itemIdx, clickChildViewWithId(R.id.butSecondaryAction))); onView(isRoot()).perform(waitForView(withId(R.id.butPlay), 1000)); long mediaId = queue.get(itemIdx).getMedia().getId(); diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java index 04c1190a7..68aab3623 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java @@ -219,7 +219,7 @@ public class DownloadService extends Service { downloadCompletionThread.interrupt(); try { - downloadCompletionThread.join(); + downloadCompletionThread.join(1000); } catch (InterruptedException e) { e.printStackTrace(); } -- cgit v1.2.3 From 376600d5b4c41f6167d5d4161a7ef8e3a132d715 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Mon, 2 Dec 2019 15:49:57 +0100 Subject: Read current media from preferences instead of activity->fragment->controller --- .../java/de/test/antennapod/EspressoTestUtils.java | 16 +++++ .../de/test/antennapod/playback/PlaybackTest.java | 74 ++++++---------------- .../service/download/DownloadServiceTest.java | 68 ++++++++++---------- .../de/test/antennapod/ui/MainActivityTest.java | 4 +- .../de/test/antennapod/ui/SpeedChangeTest.java | 6 +- .../java/de/test/antennapod/ui/UITestUtils.java | 9 ++- 6 files changed, 83 insertions(+), 94 deletions(-) diff --git a/app/src/androidTest/java/de/test/antennapod/EspressoTestUtils.java b/app/src/androidTest/java/de/test/antennapod/EspressoTestUtils.java index 31543a94a..bbd8a705c 100644 --- a/app/src/androidTest/java/de/test/antennapod/EspressoTestUtils.java +++ b/app/src/androidTest/java/de/test/antennapod/EspressoTestUtils.java @@ -16,6 +16,7 @@ import androidx.test.espresso.util.TreeIterables; import android.view.View; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; +import de.danoeh.antennapod.core.service.download.DownloadService; import de.danoeh.antennapod.core.service.playback.PlaybackService; import de.danoeh.antennapod.core.storage.PodDBAdapter; import de.danoeh.antennapod.dialog.RatingDialog; @@ -176,4 +177,19 @@ public class EspressoTestUtils { } androidx.test.platform.app.InstrumentationRegistry.getInstrumentation().waitForIdleSync(); } + + public static void tryKillDownloadService() { + Context context = InstrumentationRegistry.getTargetContext(); + context.stopService(new Intent(context, DownloadService.class)); + try { + // Android has no reliable way to stop a service instantly. + // Calling stopSelf marks allows the system to destroy the service but the actual call + // to onDestroy takes until the next GC of the system, which we can not influence. + // Try to wait for the service at least a bit. + Awaitility.await().atMost(10, TimeUnit.SECONDS).until(() -> !DownloadService.isRunning); + } catch (ConditionTimeoutException e) { + e.printStackTrace(); + } + androidx.test.platform.app.InstrumentationRegistry.getInstrumentation().waitForIdleSync(); + } } diff --git a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java index 3d3e50ede..9518c761f 100644 --- a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java +++ b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java @@ -12,8 +12,8 @@ import androidx.test.rule.ActivityTestRule; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.core.feed.FeedItem; +import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.preferences.UserPreferences; -import de.danoeh.antennapod.core.receiver.MediaButtonReceiver; import de.danoeh.antennapod.core.service.playback.PlaybackService; import de.danoeh.antennapod.core.service.playback.PlayerStatus; import de.danoeh.antennapod.core.storage.DBReader; @@ -117,22 +117,10 @@ public class PlaybackTest { final FeedItem second = queue.get(1); playFromQueue(0); - Awaitility.await().atMost(2, TimeUnit.SECONDS).until(() -> { - if (uiTestUtils.getCurrentMedia(getActivity()) != null) { - return uiTestUtils.getCurrentMedia(getActivity()).getId() - == first.getMedia().getId(); - } else { - return false; - } - }); - Awaitility.await().atMost(5, TimeUnit.SECONDS).until(() -> { - if (uiTestUtils.getCurrentMedia(getActivity()) != null) { - return uiTestUtils.getCurrentMedia(getActivity()).getId() - == second.getMedia().getId(); - } else { - return false; - } - }); + Awaitility.await().atMost(2, TimeUnit.SECONDS).until( + () -> first.getMedia().equals(uiTestUtils.getCurrentMedia())); + Awaitility.await().atMost(6, TimeUnit.SECONDS).until( + () -> second.getMedia().equals(uiTestUtils.getCurrentMedia())); } @@ -240,14 +228,9 @@ public class PlaybackTest { onView(isRoot()).perform(waitForView(allEpisodesMatcher, 1000)); onView(allEpisodesMatcher).perform(actionOnItemAtPosition(0, clickChildViewWithId(R.id.butSecondaryAction))); - long mediaId = episodes.get(0).getMedia().getId(); - Awaitility.await().atMost(1, TimeUnit.SECONDS).until(() -> { - if (uiTestUtils.getCurrentMedia(getActivity()) != null) { - return uiTestUtils.getCurrentMedia(getActivity()).getId() == mediaId; - } else { - return false; - } - }); + FeedMedia media = episodes.get(0).getMedia(); + Awaitility.await().atMost(1, TimeUnit.SECONDS).until( + () -> media.equals(uiTestUtils.getCurrentMedia())); } /** @@ -261,15 +244,10 @@ public class PlaybackTest { onView(isRoot()).perform(waitForView(queueMatcher, 1000)); onView(queueMatcher).perform(actionOnItemAtPosition(itemIdx, clickChildViewWithId(R.id.butSecondaryAction))); - onView(isRoot()).perform(waitForView(withId(R.id.butPlay), 1000)); - long mediaId = queue.get(itemIdx).getMedia().getId(); - Awaitility.await().atMost(1, TimeUnit.SECONDS).until(() -> { - if (uiTestUtils.getCurrentMedia(getActivity()) != null) { - return uiTestUtils.getCurrentMedia(getActivity()).getId() == mediaId; - } else { - return false; - } - }); + FeedMedia media = queue.get(itemIdx).getMedia(); + Awaitility.await().atMost(1, TimeUnit.SECONDS).until( + () -> media.equals(uiTestUtils.getCurrentMedia())); + } /** @@ -283,27 +261,17 @@ public class PlaybackTest { final List episodes = DBReader.getRecentlyPublishedEpisodes(0, 10); startLocalPlayback(); - long mediaId = episodes.get(0).getMedia().getId(); - Awaitility.await().atMost(1, TimeUnit.SECONDS).until(() -> { - if (uiTestUtils.getCurrentMedia(getActivity()) != null) { - return uiTestUtils.getCurrentMedia(getActivity()).getId() == mediaId; - } else { - return false; - } - }); - - Awaitility.await().atMost(5, TimeUnit.SECONDS).until(() -> - uiTestUtils.getCurrentMedia(getActivity()) == null - || uiTestUtils.getCurrentMedia(getActivity()).getId() != mediaId); + FeedMedia media = episodes.get(0).getMedia(); + Awaitility.await().atMost(1, TimeUnit.SECONDS).until( + () -> media.equals(uiTestUtils.getCurrentMedia())); + + Awaitility.await().atMost(5, TimeUnit.SECONDS).until( + () -> !media.equals(uiTestUtils.getCurrentMedia())); startLocalPlayback(); - Awaitility.await().atMost(1, TimeUnit.SECONDS).until(() -> { - if (uiTestUtils.getCurrentMedia(getActivity()) != null) { - return uiTestUtils.getCurrentMedia(getActivity()).getId() == mediaId; - } else { - return false; - } - }); + + Awaitility.await().atMost(1, TimeUnit.SECONDS).until( + () -> media.equals(uiTestUtils.getCurrentMedia())); } protected void doTestSmartMarkAsPlayed_Skip_ForEpisode(int itemIdxNegAllowed) throws Exception { diff --git a/app/src/androidTest/java/de/test/antennapod/service/download/DownloadServiceTest.java b/app/src/androidTest/java/de/test/antennapod/service/download/DownloadServiceTest.java index 6b020efcb..1ca4de1ad 100644 --- a/app/src/androidTest/java/de/test/antennapod/service/download/DownloadServiceTest.java +++ b/app/src/androidTest/java/de/test/antennapod/service/download/DownloadServiceTest.java @@ -1,5 +1,7 @@ package de.test.antennapod.service.download; +import android.content.Context; +import android.content.Intent; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.test.InstrumentationRegistry; @@ -80,6 +82,10 @@ public class DownloadServiceTest { @After public void tearDown() throws Exception { DownloadService.setDownloaderFactory(origFactory); + Context context = InstrumentationRegistry.getTargetContext(); + DownloadRequester.getInstance().cancelAllDownloads(context); + context.stopService(new Intent(context, DownloadService.class)); + EspressoTestUtils.tryKillDownloadService(); } @Test @@ -139,8 +145,9 @@ public class DownloadServiceTest { } private void doTestCancelDownload_UndoEnqueue(boolean itemAlreadyInQueue) throws Exception { + Context context = InstrumentationRegistry.getTargetContext(); // let download takes longer to ensure the test can cancel the download in time - DownloadService.setDownloaderFactory(new StubDownloaderFactory(150, downloadStatus -> { + DownloadService.setDownloaderFactory(new StubDownloaderFactory(10000, downloadStatus -> { downloadStatus.setSuccessful(); })); UserPreferences.setEnqueueDownloadedEpisodes(true); @@ -149,45 +156,38 @@ public class DownloadServiceTest { final long item1Id = testMedia11.getItem().getId(); if (itemAlreadyInQueue) { // simulate item already in queue condition - DBWriter.addQueueItem(InstrumentationRegistry.getTargetContext(), false, item1Id).get(); + DBWriter.addQueueItem(context, false, item1Id).get(); assertTrue(DBReader.getQueueIDList().contains(item1Id)); } else { assertFalse(DBReader.getQueueIDList().contains(item1Id)); } withFeedItemEventListener(feedItemEventListener -> { - try { - DownloadRequester.getInstance().downloadMedia(false, InstrumentationRegistry.getTargetContext(), - testMedia11.getItem()); - if (itemAlreadyInQueue) { - Awaitility.await("download service receives the request - " - + "no event is expected before cancel is issued") - .atLeast(100, TimeUnit.MILLISECONDS) - .until(() -> true); - } else { - Awaitility.await("item enqueue event") - .atMost(1000, TimeUnit.MILLISECONDS) - .until(() -> feedItemEventListener.getEvents().size() >= 1); - } - DownloadRequester.getInstance().cancelDownload(InstrumentationRegistry.getTargetContext(), - testMedia11); - final int totalNumEventsExpected = itemAlreadyInQueue ? 1 : 3; - Awaitility.await("item dequeue event + download termination event") - .atMost(1000, TimeUnit.MILLISECONDS) - .until(() -> feedItemEventListener.getEvents().size() >= totalNumEventsExpected); - assertFalse("The download should have been canceled", - DBReader.getFeedMedia(testMedia11.getId()).isDownloaded()); - if (itemAlreadyInQueue) { - assertTrue("The FeedItem should still be in the queue after the download is cancelled." - + " It's there before download.", - DBReader.getQueueIDList().contains(item1Id)); - } else { - assertFalse("The FeedItem should not be in the queue after the download is cancelled.", - DBReader.getQueueIDList().contains(item1Id)); - } - } catch (ConditionTimeoutException cte) { - fail("The expected FeedItemEvent (for media download complete) has not been posted. " - + cte.getMessage()); + DownloadRequester.getInstance().downloadMedia(false, context, testMedia11.getItem()); + if (itemAlreadyInQueue) { + Awaitility.await("download service receives the request - " + + "no event is expected before cancel is issued") + .atLeast(100, TimeUnit.MILLISECONDS) + .until(() -> true); + } else { + Awaitility.await("item enqueue event") + .atMost(2000, TimeUnit.MILLISECONDS) + .until(() -> feedItemEventListener.getEvents().size() >= 1); + } + DownloadRequester.getInstance().cancelDownload(context, testMedia11); + final int totalNumEventsExpected = itemAlreadyInQueue ? 1 : 3; + Awaitility.await("item dequeue event + download termination event") + .atMost(1000, TimeUnit.MILLISECONDS) + .until(() -> feedItemEventListener.getEvents().size() >= totalNumEventsExpected); + assertFalse("The download should have been canceled", + DBReader.getFeedMedia(testMedia11.getId()).isDownloaded()); + if (itemAlreadyInQueue) { + assertTrue("The FeedItem should still be in the queue after the download is cancelled." + + " It's there before download.", + DBReader.getQueueIDList().contains(item1Id)); + } else { + assertFalse("The FeedItem should not be in the queue after the download is cancelled.", + DBReader.getQueueIDList().contains(item1Id)); } }); } diff --git a/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java b/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java index bdcad215d..0784cb078 100644 --- a/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java +++ b/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java @@ -29,10 +29,12 @@ import static androidx.test.espresso.contrib.ActivityResultMatchers.hasResultCod import static androidx.test.espresso.intent.Intents.intended; import static androidx.test.espresso.intent.Intents.times; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent; +import static androidx.test.espresso.matcher.ViewMatchers.isRoot; import static androidx.test.espresso.matcher.ViewMatchers.withId; import static androidx.test.espresso.matcher.ViewMatchers.withText; import static de.test.antennapod.EspressoTestUtils.clickPreference; import static de.test.antennapod.EspressoTestUtils.openNavDrawer; +import static de.test.antennapod.EspressoTestUtils.waitForView; import static junit.framework.TestCase.assertTrue; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; @@ -79,7 +81,7 @@ public class MainActivityTest { onView(withText(R.string.confirm_label)).perform(scrollTo(), click()); Espresso.closeSoftKeyboard(); onView(withText(R.string.subscribe_label)).perform(click()); - intended(hasComponent(MainActivity.class.getName()), times(2)); + onView(isRoot()).perform(waitForView(withId(R.id.butShowSettings), 5000)); } private String getActionbarTitle() { diff --git a/app/src/androidTest/java/de/test/antennapod/ui/SpeedChangeTest.java b/app/src/androidTest/java/de/test/antennapod/ui/SpeedChangeTest.java index ff797b9bc..a536e572e 100644 --- a/app/src/androidTest/java/de/test/antennapod/ui/SpeedChangeTest.java +++ b/app/src/androidTest/java/de/test/antennapod/ui/SpeedChangeTest.java @@ -86,7 +86,7 @@ public class SpeedChangeTest { public void testChangeSpeedPlaying() { onView(isRoot()).perform(waitForView(withId(R.id.butPlay), 1000)); onView(withId(R.id.butPlay)).perform(click()); - Awaitility.await().atMost(2, TimeUnit.SECONDS).until(() + Awaitility.await().atMost(5, TimeUnit.SECONDS).until(() -> activityRule.getActivity().getPlaybackController().getStatus() == PlayerStatus.PLAYING); clickThroughSpeeds(); } @@ -95,10 +95,10 @@ public class SpeedChangeTest { public void testChangeSpeedPaused() { onView(isRoot()).perform(waitForView(withId(R.id.butPlay), 1000)); onView(withId(R.id.butPlay)).perform(click()); - Awaitility.await().atMost(2, TimeUnit.SECONDS).until(() + Awaitility.await().atMost(5, TimeUnit.SECONDS).until(() -> activityRule.getActivity().getPlaybackController().getStatus() == PlayerStatus.PLAYING); onView(withId(R.id.butPlay)).perform(click()); - Awaitility.await().atMost(2, TimeUnit.SECONDS).until(() + Awaitility.await().atMost(5, TimeUnit.SECONDS).until(() -> activityRule.getActivity().getPlaybackController().getStatus() == PlayerStatus.PAUSED); clickThroughSpeeds(); } diff --git a/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java b/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java index 5e3f66f43..e3796b26a 100644 --- a/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java +++ b/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java @@ -5,6 +5,7 @@ import android.graphics.Bitmap; import android.util.Log; import de.danoeh.antennapod.core.event.FeedListUpdateEvent; +import de.danoeh.antennapod.core.util.playback.Playable; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; @@ -204,12 +205,14 @@ public class UITestUtils { } public PlaybackController getPlaybackController(MainActivity mainActivity) { - ExternalPlayerFragment fragment = (ExternalPlayerFragment)mainActivity.getSupportFragmentManager().findFragmentByTag(ExternalPlayerFragment.TAG); + ExternalPlayerFragment fragment = (ExternalPlayerFragment) mainActivity.getSupportFragmentManager() + .findFragmentByTag(ExternalPlayerFragment.TAG); return fragment.getPlaybackControllerTestingOnly(); } - public FeedMedia getCurrentMedia(MainActivity mainActivity) { - return (FeedMedia)getPlaybackController(mainActivity).getMedia(); + public FeedMedia getCurrentMedia() { + Playable playable = Playable.PlayableUtils.createInstanceFromPreferences(context); + return (FeedMedia) playable; } public void setMediaFileName(String filename) { -- cgit v1.2.3 From d41d58063ea1ba45411e287df1324ef88721289f Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Wed, 11 Dec 2019 21:57:52 +0100 Subject: Ignore PlaybackTest on CI --- .github/workflows/android-emulator.yml | 2 +- .../androidTest/java/de/test/antennapod/IgnoreOnCi.java | 15 +++++++++++++++ .../java/de/test/antennapod/playback/PlaybackTest.java | 2 ++ 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 app/src/androidTest/java/de/test/antennapod/IgnoreOnCi.java diff --git a/.github/workflows/android-emulator.yml b/.github/workflows/android-emulator.yml index 963b084f7..332790acd 100644 --- a/.github/workflows/android-emulator.yml +++ b/.github/workflows/android-emulator.yml @@ -21,7 +21,7 @@ jobs: api-level: 28 headless: true disable-animations: true - script: ./gradlew connectedPlayDebugAndroidTest + script: ./gradlew connectedPlayDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.notAnnotation=de.test.antennapod.IgnoreOnCi - uses: actions/upload-artifact@v1 if: failure() with: diff --git a/app/src/androidTest/java/de/test/antennapod/IgnoreOnCi.java b/app/src/androidTest/java/de/test/antennapod/IgnoreOnCi.java new file mode 100644 index 000000000..41ab15b9b --- /dev/null +++ b/app/src/androidTest/java/de/test/antennapod/IgnoreOnCi.java @@ -0,0 +1,15 @@ +package de.test.antennapod; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Tests with this annotation are ignored on CI. This could be reasonable + * if the performance of the CI server is not enough to provide a reliable result. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface IgnoreOnCi { +} diff --git a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java index 9518c761f..cc380813e 100644 --- a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java +++ b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java @@ -21,6 +21,7 @@ import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.util.IntentUtils; import de.danoeh.antennapod.core.util.LongList; import de.test.antennapod.EspressoTestUtils; +import de.test.antennapod.IgnoreOnCi; import de.test.antennapod.ui.UITestUtils; import org.awaitility.Awaitility; import org.hamcrest.Matcher; @@ -60,6 +61,7 @@ import static org.junit.Assert.assertTrue; * Test cases for starting and ending playback from the MainActivity and AudioPlayerActivity. */ @LargeTest +@IgnoreOnCi @RunWith(Parameterized.class) public class PlaybackTest { @Rule -- cgit v1.2.3 From 1a8c83548be67764b2118d79f248193c9ad97363 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Thu, 19 Dec 2019 23:44:31 +0100 Subject: Ignore more playback related tests on CI --- app/src/androidTest/java/de/test/antennapod/ui/SpeedChangeTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/androidTest/java/de/test/antennapod/ui/SpeedChangeTest.java b/app/src/androidTest/java/de/test/antennapod/ui/SpeedChangeTest.java index a536e572e..df32ed3c0 100644 --- a/app/src/androidTest/java/de/test/antennapod/ui/SpeedChangeTest.java +++ b/app/src/androidTest/java/de/test/antennapod/ui/SpeedChangeTest.java @@ -11,11 +11,11 @@ import de.danoeh.antennapod.activity.AudioplayerActivity; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.preferences.PlaybackPreferences; import de.danoeh.antennapod.core.preferences.UserPreferences; -import de.danoeh.antennapod.core.service.playback.PlaybackService; import de.danoeh.antennapod.core.service.playback.PlayerStatus; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.fragment.QueueFragment; import de.test.antennapod.EspressoTestUtils; +import de.test.antennapod.IgnoreOnCi; import org.awaitility.Awaitility; import org.junit.After; import org.junit.Before; @@ -39,6 +39,7 @@ import static de.test.antennapod.EspressoTestUtils.waitForView; * User interface tests for changing the playback speed. */ @RunWith(AndroidJUnit4.class) +@IgnoreOnCi public class SpeedChangeTest { @Rule -- cgit v1.2.3 From 6dc361c5424a9b5b3f516cd2aa531b88011a3413 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Fri, 20 Dec 2019 00:08:53 +0100 Subject: Only run emulator tests on pull requests --- .github/workflows/android-emulator.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/android-emulator.yml b/.github/workflows/android-emulator.yml index 332790acd..d42b4504e 100644 --- a/.github/workflows/android-emulator.yml +++ b/.github/workflows/android-emulator.yml @@ -1,12 +1,12 @@ name: Android Emulator test -on: [push] +on: + pull_request: + types: [opened, synchronize, reopened] jobs: build: - runs-on: macOS-latest - steps: - uses: actions/checkout@v1 - name: set up JDK 1.8 -- cgit v1.2.3