Refactored instrumentation tests to support RecyclerViews

* Fixed Espresso not waiting on ViewPager switching
* Removed BaseMediaActivityTests abstract class.
  Unfortunately the click action on list items now requires
  a unique item to be able to select the item to click.
  Therefore the tests from BaseMediaActivityTests have been
  moved to the specific test classes. This made the
  BaseMediaActivityTests class obsolete.
* Removed dependency on Context class in AddonsHandler and inlined
  the json data to allow the AddonsHandler to be initialized before
  the test activity is started. This was needed to have the
  AddonsActivityTests directly start the AddonsActivity, instead of
  first starting MoviesActivity and from there start the AddonsActivity.
This commit is contained in:
Martijn Brekhof 2018-07-24 22:04:33 +02:00 committed by Synced Synapse
parent 90527708d2
commit d634d9455e
14 changed files with 1770 additions and 246 deletions

View File

@ -10,11 +10,6 @@ env:
android:
components:
# following added as quick fix to get support for 23.0.3 build tools
# "tools" always refers to the latest build tools version. Remove this
# when travis is able to parse "build-tools-23.0.3" correctly.
# See https://github.com/travis-ci/travis-ci/issues/5036
# - tools
# needed build tools
- build-tools-27.0.3

View File

@ -119,6 +119,7 @@ dependencies {
androidTestUtil 'com.android.support.test:orchestrator:1.0.1'
androidTestImplementation 'org.hamcrest:hamcrest-library:1.3'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-contrib:3.0.1'
androidTestImplementation "com.android.support:support-v13:${supportLibVersion}"
androidTestImplementation 'junit:junit:4.12'

View File

@ -23,6 +23,8 @@ import android.support.test.espresso.Espresso;
import android.support.test.espresso.NoMatchingViewException;
import android.support.test.espresso.UiController;
import android.support.test.espresso.ViewAction;
import android.support.test.espresso.ViewInteraction;
import android.support.test.espresso.contrib.RecyclerViewActions;
import android.view.View;
import android.widget.AutoCompleteTextView;
import android.widget.TextView;
@ -39,18 +41,21 @@ import static android.support.test.espresso.Espresso.openActionBarOverflowOrOpti
import static android.support.test.espresso.Espresso.pressBack;
import static android.support.test.espresso.action.ViewActions.clearText;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.action.ViewActions.closeSoftKeyboard;
import static android.support.test.espresso.action.ViewActions.typeText;
import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant;
import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.isRoot;
import static android.support.test.espresso.matcher.ViewMatchers.withClassName;
import static android.support.test.espresso.matcher.ViewMatchers.withContentDescription;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withParent;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.CoreMatchers.anything;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.anything;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.instanceOf;
import static org.xbmc.kore.testhelpers.action.ViewActions.clearFocus;
@ -108,9 +113,7 @@ public class EspressoTestUtils {
EspressoTestUtils.clickMenuItem(activity, activity.getString(R.string.action_search), R.id.action_search);
onView(isAssignableFrom(AutoCompleteTextView.class))
.perform(click(), typeText(query), clearFocus());
Espresso.closeSoftKeyboard();
.perform(click(), typeText(query), clearFocus(), closeSoftKeyboard());
}
/**
@ -121,9 +124,7 @@ public class EspressoTestUtils {
EspressoTestUtils.clickMenuItem(activity, activity.getString(R.string.action_search), R.id.action_search);
onView(isAssignableFrom(AutoCompleteTextView.class))
.perform(click(), clearText());
Espresso.closeSoftKeyboard();
.perform(click(), clearText(), closeSoftKeyboard());
}
/**
@ -150,7 +151,21 @@ public class EspressoTestUtils {
.atPosition(position).perform(click());
}
/**
public static void clickRecyclerViewItem(int position, int resourceId) {
onView(withId(resourceId)).perform(RecyclerViewActions.actionOnItemAtPosition(position, click()));
}
public static void clickRecyclerViewItem(String text, int resourceId) {
ViewInteraction viewInteraction = onView(allOf(withId(resourceId),
hasDescendant(withText(containsString(text))),
isDisplayed()));
viewInteraction.perform(RecyclerViewActions.scrollTo(hasDescendant(withText(containsString(text)))));
viewInteraction.perform(RecyclerViewActions.actionOnItem(hasDescendant(withText(containsString(text))),
click()));
}
/**
* Checks that SearchView contains the given text
* @param query text that SearchView should contain
*/
@ -165,9 +180,9 @@ public class EspressoTestUtils {
*/
public static void checkListMatchesSearchQuery(String query, int listSize, int resourceId) {
onView(allOf(withId(resourceId), isDisplayed()))
.check(matches(Matchers.withOnlyMatchingDataItems(Matchers.withItemContent(containsString(query)))));
.check(matches(Matchers.withOnlyMatchingDataItems(hasDescendant(withText(containsString(query))))));
onView(allOf(withId(resourceId), isDisplayed()))
.check(matches(Matchers.withAdapterSize(listSize)));
.check(matches(Matchers.withRecyclerViewSize(listSize)));
}
/**
@ -250,39 +265,54 @@ public class EspressoTestUtils {
public static void selectListItemPressBackAndCheckActionbarTitle(int item,
int listResourceId,
String actionbarTitle) {
EspressoTestUtils.clickAdapterViewItem(item, listResourceId);
EspressoTestUtils.clickRecyclerViewItem(item, listResourceId);
pressBack();
onView(allOf(instanceOf(TextView.class), withParent(withId(R.id.default_toolbar))))
.check(matches(withText(actionbarTitle)));
}
/**
* Selects an item in the list, then presses back and checks the action bar title
* @param itemText the text the item that must be pressed should contain
* @param listResourceId Resource identifier of the AdapterView
* @param actionbarTitle title that should be displayed in the action bar after pressing back
*/
public static void selectListItemPressBackAndCheckActionbarTitle(String itemText,
int listResourceId,
String actionbarTitle) {
EspressoTestUtils.clickRecyclerViewItem(itemText, listResourceId);
pressBack();
onView(allOf(instanceOf(TextView.class), withParent(withId(R.id.default_toolbar))))
.check(matches(withText(containsString(actionbarTitle))));
}
/**
* Selects an item in the list, then rotates the device and checks the action bar title
* @param item number (0 is first item) of the item that should be pressed
* @param itemText the text the item that must be pressed should contain
* @param listResourceId Resource identifier of the AdapterView
* @param actionbarTitle title that should be displayed in the action bar after rotating
*/
public static void selectListItemRotateDeviceAndCheckActionbarTitle(int item,
public static void selectListItemRotateDeviceAndCheckActionbarTitle(String itemText,
int listResourceId,
String actionbarTitle,
Activity activity) {
EspressoTestUtils.clickAdapterViewItem(item, listResourceId);
EspressoTestUtils.clickRecyclerViewItem(itemText, listResourceId);
EspressoTestUtils.rotateDevice(activity);
onView(allOf(instanceOf(TextView.class), withParent(withId(R.id.default_toolbar))))
.check(matches(withText(actionbarTitle)));
.check(matches(withText(containsString(actionbarTitle))));
}
/**
* Selects an item in the list and then checks the action bar title
* @param item number (0 is first item) of the item that should be pressed
* @param itemText the text the item that must be pressed should contain
* @param listResourceId Resource identifier of the AdapterView
* @param actionbarTitle title that should be displayed in the action bar after selecting item
*/
public static void selectListItemAndCheckActionbarTitle(int item,
public static void selectListItemAndCheckActionbarTitle(String itemText,
int listResourceId,
String actionbarTitle) {
EspressoTestUtils.clickAdapterViewItem(item, listResourceId);
EspressoTestUtils.clickRecyclerViewItem(itemText, listResourceId);
onView(allOf(instanceOf(TextView.class), withParent(withId(R.id.default_toolbar))))
.check(matches(withText(actionbarTitle)));
}

View File

@ -19,11 +19,10 @@ package org.xbmc.kore.testhelpers;
import android.database.Cursor;
import android.support.test.espresso.matcher.BoundedMatcher;
import android.support.test.espresso.matcher.CursorMatchers;
import android.support.v7.widget.RecyclerView;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.SeekBar;
import android.widget.TextView;
@ -31,8 +30,8 @@ import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.xbmc.kore.ui.widgets.RepeatModeButton;
import org.xbmc.kore.ui.widgets.HighlightButton;
import org.xbmc.kore.ui.widgets.RepeatModeButton;
import org.xbmc.kore.utils.UIUtils;
public class Matchers {
@ -70,33 +69,32 @@ public class Matchers {
};
}
public static Matcher<View> withAdapterSize(final int size) {
public static Matcher<View> withRecyclerViewSize(final int size) {
return new TypeSafeMatcher<View>() {
@Override
protected boolean matchesSafely(View view) {
if (!(view instanceof AdapterView))
return false;
return ((AdapterView) view).getCount() == size;
return (view instanceof RecyclerView) &&
((RecyclerView) view).getAdapter().getItemCount() == size;
}
@Override
public void describeTo(Description description) {
description.appendText("Adapter should have " + size + " item(s)");
description.appendText("RecyclerView should have " + size + " item(s)");
}
};
}
public static Matcher<View> withOnlyMatchingDataItems(final Matcher<Object> dataMatcher) {
public static Matcher<View> withOnlyMatchingDataItems(final Matcher<View> dataMatcher) {
return new TypeSafeMatcher<View>() {
@Override
protected boolean matchesSafely(View view) {
if (!(view instanceof AdapterView))
if (!(view instanceof RecyclerView))
return false;
Adapter adapter = ((AdapterView) view).getAdapter();
for (int i = 0; i < adapter.getCount(); i++) {
if (! dataMatcher.matches(adapter.getItem(i))) {
RecyclerView recyclerView = (RecyclerView) view;
for (int i = 0; i < recyclerView.getChildCount(); i++) {
RecyclerView.ViewHolder viewHolder = recyclerView.findViewHolderForAdapterPosition(i);
if (! dataMatcher.matches(viewHolder.itemView)) {
return false;
}
}

View File

@ -72,7 +72,6 @@ abstract public class AbstractTestClass<T extends AppCompatActivity> {
private ActivityTestRule<T> activityTestRule;
private static MockTcpServer server;
private static JSONConnectionHandlerManager manager;
private AddonsHandler addonsHandler;
private static PlayerHandler playerHandler;
private static ApplicationHandler applicationHandler;
private static InputHandler inputHandler;
@ -88,6 +87,7 @@ abstract public class AbstractTestClass<T extends AppCompatActivity> {
manager.addHandler(playerHandler);
manager.addHandler(applicationHandler);
manager.addHandler(inputHandler);
manager.addHandler(new AddonsHandler());
manager.addHandler(new JSONRPCHandler());
server = new MockTcpServer(manager);
server.start();
@ -108,13 +108,6 @@ abstract public class AbstractTestClass<T extends AppCompatActivity> {
//Allow each test to change the shared preferences
setSharedPreferences(context);
//Note: as the activity is not yet available in @BeforeClass we need
// to add the handler here
if (addonsHandler == null) {
addonsHandler = new AddonsHandler(context);
manager.addHandler(addonsHandler);
}
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean useEventServer = prefs.getBoolean(HostFragmentManualConfiguration.HOST_USE_EVENT_SERVER, false);
@ -136,6 +129,7 @@ abstract public class AbstractTestClass<T extends AppCompatActivity> {
Utils.switchHost(context, activityTestRule.getActivity(), hostInfo);
//Relaunch the activity for the changes (Host selection, preference changes, and database fill) to take effect
activityTestRule.finishActivity();
activityTestRule.launchActivity(new Intent());
}

View File

@ -1,127 +0,0 @@
/*
* Copyright 2017 Martijn Brekhof. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.xbmc.kore.tests.ui;
import android.content.Context;
import android.support.test.espresso.Espresso;
import android.support.test.rule.ActivityTestRule;
import org.junit.Ignore;
import org.junit.Test;
import org.xbmc.kore.R;
import org.xbmc.kore.host.HostInfo;
import org.xbmc.kore.testhelpers.EspressoTestUtils;
import org.xbmc.kore.testhelpers.Utils;
import org.xbmc.kore.ui.BaseMediaActivity;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.xbmc.kore.testhelpers.EspressoTestUtils.clickAdapterViewItem;
import static org.xbmc.kore.testhelpers.EspressoTestUtils.rotateDevice;
/**
* Contains generic tests for all activities extending BaseMediaActivity
* @param <T>
*/
@Ignore
abstract public class BaseMediaActivityTests<T extends BaseMediaActivity> extends AbstractTestClass<T> {
@Override
protected void setSharedPreferences(Context context) {
}
@Override
protected void configureHostInfo(HostInfo hostInfo) {
}
/**
* Test if the initial state shows the hamburger icon
*/
@Test
public void showHamburgerInInitialState() {
assertFalse(getActivity().getDrawerIndicatorIsArrow());
}
/**
* Test if navigation icon is changed to an arrow when selecting a list item
*
* UI interaction flow tested:
* 1. Click on list item
* 2. Result: navigation icon should be an arrow
*/
@Test
public void showArrowWhenSelectingListItem() {
clickAdapterViewItem(0, R.id.list);
assertTrue(((T) EspressoTestUtils.getActivity()).getDrawerIndicatorIsArrow());
}
/**
* Test if navigation icon is changed to an arrow when selecting a list item
*
* UI interaction flow tested:
* 1. Click on list item
* 2. Press back
* 3. Result: navigation icon should be a hamburger
*/
@Test
public void showHamburgerWhenSelectingListItemAndReturn() {
clickAdapterViewItem(0, R.id.list);
Espresso.pressBack();
assertFalse(((T) EspressoTestUtils.getActivity()).getDrawerIndicatorIsArrow());
}
/**
* Test if navigation icon is restored to an arrow when selecting a list item
* and rotating the device
*
* UI interaction flow tested:
* 1. Click on list item
* 2. Rotate device
* 3. Result: navigation icon should be an arrow
*/
@Test
public void restoreArrowOnConfigurationChange() {
clickAdapterViewItem(0, R.id.list);
rotateDevice(getActivity());
assertTrue(((T) EspressoTestUtils.getActivity()).getDrawerIndicatorIsArrow());
}
/**
* Test if navigation icon is restored to an hamburger when selecting a list item
* and rotating the device and returning to the list
*
* UI interaction flow tested:
* 1. Click on list item
* 2. Rotate device
* 3. Press back
* 4. Result: navigation icon should be a hamburger
*/
@Test
public void restoreHamburgerOnConfigurationChangeOnReturn() {
clickAdapterViewItem(0, R.id.list);
rotateDevice(getActivity());
Espresso.pressBack();
assertFalse(((T) EspressoTestUtils.getActivity()).getDrawerIndicatorIsArrow());
}
}

View File

@ -16,29 +16,34 @@
package org.xbmc.kore.tests.ui.addons;
import android.content.Intent;
import android.os.SystemClock;
import android.content.Context;
import android.support.test.espresso.Espresso;
import android.support.test.rule.ActivityTestRule;
import android.view.View;
import android.widget.TextView;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.xbmc.kore.R;
import org.xbmc.kore.host.HostInfo;
import org.xbmc.kore.testhelpers.EspressoTestUtils;
import org.xbmc.kore.testhelpers.Utils;
import org.xbmc.kore.testhelpers.action.ViewActions;
import org.xbmc.kore.tests.ui.AbstractTestClass;
import org.xbmc.kore.tests.ui.BaseMediaActivityTests;
import org.xbmc.kore.ui.sections.addon.AddonsActivity;
import org.xbmc.kore.ui.sections.video.MoviesActivity;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.isRoot;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withParent;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.xbmc.kore.testhelpers.EspressoTestUtils.clickRecyclerViewItem;
import static org.xbmc.kore.testhelpers.EspressoTestUtils.rotateDevice;
import static org.xbmc.kore.testhelpers.EspressoTestUtils.selectListItemPressBackAndCheckActionbarTitle;
/**
@ -59,24 +64,35 @@ import static org.xbmc.kore.testhelpers.EspressoTestUtils.selectListItemPressBac
* added in {@link super#setUp()} which is never started by Espresso as it waits for
* {@link org.xbmc.kore.ui.sections.addon.AddonsActivity} to become idle.
*/
public class AddonsActivityTests extends BaseMediaActivityTests<MoviesActivity> {
public class AddonsActivityTests extends AbstractTestClass<AddonsActivity> {
@Rule
public ActivityTestRule<MoviesActivity> mActivityRule = new ActivityTestRule<>(
MoviesActivity.class);
public ActivityTestRule<AddonsActivity> mActivityRule = new ActivityTestRule<>(AddonsActivity.class);
@Override
protected ActivityTestRule<MoviesActivity> getActivityTestRule() {
protected ActivityTestRule<AddonsActivity> getActivityTestRule() {
return mActivityRule;
}
@Before
@Override
protected void setSharedPreferences(Context context) {
}
@Override
protected void configureHostInfo(HostInfo hostInfo) {
}
@Before
public void setUp() throws Throwable {
super.setUp();
Intent intent = new Intent(getActivity(), AddonsActivity.class);
getActivity().startActivity(intent);
onView(isRoot()).perform(ViewActions.waitForView(R.id.list, new ViewActions.CheckStatus() {
@Override
public boolean check(View v) {
return v.isShown();
}
},10000));
}
/**
@ -97,7 +113,7 @@ public class AddonsActivityTests extends BaseMediaActivityTests<MoviesActivity>
*/
@Test
public void setActionBarTitle() {
EspressoTestUtils.selectListItemAndCheckActionbarTitle(0, R.id.list,
EspressoTestUtils.selectListItemAndCheckActionbarTitle("Dumpert", R.id.list,
"Dumpert");
}
@ -111,7 +127,7 @@ public class AddonsActivityTests extends BaseMediaActivityTests<MoviesActivity>
*/
@Test
public void restoreActionBarTitleOnConfigurationStateChanged() {
EspressoTestUtils.selectListItemRotateDeviceAndCheckActionbarTitle(0, R.id.list,
EspressoTestUtils.selectListItemRotateDeviceAndCheckActionbarTitle("Dumpert", R.id.list,
"Dumpert",
getActivity());
}
@ -129,4 +145,79 @@ public class AddonsActivityTests extends BaseMediaActivityTests<MoviesActivity>
selectListItemPressBackAndCheckActionbarTitle(0, R.id.list,
getActivity().getString(R.string.addons));
}
/**
* Test if the initial state shows the hamburger icon
*/
@Test
public void showHamburgerInInitialState() {
assertFalse(getActivity().getDrawerIndicatorIsArrow());
}
/**
* Test if navigation icon is changed to an arrow when selecting a list item
*
* UI interaction flow tested:
* 1. Click on list item
* 2. Result: navigation icon should be an arrow
*/
@Test
public void showArrowWhenSelectingListItem() {
clickRecyclerViewItem(0, R.id.list);
assertTrue(getActivity().getDrawerIndicatorIsArrow());
}
/**
* Test if navigation icon is changed to an arrow when selecting a list item
*
* UI interaction flow tested:
* 1. Click on list item
* 2. Press back
* 3. Result: navigation icon should be a hamburger
*/
@Test
public void showHamburgerWhenSelectingListItemAndReturn() {
clickRecyclerViewItem(0, R.id.list);
Espresso.pressBack();
assertFalse(getActivity().getDrawerIndicatorIsArrow());
}
/**
* Test if navigation icon is restored to an arrow when selecting a list item
* and rotating the device
*
* UI interaction flow tested:
* 1. Click on list item
* 2. Rotate device
* 3. Result: navigation icon should be an arrow
*/
@Test
public void restoreArrowOnConfigurationChange() {
clickRecyclerViewItem(0, R.id.list);
rotateDevice(getActivity());
assertTrue(getActivity().getDrawerIndicatorIsArrow());
}
/**
* Test if navigation icon is restored to an hamburger when selecting a list item
* and rotating the device and returning to the list
*
* UI interaction flow tested:
* 1. Click on list item
* 2. Rotate device
* 3. Press back
* 4. Result: navigation icon should be a hamburger
*/
@Test
public void restoreHamburgerOnConfigurationChangeOnReturn() {
clickRecyclerViewItem(0, R.id.list);
rotateDevice(getActivity());
Espresso.pressBack();
assertTrue(EspressoTestUtils.getActivity() instanceof AddonsActivity);
assertFalse(((AddonsActivity) EspressoTestUtils.getActivity()).getDrawerIndicatorIsArrow());
}
}

View File

@ -16,15 +16,17 @@
package org.xbmc.kore.tests.ui.movies;
import android.os.SystemClock;
import android.content.Context;
import android.support.test.espresso.Espresso;
import android.support.test.rule.ActivityTestRule;
import android.widget.TextView;
import org.junit.Rule;
import org.junit.Test;
import org.xbmc.kore.R;
import org.xbmc.kore.host.HostInfo;
import org.xbmc.kore.testhelpers.EspressoTestUtils;
import org.xbmc.kore.tests.ui.BaseMediaActivityTests;
import org.xbmc.kore.tests.ui.AbstractTestClass;
import org.xbmc.kore.ui.sections.video.MoviesActivity;
import static android.support.test.espresso.Espresso.onView;
@ -34,9 +36,13 @@ import static android.support.test.espresso.matcher.ViewMatchers.withParent;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.xbmc.kore.testhelpers.EspressoTestUtils.clickRecyclerViewItem;
import static org.xbmc.kore.testhelpers.EspressoTestUtils.rotateDevice;
import static org.xbmc.kore.testhelpers.EspressoTestUtils.selectListItemPressBackAndCheckActionbarTitle;
public class MoviesActivityTests extends BaseMediaActivityTests<MoviesActivity> {
public class MoviesActivityTests extends AbstractTestClass<MoviesActivity> {
@Rule
public ActivityTestRule<MoviesActivity> mActivityRule = new ActivityTestRule<>(
@ -47,6 +53,16 @@ public class MoviesActivityTests extends BaseMediaActivityTests<MoviesActivity>
return mActivityRule;
}
@Override
protected void setSharedPreferences(Context context) {
}
@Override
protected void configureHostInfo(HostInfo hostInfo) {
}
/**
* Test if action bar title initially displays Movies
*/
@ -65,7 +81,7 @@ public class MoviesActivityTests extends BaseMediaActivityTests<MoviesActivity>
*/
@Test
public void setActionBarTitle() {
EspressoTestUtils.selectListItemAndCheckActionbarTitle(0, R.id.list,
EspressoTestUtils.selectListItemAndCheckActionbarTitle("#Rookie93 Marc Marquez: Beyond the Smile", R.id.list,
"#Rookie93 Marc Marquez: Beyond the Smile");
}
@ -79,7 +95,7 @@ public class MoviesActivityTests extends BaseMediaActivityTests<MoviesActivity>
*/
@Test
public void restoreActionBarTitleOnConfigurationStateChanged() {
EspressoTestUtils.selectListItemRotateDeviceAndCheckActionbarTitle(0, R.id.list,
EspressoTestUtils.selectListItemRotateDeviceAndCheckActionbarTitle("#Rookie93 Marc Marquez: Beyond the Smile", R.id.list,
"#Rookie93 Marc Marquez: Beyond the Smile",
getActivity());
}
@ -97,4 +113,79 @@ public class MoviesActivityTests extends BaseMediaActivityTests<MoviesActivity>
selectListItemPressBackAndCheckActionbarTitle(0, R.id.list,
getActivity().getString(R.string.movies));
}
/**
* Test if the initial state shows the hamburger icon
*/
@Test
public void showHamburgerInInitialState() {
assertFalse(getActivity().getDrawerIndicatorIsArrow());
}
/**
* Test if navigation icon is changed to an arrow when selecting a list item
*
* UI interaction flow tested:
* 1. Click on list item
* 2. Result: navigation icon should be an arrow
*/
@Test
public void showArrowWhenSelectingListItem() {
clickRecyclerViewItem(0, R.id.list);
assertTrue(getActivity().getDrawerIndicatorIsArrow());
}
/**
* Test if navigation icon is changed to an arrow when selecting a list item
*
* UI interaction flow tested:
* 1. Click on list item
* 2. Press back
* 3. Result: navigation icon should be a hamburger
*/
@Test
public void showHamburgerWhenSelectingListItemAndReturn() {
clickRecyclerViewItem(0, R.id.list);
Espresso.pressBack();
assertFalse(getActivity().getDrawerIndicatorIsArrow());
}
/**
* Test if navigation icon is restored to an arrow when selecting a list item
* and rotating the device
*
* UI interaction flow tested:
* 1. Click on list item
* 2. Rotate device
* 3. Result: navigation icon should be an arrow
*/
@Test
public void restoreArrowOnConfigurationChange() {
clickRecyclerViewItem(0, R.id.list);
rotateDevice(getActivity());
assertTrue(getActivity().getDrawerIndicatorIsArrow());
}
/**
* Test if navigation icon is restored to an hamburger when selecting a list item
* and rotating the device and returning to the list
*
* UI interaction flow tested:
* 1. Click on list item
* 2. Rotate device
* 3. Press back
* 4. Result: navigation icon should be a hamburger
*/
@Test
public void restoreHamburgerOnConfigurationChangeOnReturn() {
clickRecyclerViewItem(0, R.id.list);
rotateDevice(getActivity());
Espresso.pressBack();
assertTrue(EspressoTestUtils.getActivity() instanceof MoviesActivity);
assertFalse(((MoviesActivity) EspressoTestUtils.getActivity()).getDrawerIndicatorIsArrow());
}
}

View File

@ -95,7 +95,7 @@ public class RestoreSearchQueryListFragmentTest extends AbstractTestClass<Movies
public void searchClickBackTest() {
EspressoTestUtils.clearSearchQuery(mActivityRule.getActivity());
EspressoTestUtils.enterSearchQuery(mActivityRule.getActivity(), SEARCH_QUERY);
EspressoTestUtils.clickAdapterViewItem(0, R.id.list);
EspressoTestUtils.clickRecyclerViewItem(0, R.id.list);
Espresso.pressBack();
EspressoTestUtils.checkTextInSearchQuery(SEARCH_QUERY);
@ -117,7 +117,7 @@ public class RestoreSearchQueryListFragmentTest extends AbstractTestClass<Movies
public void searchClickRotateBackTest() {
EspressoTestUtils.clearSearchQuery(mActivityRule.getActivity());
EspressoTestUtils.enterSearchQuery(mActivityRule.getActivity(), SEARCH_QUERY);
EspressoTestUtils.clickAdapterViewItem(0, R.id.list);
EspressoTestUtils.clickRecyclerViewItem(0, R.id.list);
EspressoTestUtils.rotateDevice(mActivityRule.getActivity());
Espresso.pressBack();
@ -141,10 +141,10 @@ public class RestoreSearchQueryListFragmentTest extends AbstractTestClass<Movies
@Test
public void searchClickBackClearSearchClickBackTest() {
EspressoTestUtils.enterSearchQuery(mActivityRule.getActivity(), SEARCH_QUERY);
EspressoTestUtils.clickAdapterViewItem(0, R.id.list);
EspressoTestUtils.clickRecyclerViewItem(0, R.id.list);
Espresso.pressBack();
EspressoTestUtils.clearSearchQuery(mActivityRule.getActivity());
EspressoTestUtils.clickAdapterViewItem(0, R.id.list);
EspressoTestUtils.clickRecyclerViewItem(0, R.id.list);
Espresso.pressBack();
EspressoTestUtils.checkSearchMenuCollapsed();
@ -164,7 +164,7 @@ public class RestoreSearchQueryListFragmentTest extends AbstractTestClass<Movies
@Test
public void searchClickBackBackTest() {
EspressoTestUtils.enterSearchQuery(mActivityRule.getActivity(), SEARCH_QUERY);
EspressoTestUtils.clickAdapterViewItem(0, R.id.list);
EspressoTestUtils.clickRecyclerViewItem(0, R.id.list);
Espresso.pressBack();
Espresso.pressBack();
@ -201,7 +201,7 @@ public class RestoreSearchQueryListFragmentTest extends AbstractTestClass<Movies
@Test
public void searchClickBackUpTest() {
EspressoTestUtils.enterSearchQuery(mActivityRule.getActivity(), SEARCH_QUERY);
EspressoTestUtils.clickAdapterViewItem(0, R.id.list);
EspressoTestUtils.clickRecyclerViewItem(0, R.id.list);
Espresso.pressBack();
EspressoTestUtils.clickToolbarCollapseButton();
EspressoTestUtils.checkSearchMenuCollapsed();

View File

@ -16,14 +16,18 @@
package org.xbmc.kore.tests.ui.music;
import android.content.Context;
import android.os.SystemClock;
import android.support.test.espresso.Espresso;
import android.support.test.rule.ActivityTestRule;
import android.widget.TextView;
import org.junit.Rule;
import org.junit.Test;
import org.xbmc.kore.R;
import org.xbmc.kore.host.HostInfo;
import org.xbmc.kore.testhelpers.EspressoTestUtils;
import org.xbmc.kore.tests.ui.BaseMediaActivityTests;
import org.xbmc.kore.tests.ui.AbstractTestClass;
import org.xbmc.kore.ui.sections.audio.MusicActivity;
import static android.support.test.espresso.Espresso.onView;
@ -33,15 +37,17 @@ import static android.support.test.espresso.matcher.ViewMatchers.withParent;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.xbmc.kore.testhelpers.EspressoTestUtils.clickAlbumsTab;
import static org.xbmc.kore.testhelpers.EspressoTestUtils.clickGenresTab;
import static org.xbmc.kore.testhelpers.EspressoTestUtils.clickMusicVideosTab;
import static org.xbmc.kore.testhelpers.EspressoTestUtils.rotateDevice;
import static org.xbmc.kore.testhelpers.EspressoTestUtils.selectListItemAndCheckActionbarTitle;
import static org.xbmc.kore.testhelpers.EspressoTestUtils.selectListItemPressBackAndCheckActionbarTitle;
import static org.xbmc.kore.testhelpers.EspressoTestUtils.selectListItemRotateDeviceAndCheckActionbarTitle;
public class MusicActivityTests extends BaseMediaActivityTests<MusicActivity> {
public class MusicActivityTests extends AbstractTestClass<MusicActivity> {
@Rule
public ActivityTestRule<MusicActivity> musicActivityActivityTestRule =
new ActivityTestRule<>(MusicActivity.class);
@ -51,6 +57,16 @@ public class MusicActivityTests extends BaseMediaActivityTests<MusicActivity> {
return musicActivityActivityTestRule;
}
@Override
protected void setSharedPreferences(Context context) {
}
@Override
protected void configureHostInfo(HostInfo hostInfo) {
}
/**
* Test if action bar title initially displays Music
*/
@ -69,7 +85,7 @@ public class MusicActivityTests extends BaseMediaActivityTests<MusicActivity> {
*/
@Test
public void setActionBarTitleArtist() {
selectListItemAndCheckActionbarTitle(0, R.id.list, "ABC Orch");
selectListItemAndCheckActionbarTitle(ArtistTestData.title, R.id.list, ArtistTestData.title);
}
/**
@ -83,7 +99,7 @@ public class MusicActivityTests extends BaseMediaActivityTests<MusicActivity> {
@Test
public void setActionBarTitleAlbum() {
clickAlbumsTab();
selectListItemAndCheckActionbarTitle(0, R.id.list, "1958 - The Fabulous Johnny Cash");
selectListItemAndCheckActionbarTitle(AlbumTestData.title, R.id.list, AlbumTestData.title);
}
/**
@ -97,7 +113,7 @@ public class MusicActivityTests extends BaseMediaActivityTests<MusicActivity> {
@Test
public void setActionBarTitleGenre() {
clickGenresTab();
selectListItemAndCheckActionbarTitle(0, R.id.list, "Ambient");
selectListItemAndCheckActionbarTitle(GenreTestData.title, R.id.list, GenreTestData.title);
}
/**
@ -111,7 +127,7 @@ public class MusicActivityTests extends BaseMediaActivityTests<MusicActivity> {
@Test
public void setActionBarTitleVideo() {
clickMusicVideosTab();
selectListItemAndCheckActionbarTitle(0, R.id.list, "(You Drive Me) Crazy");
selectListItemAndCheckActionbarTitle(MusicVideoTestData.title, R.id.list, MusicVideoTestData.title);
}
/**
@ -125,8 +141,9 @@ public class MusicActivityTests extends BaseMediaActivityTests<MusicActivity> {
*/
@Test
public void restoreActionBarTitleArtistOnConfigurationStateChanged() {
selectListItemRotateDeviceAndCheckActionbarTitle(0, R.id.list,
"ABC Orch", getActivity());
SystemClock.sleep(10000);
selectListItemRotateDeviceAndCheckActionbarTitle(ArtistTestData.title, R.id.list,
ArtistTestData.title, getActivity());
}
/**
@ -142,8 +159,8 @@ public class MusicActivityTests extends BaseMediaActivityTests<MusicActivity> {
@Test
public void restoreActionBarTitleAlbumOnConfigurationStateChanged() {
clickAlbumsTab();
selectListItemRotateDeviceAndCheckActionbarTitle(0, R.id.list,
"1958 - The Fabulous Johnny Cash",
selectListItemRotateDeviceAndCheckActionbarTitle(AlbumTestData.title, R.id.list,
AlbumTestData.title,
getActivity());
}
@ -160,8 +177,8 @@ public class MusicActivityTests extends BaseMediaActivityTests<MusicActivity> {
@Test
public void restoreActionBarTitleGenreOnConfigurationStateChanged() {
clickGenresTab();
selectListItemRotateDeviceAndCheckActionbarTitle(0, R.id.list,
"Ambient", getActivity());
selectListItemRotateDeviceAndCheckActionbarTitle(GenreTestData.title, R.id.list,
GenreTestData.title, getActivity());
}
/**
@ -177,8 +194,8 @@ public class MusicActivityTests extends BaseMediaActivityTests<MusicActivity> {
@Test
public void restoreActionBarTitleMusicVideoOnConfigurationStateChanged() {
clickMusicVideosTab();
selectListItemRotateDeviceAndCheckActionbarTitle(0, R.id.list,
"(You Drive Me) Crazy",
selectListItemRotateDeviceAndCheckActionbarTitle(MusicVideoTestData.title, R.id.list,
MusicVideoTestData.title,
getActivity());
}
@ -192,7 +209,7 @@ public class MusicActivityTests extends BaseMediaActivityTests<MusicActivity> {
*/
@Test
public void restoreActionBarTitleOnReturningFromArtist() {
selectListItemPressBackAndCheckActionbarTitle(0, R.id.list,
selectListItemPressBackAndCheckActionbarTitle(ArtistTestData.title, R.id.list,
getActivity().getString(R.string.music));
}
@ -208,9 +225,9 @@ public class MusicActivityTests extends BaseMediaActivityTests<MusicActivity> {
*/
@Test
public void restoreActionBarTitleOnArtistOnReturningFromAlbum() {
EspressoTestUtils.clickAdapterViewItem(0, R.id.list);
EspressoTestUtils.clickRecyclerViewItem(ArtistTestData.title, R.id.list);
clickAlbumsTab();
selectListItemPressBackAndCheckActionbarTitle(0, R.id.list, "ABC Orch");
selectListItemPressBackAndCheckActionbarTitle(ArtistTestData.album, R.id.list, ArtistTestData.title);
}
/**
@ -224,7 +241,7 @@ public class MusicActivityTests extends BaseMediaActivityTests<MusicActivity> {
@Test
public void restoreActionBarTitleOnReturningFromMusicVideo() {
clickMusicVideosTab();
selectListItemPressBackAndCheckActionbarTitle(0, R.id.list,
selectListItemPressBackAndCheckActionbarTitle(MusicVideoTestData.title, R.id.list,
getActivity().getString(R.string.music));
}
@ -239,7 +256,7 @@ public class MusicActivityTests extends BaseMediaActivityTests<MusicActivity> {
@Test
public void restoreActionBarTitleOnReturningFromGenre() {
clickGenresTab();
selectListItemPressBackAndCheckActionbarTitle(0, R.id.list,
selectListItemPressBackAndCheckActionbarTitle(GenreTestData.title, R.id.list,
getActivity().getString(R.string.music));
}
@ -254,7 +271,101 @@ public class MusicActivityTests extends BaseMediaActivityTests<MusicActivity> {
@Test
public void restoreActionBarTitleOnReturningFromAlbum() {
clickAlbumsTab();
selectListItemPressBackAndCheckActionbarTitle(0, R.id.list,
selectListItemPressBackAndCheckActionbarTitle(AlbumTestData.title, R.id.list,
getActivity().getString(R.string.music));
}
/**
* Test if the initial state shows the hamburger icon
*/
@Test
public void showHamburgerInInitialState() {
assertFalse(getActivity().getDrawerIndicatorIsArrow());
}
/**
* Test if navigation icon is changed to an arrow when selecting a list item
*
* UI interaction flow tested:
* 1. Click on list item
* 2. Result: navigation icon should be an arrow
*/
@Test
public void showArrowWhenSelectingListItem() {
EspressoTestUtils.clickRecyclerViewItem(ArtistTestData.title, R.id.list);
assertTrue(getActivity().getDrawerIndicatorIsArrow());
}
/**
* Test if navigation icon is changed to an arrow when selecting a list item
*
* UI interaction flow tested:
* 1. Click on list item
* 2. Press back
* 3. Result: navigation icon should be a hamburger
*/
@Test
public void showHamburgerWhenSelectingListItemAndReturn() {
EspressoTestUtils.clickRecyclerViewItem(ArtistTestData.title, R.id.list);
Espresso.pressBack();
assertFalse(getActivity().getDrawerIndicatorIsArrow());
}
/**
* Test if navigation icon is restored to an arrow when selecting a list item
* and rotating the device
*
* UI interaction flow tested:
* 1. Click on list item
* 2. Rotate device
* 3. Result: navigation icon should be an arrow
*/
@Test
public void restoreArrowOnConfigurationChange() {
EspressoTestUtils.clickRecyclerViewItem(ArtistTestData.title, R.id.list);
rotateDevice(getActivity());
assertTrue(getActivity().getDrawerIndicatorIsArrow());
}
/**
* Test if navigation icon is restored to an hamburger when selecting a list item
* and rotating the device and returning to the list
*
* UI interaction flow tested:
* 1. Click on list item
* 2. Rotate device
* 3. Press back
* 4. Result: navigation icon should be a hamburger
*/
@Test
public void restoreHamburgerOnConfigurationChangeOnReturn() {
EspressoTestUtils.clickRecyclerViewItem(ArtistTestData.title, R.id.list);
rotateDevice(getActivity());
Espresso.pressBack();
assertTrue(EspressoTestUtils.getActivity() instanceof MusicActivity);
assertFalse(((MusicActivity) EspressoTestUtils.getActivity()).getDrawerIndicatorIsArrow());
}
private static class ArtistTestData {
static String title = "ABC Orch Conducted by Herschel Burke Gilbert";
static String album = "Songs Of The West";
}
private static class AlbumTestData {
static String title = "1958 - The Fabulous Johnny Cash";
}
private static class GenreTestData {
static String title = "Ambient";
}
private static class MusicVideoTestData {
static String title = "(You Drive Me) Crazy";
}
}

View File

@ -18,7 +18,6 @@ package org.xbmc.kore.tests.ui.music;
import android.app.Activity;
import android.content.Context;
import android.os.SystemClock;
import android.support.test.espresso.Espresso;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
@ -43,6 +42,7 @@ public class RestoreSearchQueryViewPagerTest extends AbstractTestClass<MusicActi
private final String ARTIST_SEARCH_QUERY = "Ben";
private final int ARTIST_SEARCH_QUERY_LIST_SIZE = 2;
private final String ARTIST_MATCHING_SEARCH_QUERY = "Ben E. King";
private final String ALBUMS_SEARCH_QUERY = "tes";
private final int ALBUM_SEARCH_QUERY_LIST_SIZE = 3;
private final int ARTIST_COMPLETE_LIST_SIZE = 229;
@ -113,7 +113,7 @@ public class RestoreSearchQueryViewPagerTest extends AbstractTestClass<MusicActi
@Test
public void searchClickBackTest() {
EspressoTestUtils.enterSearchQuery(mActivityRule.getActivity(), ARTIST_SEARCH_QUERY);
EspressoTestUtils.clickAdapterViewItem(0, R.id.list);
EspressoTestUtils.clickRecyclerViewItem(ARTIST_MATCHING_SEARCH_QUERY, R.id.list);
Espresso.pressBack();
EspressoTestUtils.checkTextInSearchQuery(ARTIST_SEARCH_QUERY);
@ -134,7 +134,7 @@ public class RestoreSearchQueryViewPagerTest extends AbstractTestClass<MusicActi
@Test
public void searchClickRotateBackTest() {
EspressoTestUtils.enterSearchQuery(mActivityRule.getActivity(), ARTIST_SEARCH_QUERY);
EspressoTestUtils.clickAdapterViewItem(0, R.id.list);
EspressoTestUtils.clickRecyclerViewItem(ARTIST_MATCHING_SEARCH_QUERY, R.id.list);
EspressoTestUtils.rotateDevice(mActivityRule.getActivity());
Espresso.pressBack();

View File

@ -16,14 +16,17 @@
package org.xbmc.kore.tests.ui.tvshows;
import android.content.Context;
import android.support.test.espresso.Espresso;
import android.support.test.rule.ActivityTestRule;
import android.widget.TextView;
import org.junit.Rule;
import org.junit.Test;
import org.xbmc.kore.R;
import org.xbmc.kore.host.HostInfo;
import org.xbmc.kore.testhelpers.EspressoTestUtils;
import org.xbmc.kore.tests.ui.BaseMediaActivityTests;
import org.xbmc.kore.tests.ui.AbstractTestClass;
import org.xbmc.kore.ui.sections.video.TVShowsActivity;
import static android.support.test.espresso.Espresso.onView;
@ -34,9 +37,15 @@ import static android.support.test.espresso.matcher.ViewMatchers.withParent;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.xbmc.kore.testhelpers.EspressoTestUtils.clickRecyclerViewItem;
import static org.xbmc.kore.testhelpers.EspressoTestUtils.rotateDevice;
import static org.xbmc.kore.testhelpers.action.ViewActions.nestedScrollTo;
public class TVShowsActivityTests extends BaseMediaActivityTests<TVShowsActivity> {
public class TVShowsActivityTests extends AbstractTestClass<TVShowsActivity> {
private final String TV_SHOW_TITLE = "11.22.63";
private final String EPISODE_TITLE = "The Rabbit Hole";
@Rule
public ActivityTestRule<TVShowsActivity> mActivityRule = new ActivityTestRule<>(
@ -47,6 +56,16 @@ public class TVShowsActivityTests extends BaseMediaActivityTests<TVShowsActivity
return mActivityRule;
}
@Override
protected void setSharedPreferences(Context context) {
}
@Override
protected void configureHostInfo(HostInfo hostInfo) {
}
/**
* Test if action bar title initially displays TV Shows
*/
@ -65,7 +84,7 @@ public class TVShowsActivityTests extends BaseMediaActivityTests<TVShowsActivity
*/
@Test
public void setActionBarTitle() {
EspressoTestUtils.selectListItemAndCheckActionbarTitle(0, R.id.list, "11.22.63");
EspressoTestUtils.selectListItemAndCheckActionbarTitle(TV_SHOW_TITLE, R.id.list, TV_SHOW_TITLE);
}
/**
@ -78,7 +97,7 @@ public class TVShowsActivityTests extends BaseMediaActivityTests<TVShowsActivity
*/
@Test
public void setActionBarTitleOnNextEpisode() {
EspressoTestUtils.clickAdapterViewItem(1, R.id.list);
clickRecyclerViewItem(1, R.id.list);
onView( withId(R.id.next_episode_list)).perform( nestedScrollTo(), click());
onView(allOf(instanceOf(TextView.class), withParent(withId(R.id.default_toolbar))))
@ -95,7 +114,7 @@ public class TVShowsActivityTests extends BaseMediaActivityTests<TVShowsActivity
*/
@Test
public void setActionBarTitleOnSeasonList() {
EspressoTestUtils.clickAdapterViewItem(0, R.id.list);
clickRecyclerViewItem(0, R.id.list);
onView( withId(R.id.seasons_list)).perform(nestedScrollTo(), click());
onView(allOf(instanceOf(TextView.class), withParent(withId(R.id.default_toolbar))))
@ -113,9 +132,9 @@ public class TVShowsActivityTests extends BaseMediaActivityTests<TVShowsActivity
*/
@Test
public void setActionBarTitleOnSeasonListEpisode() {
EspressoTestUtils.clickAdapterViewItem(0, R.id.list);
clickRecyclerViewItem(0, R.id.list);
onView( withId(R.id.seasons_list)).perform( nestedScrollTo(), click());
EspressoTestUtils.selectListItemAndCheckActionbarTitle(0, R.id.list, "11.22.63");
EspressoTestUtils.selectListItemAndCheckActionbarTitle(EPISODE_TITLE, R.id.list, TV_SHOW_TITLE);
}
/**
@ -128,8 +147,8 @@ public class TVShowsActivityTests extends BaseMediaActivityTests<TVShowsActivity
*/
@Test
public void restoreActionBarTitleOnConfigurationStateChanged() {
EspressoTestUtils.selectListItemRotateDeviceAndCheckActionbarTitle(0, R.id.list,
"11.22.63",
EspressoTestUtils.selectListItemRotateDeviceAndCheckActionbarTitle(TV_SHOW_TITLE, R.id.list,
TV_SHOW_TITLE,
mActivityRule.getActivity());
}
@ -144,7 +163,7 @@ public class TVShowsActivityTests extends BaseMediaActivityTests<TVShowsActivity
*/
@Test
public void restoreActionBarTitleSeasonListOnConfigurationStateChanged() {
EspressoTestUtils.clickAdapterViewItem(0, R.id.list);
clickRecyclerViewItem(0, R.id.list);
onView( withId(R.id.seasons_list)).perform( nestedScrollTo(), click());
EspressoTestUtils.rotateDevice(mActivityRule.getActivity());
<