diff options
author | H. Lehmann <ByteHamster@users.noreply.github.com> | 2019-10-22 17:01:34 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-10-22 17:01:34 +0200 |
commit | b5f3c79c6259dbee62451ad9cb7d5cee715897f3 (patch) | |
tree | 79095d6785c76592b0eed8c08b68faedf0839a3d /app/src/androidTest/java/de/test/antennapod/playback | |
parent | f1f91478b6057dbaaaa5255d14dfe254bdc10f1d (diff) | |
parent | c7415924e0fefdfb8ed945170ecb46e84bfeb470 (diff) | |
download | AntennaPod-b5f3c79c6259dbee62451ad9cb7d5cee715897f3.zip |
Merge pull request #3543 from ByteHamster/tests2
Improved playback test
Diffstat (limited to 'app/src/androidTest/java/de/test/antennapod/playback')
4 files changed, 377 insertions, 0 deletions
diff --git a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackBuiltinTest.java b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackBuiltinTest.java new file mode 100644 index 000000000..a80ee41d7 --- /dev/null +++ b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackBuiltinTest.java @@ -0,0 +1,17 @@ +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 new file mode 100644 index 000000000..0cf73f069 --- /dev/null +++ b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackExoplayerTest.java @@ -0,0 +1,17 @@ +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 new file mode 100644 index 000000000..a0fb74809 --- /dev/null +++ b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackSonicTest.java @@ -0,0 +1,17 @@ +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 new file mode 100644 index 000000000..78f1ba7c4 --- /dev/null +++ b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java @@ -0,0 +1,326 @@ +package de.test.antennapod.playback; + +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; +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.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.test.antennapod.EspressoTestUtils; +import de.test.antennapod.ui.UITestUtils; +import org.awaitility.Awaitility; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +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.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.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.hamcrest.Matchers.not; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertThat; + +/** + * test cases for starting and ending playback from the MainActivity and AudioPlayerActivity + */ +public abstract class PlaybackTest { + + @Rule + public ActivityTestRule<MainActivity> activityTestRule = new ActivityTestRule<>(MainActivity.class, false, false); + + private UITestUtils uiTestUtils; + protected Context context; + + @Before + public void setUp() throws Exception { + context = InstrumentationRegistry.getInstrumentation().getTargetContext(); + EspressoTestUtils.clearPreferences(); + EspressoTestUtils.clearDatabase(); + EspressoTestUtils.makeNotFirstRun(); + + uiTestUtils = new UITestUtils(context); + uiTestUtils.setup(); + } + + @After + public void tearDown() throws Exception { + uiTestUtils.tearDown(); + + // shut down playback service + skipEpisode(); + context.sendBroadcast(new Intent(PlaybackService.ACTION_SHUTDOWN_PLAYBACK_SERVICE)); + } + + @Test + public void testContinousPlaybackOffMultipleEpisodes() throws Exception { + 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()); + } + + @Test + public void testContinuousPlaybackOnMultipleEpisodes() throws Exception { + setContinuousPlaybackPreference(true); + uiTestUtils.addLocalFeedData(true); + activityTestRule.launchActivity(new Intent()); + + List<FeedItem> queue = DBReader.getQueue(); + final FeedItem first = queue.get(0); + 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; + } + }); + } + + + @Test + public void testReplayEpisodeContinuousPlaybackOn() throws Exception { + replayEpisodeCheck(true); + } + + @Test + public void testReplayEpisodeContinuousPlaybackOff() throws Exception { + replayEpisodeCheck(false); + } + + @Test + public void testSmartMarkAsPlayed_Skip_Average() throws Exception { + doTestSmartMarkAsPlayed_Skip_ForEpisode(0); + } + + @Test + public void testSmartMarkAsPlayed_Skip_LastEpisodeInQueue() throws Exception { + doTestSmartMarkAsPlayed_Skip_ForEpisode(-1); + } + + @Test + public void testSmartMarkAsPlayed_Pause_WontAffectItem() throws Exception { + setSmartMarkAsPlayedPreference(60); + + uiTestUtils.addLocalFeedData(true); + activityTestRule.launchActivity(new Intent()); + + final int fiIdx = 0; + final FeedItem feedItem = DBReader.getQueue().get(fiIdx); + + playFromQueue(fiIdx); + + // let playback run a bit then pause + Awaitility.await() + .atMost(1000, MILLISECONDS) + .until(() -> PlayerStatus.PLAYING == uiTestUtils.getPlaybackController(getActivity()).getStatus()); + pauseEpisode(); + Awaitility.await() + .atMost(1000, MILLISECONDS) + .until(() -> PlayerStatus.PAUSED == uiTestUtils.getPlaybackController(getActivity()).getStatus()); + + assertThat("Ensure even with smart mark as play, after pause, the item remains in the queue.", + DBReader.getQueue(), hasItems(feedItem)); + assertThat("Ensure even with smart mark as play, after pause, the item played status remains false.", + DBReader.getFeedItem(feedItem.getId()).isPlayed(), is(false)); + } + + @Test + public void testStartLocal() throws Exception { + uiTestUtils.addLocalFeedData(true); + activityTestRule.launchActivity(new Intent()); + DBWriter.clearQueue().get(); + startLocalPlayback(); + } + + @Test + public void testContinousPlaybackOffSingleEpisode() throws Exception { + setContinuousPlaybackPreference(false); + uiTestUtils.addLocalFeedData(true); + activityTestRule.launchActivity(new Intent()); + DBWriter.clearQueue().get(); + startLocalPlayback(); + } + + protected MainActivity getActivity() { + return activityTestRule.getActivity(); + } + + protected void setContinuousPlaybackPreference(boolean value) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + prefs.edit().putBoolean(UserPreferences.PREF_FOLLOW_QUEUE, value).commit(); + } + + protected void setSkipKeepsEpisodePreference(boolean value) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + prefs.edit().putBoolean(UserPreferences.PREF_SKIP_KEEPS_EPISODE, value).commit(); + } + + protected void setSmartMarkAsPlayedPreference(int smartMarkAsPlayedSecs) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + prefs.edit().putString(UserPreferences.PREF_SMART_MARK_AS_PLAYED_SECS, + Integer.toString(smartMarkAsPlayedSecs, 10)) + .commit(); + } + + private void skipEpisode() { + Intent skipIntent = new Intent(PlaybackService.ACTION_SKIP_CURRENT_EPISODE); + context.sendBroadcast(skipIntent); + } + + protected void pauseEpisode() { + Intent pauseIntent = new Intent(PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE); + context.sendBroadcast(pauseIntent); + } + + protected void startLocalPlayback() { + openNavDrawer(); + onDrawerItem(withText(R.string.episodes_label)).perform(click()); + onView(isRoot()).perform(waitForView(withId(R.id.emptyViewTitle), 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; + } + }); + } + + /** + * + * @param itemIdx The 0-based index of the episode to be played in the queue. + */ + 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; + } + }); + } + + /** + * Check if an episode can be played twice without problems. + */ + protected void replayEpisodeCheck(boolean followQueue) throws Exception { + setContinuousPlaybackPreference(followQueue); + uiTestUtils.addLocalFeedData(true); + DBWriter.clearQueue().get(); + activityTestRule.launchActivity(new Intent()); + 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); + + startLocalPlayback(); + Awaitility.await().atMost(1, TimeUnit.SECONDS).until(() -> { + if (uiTestUtils.getCurrentMedia(getActivity()) != null) { + return uiTestUtils.getCurrentMedia(getActivity()).getId() == mediaId; + } else { + return false; + } + }); + } + + 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.addLocalFeedData(true); + + 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; + } + final FeedItem feedItem = DBReader.getQueue().get(fiIdx); + + activityTestRule.launchActivity(new Intent()); + playFromQueue(fiIdx); + + skipEpisode(); + + // assert item no longer in queue (needs to wait till skip is asynchronously processed) + Awaitility.await() + .atMost(1000, MILLISECONDS) + .untilAsserted(() -> { + assertThat("Ensure smart mark as play will lead to the item removed from the queue", + DBReader.getQueue(), not(hasItems(feedItem))); + }); + assertThat(DBReader.getFeedItem(feedItem.getId()).isPlayed(), is(true)); + } +} |