/*
* Copyright (c) 2016 Google Inc.
*
* 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 com.google.samples.apps.iosched.testutils;
import android.support.test.espresso.NoMatchingViewException;
import android.support.test.rule.ActivityTestRule;
import android.support.v7.widget.AppCompatCheckedTextView;
import android.view.View;
import com.google.samples.apps.iosched.R;
import com.google.samples.apps.iosched.navigation.NavigationModel;
import org.hamcrest.Matcher;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.contrib.DrawerActions.open;
import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom;
import static android.support.test.espresso.matcher.ViewMatchers.isChecked;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
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.allOf;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertTrue;
/**
* Methods to help with navigation testing
*/
public class NavigationUtils {
public static void showNavigation() {
onView(withId(R.id.drawer_layout)).perform(open()); // Open Drawer
}
public static void checkScreenTitleIsDisplayed(int stringResource) {
onView(allOf(withParent(withId(R.id.toolbar)),
withText(stringResource))).check(matches(isDisplayed()));
}
public static void clickOnNavigationItemAndCheckActivityIsDisplayed(
int navigationItemStringResource, int expectedTitleResource) {
// Given navigation menu
NavigationUtils.showNavigation();
// When selecting item
onView(getNavigationItemWithString(navigationItemStringResource)).perform(click());
// Then screen is showing
NavigationUtils.checkScreenTitleIsDisplayed(expectedTitleResource);
}
public static void checkNavigationItemIsDisplayed(int navigationItemStringResource) {
// Given navigation menu
NavigationUtils.showNavigation();
// Check selecting item is displayed
onView(getNavigationItemWithString(navigationItemStringResource)).check(
matches(isDisplayed()));
}
public static void checkNavigationItemIsNotDisplayed(int navigationItemStringResource) {
// Given navigation menu
NavigationUtils.showNavigation();
// Check selecting item does not exist
onView(getNavigationItemWithString(navigationItemStringResource)).check(doesNotExist());
}
public static void cleanUpActivityStack(ActivityTestRule rule) {
NavigationUtils.showNavigation();
// Selecting Explore activity will clean up the activity stack, leaving only the explore
// activity, which can then be finished
onView(getNavigationItemWithString(R.string.navdrawer_item_explore)).perform(click());
rule.getActivity().finish();
}
public static void checkNavigationIsDisplayedWhenClickingMenuIcon() {
checkNavigationItemIsDisplayed(R.string.navdrawer_item_explore);
}
public static void checkNavigationIconIsUp() {
onView(withContentDescription(R.string.close_and_go_back)).check(matches(isDisplayed()));
}
public static void checkNavigationIconIsMenu() {
onView(withContentDescription(R.string.navdrawer_description_a11y)).check(
matches(isDisplayed()));
}
/**
* Checks that the {@code expectedSelectedItem} is checked in the navigation drawer, and that no
* other items in the drawer are checked.
*/
public static void checkNavigationItemIsSelected(
NavigationModel.NavigationItemEnum expectedSelectedItem) {
// Given navigation menu
NavigationUtils.showNavigation();
boolean selectedFound = false;
for (int i = 0; i < NavigationModel.NavigationItemEnum.values().length; i++) {
NavigationModel.NavigationItemEnum item =
NavigationModel.NavigationItemEnum.values()[i];
try {
// Check item is displayed
onView(getNavigationItemWithString(item.getTitleResource())).check(
matches(isDisplayed()));
// If item is shown, check item is not activated, unless it is the requested one
if (NavigationModel.NavigationItemEnum.values()[i].getId() ==
expectedSelectedItem.getId()) {
onView(getNavigationItemWithString(item.getTitleResource())).check(
matches(isChecked()));
selectedFound = true;
} else {
onView(getNavigationItemWithString(item.getTitleResource())).check(
matches(not(isChecked())));
}
} catch (NoMatchingViewException e) {
// Not all navigation items in the enum are shown. This test doesn't aim to
// check that the correct items are shown, but that only the selected one among
// those shown is shown as selected. Tests in the navigation package check
// correct items are shown.
}
}
// Sanity check to ensure the tests in the try/catch block weren't all skipped
assertTrue(selectedFound);
}
private static Matcher<View> getNavigationItemWithString(int stringResource) {
return allOf(isAssignableFrom(AppCompatCheckedTextView.class), withText(stringResource));
}
}