diff options
author | H. Lehmann <ByteHamster@users.noreply.github.com> | 2019-12-20 00:12:51 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-12-20 00:12:51 +0100 |
commit | 707fcdbc7fc874b99cc08e14906310c718b5e8a7 (patch) | |
tree | 6de1485cb2494299b39e70488e68c658ee8fb442 /app/src | |
parent | 19890afc663d067f70e0286eeaa73cb8cb7acbad (diff) | |
parent | 6dc361c5424a9b5b3f516cd2aa531b88011a3413 (diff) | |
download | AntennaPod-707fcdbc7fc874b99cc08e14906310c718b5e8a7.zip |
Merge pull request #3654 from ByteHamster/emulator-test
Run integration tests on CI
Diffstat (limited to 'app/src')
16 files changed, 268 insertions, 259 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..bbd8a705c 100644 --- a/app/src/androidTest/java/de/test/antennapod/EspressoTestUtils.java +++ b/app/src/androidTest/java/de/test/antennapod/EspressoTestUtils.java @@ -1,6 +1,8 @@ package de.test.antennapod; import android.content.Context; +import android.content.Intent; +import androidx.annotation.IdRes; import androidx.annotation.StringRes; import androidx.test.InstrumentationRegistry; import androidx.test.espresso.PerformException; @@ -14,11 +16,16 @@ 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; +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; @@ -77,6 +84,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<View> 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 */ public static void clearPreferences() { @@ -127,12 +159,37 @@ 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<View> 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(); + } + + 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/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/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 <T> Matcher<T> second(final Matcher<T> matcher) { - return nth(matcher, 2); - } - public static <T> Matcher<T> nth(final Matcher<T> matcher, final int index) { return new BaseMatcher<T>() { 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/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 be2fc432c..cc380813e 100644 --- a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java +++ b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java @@ -4,55 +4,79 @@ import android.content.Context; 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; 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.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.IgnoreOnCi; 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; 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; 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; 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.allOf; import static org.hamcrest.Matchers.hasItems; import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; /** * Test cases for starting and ending playback from the MainActivity and AudioPlayerActivity. */ -public abstract class PlaybackTest { - +@LargeTest +@IgnoreOnCi +@RunWith(Parameterized.class) +public class PlaybackTest { @Rule public ActivityTestRule<MainActivity> 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<Object[]> initParameters() { + return Arrays.asList(new Object[][] { { "exoplayer" }, { "builtin" }, { "sonic" } }); + } + @Before public void setUp() throws Exception { context = InstrumentationRegistry.getInstrumentation().getTargetContext(); @@ -60,6 +84,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(); } @@ -67,10 +94,8 @@ public abstract class PlaybackTest { @After public void tearDown() throws Exception { activityTestRule.finishActivity(); + EspressoTestUtils.tryKillPlaybackService(); uiTestUtils.tearDown(); - // shut down playback service - context.sendBroadcast(new Intent(PlaybackService.ACTION_SHUTDOWN_PLAYBACK_SERVICE)); - Awaitility.await().until(() -> !PlaybackService.isRunning); } @Test @@ -78,23 +103,9 @@ public abstract class PlaybackTest { setContinuousPlaybackPreference(false); uiTestUtils.addLocalFeedData(true); activityTestRule.launchActivity(new Intent()); - List<FeedItem> 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 @@ -108,22 +119,10 @@ public abstract 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())); } @@ -213,33 +212,27 @@ public abstract 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() { 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<FeedItem> episodes = DBReader.getRecentlyPublishedEpisodes(0, 10); - onView(isRoot()).perform(waitForView(withId(R.id.butSecondaryAction), 1000)); - - 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) { - return uiTestUtils.getCurrentMedia(getActivity()).getId() == mediaId; - } else { - return false; - } - }); + Matcher<View> 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))); + + FeedMedia media = episodes.get(0).getMedia(); + Awaitility.await().atMost(1, TimeUnit.SECONDS).until( + () -> media.equals(uiTestUtils.getCurrentMedia())); } /** @@ -249,16 +242,14 @@ public abstract class PlaybackTest { protected void playFromQueue(int itemIdx) { final List<FeedItem> queue = DBReader.getQueue(); - onView(nth(withId(R.id.butSecondaryAction), itemIdx + 1)).perform(click()); - 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; - } - }); + Matcher<View> queueMatcher = allOf(withId(R.id.recyclerView), isDisplayed(), hasMinimumChildCount(2)); + onView(isRoot()).perform(waitForView(queueMatcher, 1000)); + onView(queueMatcher).perform(actionOnItemAtPosition(itemIdx, clickChildViewWithId(R.id.butSecondaryAction))); + + FeedMedia media = queue.get(itemIdx).getMedia(); + Awaitility.await().atMost(1, TimeUnit.SECONDS).until( + () -> media.equals(uiTestUtils.getCurrentMedia())); + } /** @@ -272,42 +263,36 @@ public abstract class PlaybackTest { final List<FeedItem> 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 { 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); + 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); @@ -316,8 +301,8 @@ public abstract class PlaybackTest { // assert item no longer in queue (needs to wait till skip is asynchronously processed) Awaitility.await() - .atMost(1000, 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()); } } 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..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,10 +1,13 @@ 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; 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 +56,8 @@ public class DownloadServiceTest { @Before public void setUp() throws Exception { + EspressoTestUtils.clearDatabase(); + EspressoTestUtils.clearPreferences(); origFactory = DownloadService.getDownloaderFactory(); testFeed = setUpTestFeeds(); testMedia11 = testFeed.getItemAtIndex(0).getMedia(); @@ -77,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 @@ -136,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); @@ -146,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/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..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; @@ -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 @@ -67,10 +66,11 @@ public class PlaybackServiceMediaPlayerTest { EspressoTestUtils.makeNotFirstRun(); EspressoTestUtils.clearDatabase(); - final Context context = InstrumentationRegistry.getTargetContext(); + final Context context = getInstrumentation().getTargetContext(); httpServer = new HTTPBin(); httpServer.start(); + playableFileUrl = httpServer.getBaseUrl() + "/files/0"; File cacheDir = context.getExternalFilesDir("testFiles"); if (cacheDir == null) @@ -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(); @@ -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/storage/AutoDownloadTest.java b/app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java index 00eef5c8d..b89f1b9bc 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,8 @@ 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; import org.junit.After; @@ -14,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; @@ -49,21 +52,16 @@ 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(); + UserPreferences.setAllowMobileStreaming(true); } @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); + EspressoTestUtils.tryKillPlaybackService(); + stubFeedsServer.tearDown(); } /** @@ -117,7 +115,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())); } @@ -126,7 +124,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..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; @@ -75,11 +77,11 @@ 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)); + onView(isRoot()).perform(waitForView(withId(R.id.butShowSettings), 5000)); } private String getActionbarTitle() { 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; }); 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..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 @@ -68,9 +69,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()); } @@ -88,7 +87,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(5, TimeUnit.SECONDS).until(() -> activityRule.getActivity().getPlaybackController().getStatus() == PlayerStatus.PLAYING); clickThroughSpeeds(); } @@ -97,10 +96,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(5, 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(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 66404e2a8..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; @@ -87,13 +88,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 { @@ -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) { 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<File> 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. * |