aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorweldoncyngn <wng@cyngn.com>2015-07-29 13:58:35 -0700
committerGerrit Code Review <gerrit@cyanogenmod.org>2015-08-28 13:57:36 -0700
commit4803835d855055f376bc6728cd4b959ab8d0a3a9 (patch)
treeda36d00a06d9e895ea819e3f8738f09fe540030b
parent60b5090aa7cf6fe7a640720c5e6a43a563c830e4 (diff)
downloadandroid_packages_apps_CMFileManager-staging/dev.tar.gz
android_packages_apps_CMFileManager-staging/dev.tar.bz2
android_packages_apps_CMFileManager-staging/dev.zip
Initial commit for Espresso tests.staging/dev
Change-Id: Ie2cd998d9399d51ad646d7ffe3e82cf9ca61a6b7
-rw-r--r--androidTest/.gitignore7
-rwxr-xr-xandroidTest/Android.mk54
-rwxr-xr-xandroidTest/AndroidManifest.xml22
-rwxr-xr-xandroidTest/README.md8
-rw-r--r--androidTest/res/drawable-hdpi/ic_launcher.pngbin0 -> 4811 bytes
-rw-r--r--androidTest/res/drawable-mdpi/ic_launcher.pngbin0 -> 3033 bytes
-rw-r--r--androidTest/res/drawable-xhdpi/ic_launcher.pngbin0 -> 6887 bytes
-rw-r--r--androidTest/res/values/strings.xml19
-rw-r--r--androidTest/src/com/cyanogenmod/filemanager/activities/MainActivityTest.java481
-rw-r--r--androidTest/src/com/cyanogenmod/filemanager/activities/WelcomeActivityTest.java137
-rwxr-xr-xsrc/com/cyanogenmod/filemanager/activities/MainActivity.java4
11 files changed, 731 insertions, 1 deletions
diff --git a/androidTest/.gitignore b/androidTest/.gitignore
new file mode 100644
index 00000000..663bbcab
--- /dev/null
+++ b/androidTest/.gitignore
@@ -0,0 +1,7 @@
+/.settings
+/bin
+/gen
+/.checkstyle
+/.classpath
+/.project
+/project.properties
diff --git a/androidTest/Android.mk b/androidTest/Android.mk
new file mode 100755
index 00000000..b9def492
--- /dev/null
+++ b/androidTest/Android.mk
@@ -0,0 +1,54 @@
+#
+# Copyright (C) 2012 The CyanogenMod Project
+#
+# 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.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# We only want this apk build for tests.
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_STATIC_JAVA_LIBRARIES := espresso
+
+annotation_dir := ../../../../frameworks/testing/runner/src/main/java/android/support/test/annotation
+rules_dir := ../../../../frameworks/testing/rules/src/main
+
+# Include all test java files.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SRC_FILES += $(call all-java-files-under, $(annotation_dir))
+LOCAL_SRC_FILES += $(call all-java-files-under, $(rules_dir))
+
+# Notice that we don't have to include the src files of CMFileManager because, by
+# running the tests using an instrumentation targeting CMFileManager, we
+# automatically get all of its classes loaded into our environment.
+
+LOCAL_PACKAGE_NAME := CMFileManagerAndroidTests
+
+LOCAL_INSTRUMENTATION_FOR := CMFileManager
+
+LOCAL_CERTIFICATE := platform
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+include $(BUILD_PACKAGE)
+
+include $(CLEAR_VARS)
+
+LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := \
+ espresso:../../../../prebuilts/misc/common/android-support-test/espresso-core.jar
+
+include $(BUILD_MULTI_PREBUILT)
diff --git a/androidTest/AndroidManifest.xml b/androidTest/AndroidManifest.xml
new file mode 100755
index 00000000..ab81c3c4
--- /dev/null
+++ b/androidTest/AndroidManifest.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.cyanogenmod.filemanager.test">
+
+ <original-package android:name="com.cyanogenmod.filemanager.test" />
+
+ <uses-sdk android:minSdkVersion="17" android:targetSdkVersion="17" />
+
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
+
+ <instrumentation
+ android:name="android.support.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.cyanogenmod.filemanager" />
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name" >
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+</manifest>
diff --git a/androidTest/README.md b/androidTest/README.md
new file mode 100755
index 00000000..40e099e7
--- /dev/null
+++ b/androidTest/README.md
@@ -0,0 +1,8 @@
+To run the espresso tests:
+
+mm
+
+adb install -r $OUT/data/app/CMFileManagerAndroidTests/CMFileManagerAndroidTests.apk
+
+adb shell am instrument -w -e class com.cyanogenmod.filemanager.activities.WelcomeActivityTest com.cyanogenmod.filemanager.test/android.support.test.runner.AndroidJUnitRunner
+adb shell am instrument -w -e class com.cyanogenmod.filemanager.activities.MainActivityTest com.cyanogenmod.filemanager.test/android.support.test.runner.AndroidJUnitRunner
diff --git a/androidTest/res/drawable-hdpi/ic_launcher.png b/androidTest/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 00000000..6705a79d
--- /dev/null
+++ b/androidTest/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/androidTest/res/drawable-mdpi/ic_launcher.png b/androidTest/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 00000000..7d7c4881
--- /dev/null
+++ b/androidTest/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/androidTest/res/drawable-xhdpi/ic_launcher.png b/androidTest/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 00000000..51e4604b
--- /dev/null
+++ b/androidTest/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/androidTest/res/values/strings.xml b/androidTest/res/values/strings.xml
new file mode 100644
index 00000000..219dcb07
--- /dev/null
+++ b/androidTest/res/values/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ** Copyright (C) 2015 The CyanogenMod Project
+ **
+ ** 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.
+-->
+<resources>
+ <string name="app_name">File Manager Tests</string>
+</resources>
diff --git a/androidTest/src/com/cyanogenmod/filemanager/activities/MainActivityTest.java b/androidTest/src/com/cyanogenmod/filemanager/activities/MainActivityTest.java
new file mode 100644
index 00000000..a9750a66
--- /dev/null
+++ b/androidTest/src/com/cyanogenmod/filemanager/activities/MainActivityTest.java
@@ -0,0 +1,481 @@
+/*
+ * Copyright (C) 2015 The CyanogenMod Project
+ *
+ * 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.cyanogenmod.filemanager.activities;
+
+import android.app.Activity;
+import android.support.test.espresso.action.ViewActions;
+import android.support.test.espresso.matcher.BoundedMatcher;
+import android.support.test.espresso.matcher.ViewMatchers;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.View;
+import android.widget.Adapter;
+import android.widget.AdapterView;
+import android.widget.ListView;
+
+import com.cyanogen.ambient.storage.provider.StorageProviderInfo;
+import com.cyanogenmod.filemanager.R;
+import com.cyanogenmod.filemanager.console.storageapi.StorageApiConsole;
+import com.cyanogenmod.filemanager.model.FileSystemObject;
+import com.cyanogenmod.filemanager.util.StorageHelper;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+import java.io.InvalidClassException;
+import java.lang.InterruptedException;
+import java.util.List;
+import java.util.Random;
+
+import static android.support.test.espresso.Espresso.onData;
+import static android.support.test.espresso.Espresso.onView;
+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.longClick;
+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.isAssignableFrom;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static android.support.test.espresso.matcher.ViewMatchers.withContentDescription;
+import static android.support.test.espresso.matcher.ViewMatchers.withText;
+
+import static org.hamcrest.Matchers.allOf;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+
+/**
+ * The timeouts for each test size is:
+ * @SmallTest - 1 minute
+ * @MediumTest - 3 minutes
+ * @LargeTest - 5 minutes
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class MainActivityTest {
+ private static final String TAG = MainActivityTest.class.getSimpleName();
+ private static final String OK = "OK";
+ private static final String YES = "Yes";
+ private static final String NEW_FOLDER = "New folder";
+ private static final String NEW_FILE = "New file";
+ private static final String DELETE_SELECTION = "Delete selection";
+ private static final String COPY_TO = "Copy to";
+ private static final String MOVE_TO = "Move to";
+ private static final String DROPBOX = "Dropbox";
+ private static final String LOCAL_STORAGE = "Local storage";
+ private static final String COPY = "Copy";
+ private static final String MOVE = "Move";
+ private static final String MORE_OPTIONS = "More options";
+
+ private MainActivity mActivity;
+
+ /**
+ * A JUnit {@link Rule @Rule} to launch your activity under test. This is a replacement
+ * for {@link ActivityInstrumentationTestCase2}.
+ * <p>
+ * Rules are interceptors which are executed for each test method and will run before
+ * any of your setup code in the {@link Before @Before} method.
+ * <p>
+ * {@link ActivityTestRule} will create and launch of the activity for you and also expose
+ * the activity under test. To get a reference to the activity you can use
+ * the {@link ActivityTestRule#getActivity()} method.
+ */
+ @Rule
+ public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(
+ MainActivity.class);
+
+ @Before
+ public void setUp() {
+ mActivity = (MainActivity) mActivityRule.getActivity();
+ Assert.assertNotNull(mActivity);
+ }
+
+ /**
+ * Tests the Navigation Fragment of the Main Activity.
+ * Navigates to Storage API provider. Verify the provider's title is Dropbox.
+ * Verify the navigation fragment is presented.
+ */
+ @Test
+ public void navigateToDropbox() throws InterruptedException {
+ pauseForProviderToLoad();
+ List<StorageProviderInfo> providerInfoList = mActivity.getProviderList();
+ Assert.assertNotNull("providerInfoList is null", providerInfoList);
+ Assert.assertEquals("No longer support single provider. Modify test.",
+ providerInfoList.size(), 1);
+ StorageProviderInfo storageProviderInfo = providerInfoList.get(0);
+ Assert.assertFalse("Provider still needs authentication", storageProviderInfo.needAuthentication());
+ Assert.assertEquals("Not equal to Dropbox", storageProviderInfo.getTitle(), "Dropbox");
+ String path = StorageApiConsole.constructStorageApiFilePathFromProvider(
+ storageProviderInfo.getRootDocumentId(),
+ StorageApiConsole.getHashCodeFromProvider(storageProviderInfo));
+ mActivity.navigateToPath(path);
+ Thread.sleep(1000);
+ Assert.assertTrue("Current Fragment is not NAVIGATION",
+ mActivity.isCurrentFragment(MainActivity.FragmentType.NAVIGATION));
+ }
+
+ /**
+ * Tests dismissing add cloud storage card.
+ */
+ @Test
+ public void dismissAddCloudStorageCard() throws InterruptedException, InvalidClassException {
+ onView(withId(R.id.dismiss_card)).check(matches(isDisplayed()));
+ onView(withId(R.id.dismiss_card)).perform(click());
+ onView(withId(R.id.dismiss_card)).check(matches(not(isDisplayed())));
+ }
+
+ /**
+ * Tests creating local folder and file.
+ */
+ @Test
+ public void createDeleteLocalFolderAndFile() throws InterruptedException {
+ String FOLDER_NAME = "BTestFolder" + new Random().nextInt();
+ String FILE_NAME = "TestFile" + new Random().nextInt();
+
+ mActivity.navigateToPath(StorageHelper.getLocalStoragePath(mActivity));
+
+ // create a folder
+ onView(withContentDescription(MORE_OPTIONS)).perform(click());
+ onView(withText(NEW_FOLDER)).perform(click());
+ onView(withId(R.id.input_name_dialog_edit)).perform(clearText()).perform(typeText(FOLDER_NAME));
+ onView(withText(OK)).perform(click());
+
+ // check folder exists
+ onView(withId(R.id.navigation_view_layout))
+ .check(matches(withAdaptedData(withDocumentName(FOLDER_NAME))));
+
+ // create a file
+ onData(withDocumentName(FOLDER_NAME))
+ .inAdapterView(allOf(isAssignableFrom(ListView.class), isDisplayed()))
+ .perform(click());
+ onView(withContentDescription(MORE_OPTIONS)).perform(click());
+ onView(withText(NEW_FILE)).perform(click());
+ onView(withId(R.id.input_name_dialog_edit)).perform(clearText()).perform(typeText(FILE_NAME));
+ onView(withText(OK)).perform(click());
+
+ // check file exists
+ onView(withId(R.id.navigation_view_layout))
+ .check(matches(withAdaptedData(withDocumentName(FILE_NAME))));
+
+ Thread.sleep(2000);
+ pressBack();
+ Thread.sleep(2000);
+
+ // delete the folder
+ onData(withDocumentName(FOLDER_NAME))
+ .inAdapterView(allOf(isAssignableFrom(ListView.class), isDisplayed()))
+ .perform(longClick());
+ onView(withId(R.id.ab_actions)).perform(click());
+ onView(withText(DELETE_SELECTION)).perform(click());
+ onView(withText(YES)).perform(click());
+
+ // check folder is gone
+ onView(withId(R.id.navigation_view_layout))
+ .check(matches(not(withAdaptedData(withDocumentName(FOLDER_NAME)))));
+ }
+
+ /**
+ * Tests copying a file from local to Dropbox
+ */
+ @Test
+ public void copyFileFromLocalToDropbox() {
+ String FILE_NAME = "LocalFile" + new Random().nextInt();
+ mActivity.navigateToPath(StorageHelper.getLocalStoragePath(mActivity));
+
+ // create a file
+ onView(withContentDescription(MORE_OPTIONS)).perform(click());
+ onView(withText(NEW_FILE)).perform(click());
+ onView(withId(R.id.input_name_dialog_edit)).perform(clearText()).perform(typeText(FILE_NAME));
+ onView(withText(OK)).perform(click());
+ onData(withDocumentName(FILE_NAME))
+ .inAdapterView(allOf(isAssignableFrom(ListView.class), isDisplayed()))
+ .check(matches(isDisplayed()));
+
+ // long press the file
+ onData(withDocumentName(FILE_NAME))
+ .inAdapterView(allOf(isAssignableFrom(ListView.class), isDisplayed()))
+ .perform(longClick());
+ onView(withId(R.id.ab_actions)).perform(click());
+ onView(withText(COPY_TO)).perform(click());
+ onView(withText(DROPBOX)).perform(click());
+ onView(withText(COPY)).perform(click());
+
+ // Check file in Dropbox
+ List<StorageProviderInfo> providerInfoList = mActivity.getProviderList();
+ StorageProviderInfo storageProviderInfo = providerInfoList.get(0);
+ String path = StorageApiConsole.constructStorageApiFilePathFromProvider(
+ storageProviderInfo.getRootDocumentId(),
+ StorageApiConsole.getHashCodeFromProvider(storageProviderInfo));
+ mActivity.navigateToPath(path);
+ onData(withDocumentName(FILE_NAME))
+ .inAdapterView(allOf(isAssignableFrom(ListView.class), isDisplayed()))
+ .perform(click());
+ }
+
+ /**
+ * Tests moving a file from local to Dropbox
+ */
+ @Test
+ public void moveFileFromLocalToDropbox() {
+ String FILE_NAME = "LocalFile" + new Random().nextInt();
+ mActivity.navigateToPath(StorageHelper.getLocalStoragePath(mActivity));
+
+ // create a file
+ onView(withContentDescription(MORE_OPTIONS)).perform(click());
+ onView(withText(NEW_FILE)).perform(click());
+ onView(withId(R.id.input_name_dialog_edit)).perform(clearText()).perform(typeText(FILE_NAME));
+ onView(withText(OK)).perform(click());
+ onData(withDocumentName(FILE_NAME))
+ .inAdapterView(allOf(isAssignableFrom(ListView.class), isDisplayed()))
+ .check(matches(isDisplayed()));
+
+ // long press the file
+ onData(withDocumentName(FILE_NAME))
+ .inAdapterView(allOf(isAssignableFrom(ListView.class), isDisplayed()))
+ .perform(longClick());
+ onView(withId(R.id.ab_actions)).perform(click());
+ onView(withText(MOVE_TO)).perform(click());
+ onView(withText(DROPBOX)).perform(click());
+ onView(withText(MOVE)).perform(click());
+
+ // Check not in local storage
+ onView(withId(R.id.navigation_view_layout))
+ .check(matches(not(withAdaptedData(withDocumentName(FILE_NAME)))));
+
+ // Check file in Dropbox
+ List<StorageProviderInfo> providerInfoList = mActivity.getProviderList();
+ StorageProviderInfo storageProviderInfo = providerInfoList.get(0);
+ String path = StorageApiConsole.constructStorageApiFilePathFromProvider(
+ storageProviderInfo.getRootDocumentId(),
+ StorageApiConsole.getHashCodeFromProvider(storageProviderInfo));
+ mActivity.navigateToPath(path);
+ onData(withDocumentName(FILE_NAME))
+ .inAdapterView(allOf(isAssignableFrom(ListView.class), isDisplayed()))
+ .perform(click());
+ }
+
+ /**
+ * Tests copying a file from local to Dropbox
+ */
+ @Test
+ public void copyFileFromDropboxToLocal() throws InterruptedException {
+ String FILE_NAME = "DropboxFile" + new Random().nextInt();
+
+ pauseForProviderToLoad();
+ List<StorageProviderInfo> providerInfoList = mActivity.getProviderList();
+ StorageProviderInfo storageProviderInfo = providerInfoList.get(0);
+ String path = StorageApiConsole.constructStorageApiFilePathFromProvider(
+ storageProviderInfo.getRootDocumentId(),
+ StorageApiConsole.getHashCodeFromProvider(storageProviderInfo));
+ mActivity.navigateToPath(path);
+
+ // create a file
+ onView(withContentDescription(MORE_OPTIONS)).perform(click());
+ onView(withText(NEW_FILE)).perform(click());
+ onView(withId(R.id.input_name_dialog_edit)).perform(clearText()).perform(typeText(FILE_NAME));
+ onView(withText(OK)).perform(click());
+ onData(withDocumentName(FILE_NAME))
+ .inAdapterView(allOf(isAssignableFrom(ListView.class), isDisplayed()))
+ .check(matches(isDisplayed()));
+
+ // long press the file
+ onData(withDocumentName(FILE_NAME))
+ .inAdapterView(allOf(isAssignableFrom(ListView.class), isDisplayed()))
+ .perform(longClick());
+ onView(withId(R.id.ab_actions)).perform(click());
+ onView(withText(COPY_TO)).perform(click());
+ onView(withText(LOCAL_STORAGE)).perform(click());
+ onView(withText(COPY)).perform(click());
+
+ // Check file in local storage
+ mActivity.navigateToPath(StorageHelper.getLocalStoragePath(mActivity));
+ pauseForProviderToLoad();
+ onData(withDocumentName(FILE_NAME))
+ .inAdapterView(allOf(isAssignableFrom(ListView.class), isDisplayed()))
+ .check(matches(isDisplayed()));
+ }
+
+ /**
+ * Tests moving a file from Dropbox to local
+ */
+ @Test
+ public void moveFileFromDropboxToLocal() throws InterruptedException {
+ String FILE_NAME = "DropboxFile" + new Random().nextInt();
+
+ pauseForProviderToLoad();
+ List<StorageProviderInfo> providerInfoList = mActivity.getProviderList();
+ StorageProviderInfo storageProviderInfo = providerInfoList.get(0);
+ String path = StorageApiConsole.constructStorageApiFilePathFromProvider(
+ storageProviderInfo.getRootDocumentId(),
+ StorageApiConsole.getHashCodeFromProvider(storageProviderInfo));
+ mActivity.navigateToPath(path);
+
+ // create a file
+ onView(withContentDescription(MORE_OPTIONS)).perform(click());
+ onView(withText(NEW_FILE)).perform(click());
+ onView(withId(R.id.input_name_dialog_edit)).perform(clearText()).perform(typeText(FILE_NAME));
+ onView(withText(OK)).perform(click());
+ onData(withDocumentName(FILE_NAME))
+ .inAdapterView(allOf(isAssignableFrom(ListView.class), isDisplayed()))
+ .check(matches(isDisplayed()));
+
+ // long press the file
+ onData(withDocumentName(FILE_NAME))
+ .inAdapterView(allOf(isAssignableFrom(ListView.class), isDisplayed()))
+ .perform(longClick());
+ onView(withId(R.id.ab_actions)).perform(click());
+ onView(withText(MOVE_TO)).perform(click());
+ onView(withText(LOCAL_STORAGE)).perform(click());
+ onView(withText(MOVE)).perform(click());
+
+ // Check not in Dropbox
+ onView(withId(R.id.navigation_view_layout))
+ .check(matches(not(withAdaptedData(withDocumentName(FILE_NAME)))));
+
+ // Check file in local storage
+ mActivity.navigateToPath(StorageHelper.getLocalStoragePath(mActivity));
+ pauseForProviderToLoad();
+ onData(withDocumentName(FILE_NAME))
+ .inAdapterView(allOf(isAssignableFrom(ListView.class), isDisplayed()))
+ .check(matches(isDisplayed()));
+ }
+
+ /**
+ * Tests moving a file from Dropbox to local
+ */
+ @Test
+ public void createDeleteFileAndFolderinDropbox() throws InterruptedException {
+ String FILE_NAME = "DropboxFile" + new Random().nextInt();
+ String FOLDER_NAME = "DropboxFile" + new Random().nextInt();
+
+ // open Dropbox Navigation View
+ pauseForProviderToLoad();
+ List<StorageProviderInfo> providerInfoList = mActivity.getProviderList();
+ StorageProviderInfo storageProviderInfo = providerInfoList.get(0);
+ String path = StorageApiConsole.constructStorageApiFilePathFromProvider(
+ storageProviderInfo.getRootDocumentId(),
+ StorageApiConsole.getHashCodeFromProvider(storageProviderInfo));
+ mActivity.navigateToPath(path);
+
+ // create a file
+ onView(withContentDescription(MORE_OPTIONS)).perform(click());
+ onView(withText(NEW_FILE)).perform(click());
+ onView(withId(R.id.input_name_dialog_edit)).perform(clearText()).perform(typeText(FILE_NAME));
+ onView(withText(OK)).perform(click());
+ onData(withDocumentName(FILE_NAME))
+ .inAdapterView(allOf(isAssignableFrom(ListView.class), isDisplayed()))
+ .check(matches(isDisplayed()));
+
+ // create a folder
+ onView(withContentDescription(MORE_OPTIONS)).perform(click());
+ onView(withText(NEW_FOLDER)).perform(click());
+ onView(withId(R.id.input_name_dialog_edit)).perform(clearText()).perform(typeText(FOLDER_NAME));
+ onView(withText(OK)).perform(click());
+ onData(withDocumentName(FOLDER_NAME))
+ .inAdapterView(allOf(isAssignableFrom(ListView.class), isDisplayed()))
+ .check(matches(isDisplayed()));
+
+ // move the file into the folder
+ onData(withDocumentName(FILE_NAME))
+ .inAdapterView(allOf(isAssignableFrom(ListView.class), isDisplayed()))
+ .perform(longClick());
+ onView(withId(R.id.ab_actions)).perform(click());
+ onView(withText(MOVE_TO)).perform(click());
+ onView(withText(DROPBOX)).perform(click());
+ onData(withDocumentName(FOLDER_NAME))
+ .inAdapterView(allOf(isAssignableFrom(ListView.class), isDisplayed()))
+ .perform(click());
+ onView(withText(MOVE)).perform(click());
+
+ // check the file is not in root folder
+ onView(withId(R.id.navigation_view_layout))
+ .check(matches(not(withAdaptedData(withDocumentName(FILE_NAME)))));
+
+ // check the file is moved into the folder
+ onData(withDocumentName(FOLDER_NAME))
+ .inAdapterView(allOf(isAssignableFrom(ListView.class), isDisplayed()))
+ .perform(click());
+ onData(withDocumentName(FILE_NAME))
+ .inAdapterView(allOf(isAssignableFrom(ListView.class), isDisplayed()))
+ .check(matches(isDisplayed()));
+ }
+
+ /**
+ * Returns a Matcher<Object> from a document name which matches FileSystemObject.getName()
+ * @param name
+ * @return Matcher<Object>
+ */
+ public static Matcher<Object> withDocumentName(final String name) {
+ return new BoundedMatcher<Object, FileSystemObject>(FileSystemObject.class) {
+
+ @Override
+ protected boolean matchesSafely(FileSystemObject systemObj) {
+ return name.equals(systemObj.getName());
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("with name: " + name);
+ }
+ };
+ }
+
+ /**
+ * Returns a Matcher<View> asserting that a data item is not in an adapter
+ * @param dataMatcher
+ * @return Matcher<View>
+ */
+ private static Matcher<View> withAdaptedData(final Matcher<Object> dataMatcher) {
+ return new TypeSafeMatcher<View>() {
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("with class name: ");
+ dataMatcher.describeTo(description);
+ }
+
+ @Override
+ public boolean matchesSafely(View view) {
+ if (!(view instanceof AdapterView)) {
+ return false;
+ }
+
+ @SuppressWarnings("rawtypes")
+ Adapter adapter = ((AdapterView) view).getAdapter();
+ for (int i = 0; i < adapter.getCount(); i++) {
+ if (dataMatcher.matches(adapter.getItem(i))) {
+ return true;
+ }
+ }
+ return false;
+ }
+ };
+ }
+
+ private void pauseForProviderToLoad() throws InterruptedException {
+ Thread.sleep(2000); // need time for Activity to initialize getProviderList()
+ }
+}
diff --git a/androidTest/src/com/cyanogenmod/filemanager/activities/WelcomeActivityTest.java b/androidTest/src/com/cyanogenmod/filemanager/activities/WelcomeActivityTest.java
new file mode 100644
index 00000000..7eea3590
--- /dev/null
+++ b/androidTest/src/com/cyanogenmod/filemanager/activities/WelcomeActivityTest.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2015 The CyanogenMod Project
+ *
+ * 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.cyanogenmod.filemanager.activities;
+
+import com.cyanogenmod.filemanager.R;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.app.Activity;
+import android.support.test.espresso.action.ViewActions;
+import android.support.test.espresso.matcher.ViewMatchers;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.widget.TextView;
+
+import static android.support.test.espresso.Espresso.onView;
+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.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static android.support.test.espresso.matcher.ViewMatchers.withText;
+import static android.support.test.espresso.matcher.ViewMatchers.withEffectiveVisibility;
+import static android.support.test.espresso.matcher.ViewMatchers.Visibility;
+
+/**
+ * Basic tests showcasing simple view matchers and actions like {@link ViewMatchers#withId},
+ * {@link ViewActions#click} and {@link ViewActions#typeText}.
+ * <p>
+ * Note that there is no need to tell Espresso that a view is in a different {@link Activity}.
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class WelcomeActivityTest {
+
+ /**
+ * A JUnit {@link Rule @Rule} to launch your activity under test. This is a replacement
+ * for {@link ActivityInstrumentationTestCase2}.
+ * <p>
+ * Rules are interceptors which are executed for each test method and will run before
+ * any of your setup code in the {@link Before @Before} method.
+ * <p>
+ * {@link ActivityTestRule} will create and launch of the activity for you and also expose
+ * the activity under test. To get a reference to the activity you can use
+ * the {@link ActivityTestRule#getActivity()} method.
+ */
+ @Rule
+ public ActivityTestRule<WelcomeActivity> mActivityRule = new ActivityTestRule<>(
+ WelcomeActivity.class);
+
+ /**
+ * This test goes through the welcome screens and tries clicking connect button.
+ */
+ @Test
+ public void testClickConnectCloud() {
+ goThroughWelcomePages();
+ onView(withId(R.id.dismiss_card)).perform(click());
+ onView(withId(R.id.dismiss_card)).check(doesNotExist());
+ }
+
+ /**
+ * This test goes back and forth the welcome, verifying texts and buttons.
+ */
+ @Test
+ public void testClickNextOnWelcomePage() {
+ goThroughWelcomePages();
+
+ onView(withId(R.id.prevButton)).perform(click());
+
+ // Third page, to go back to the second page
+ onView(withId(R.id.nextButton)).check(matches(isDisplayed()));
+ onView(withId(R.id.pagination)).check(matches(isDisplayed()));
+ onView(withId(R.id.prevButton)).perform(click());
+
+ // Second page, to go back to the first page
+ onView(withId(R.id.titleMessageOne)).check(matches(withText(R.string.second_title)));
+ onView(withId(R.id.bottomMessageOne)).check(matches(withText(R.string.first_message)));
+ onView(withId(R.id.nextButton)).check(matches(isDisplayed()));
+ onView(withId(R.id.pagination)).check(matches(isDisplayed()));
+ onView(withId(R.id.prevButton)).perform(click());
+
+ goThroughWelcomePages();
+
+ onView(withId(R.id.nextButton)).perform(click());
+ }
+
+ /**
+ * Helper function.
+ */
+ private void goThroughWelcomePages() {
+ // First page
+ onView(withId(R.id.welcome_textview_0)).check(matches(withText(R.string.welcome_to)));
+ onView(withId(R.id.welcome_textview_1)).check(matches(withText(R.string.file)));
+ onView(withId(R.id.welcome_textview_2)).check(matches(withText(R.string.manager)));
+ onView(withId(R.id.welcome_textview_3)).check(matches(withText(R.string.welcome_desc)));
+ onView(withId(R.id.prevButton)).check(matches(withEffectiveVisibility(Visibility.INVISIBLE)));
+ onView(withId(R.id.pagination)).check(matches(isDisplayed()));
+ onView(withId(R.id.nextButton)).perform(click());
+ // Second page
+ onView(withId(R.id.titleMessageOne)).check(matches(withText(R.string.second_title)));
+ onView(withId(R.id.bottomMessageOne)).check(matches(withText(R.string.first_message)));
+ onView(withId(R.id.prevButton)).check(matches(isDisplayed()));
+ onView(withId(R.id.pagination)).check(matches(isDisplayed()));
+ onView(withId(R.id.nextButton)).perform(click());
+ // Third page
+ onView(withId(R.id.prevButton)).check(matches(isDisplayed()));
+ onView(withId(R.id.pagination)).check(matches(isDisplayed()));
+ onView(withId(R.id.nextButton)).perform(click());
+ // Last page
+ onView(withId(R.id.dismiss_card)).check(matches(withText(R.string.connect_now)));
+ onView(withId(R.id.cardHeaderText)).check(matches(withText(R.string.add_cloud_storage)));
+ onView(withId(R.id.cardChildText)).check(matches(withText(R.string.oobe_add_cloud_storage_desc)));
+ onView(withId(R.id.nextButton)).check(matches(isDisplayed()));
+ onView(withId(R.id.pagination)).check(matches(isDisplayed()));
+ }
+}
diff --git a/src/com/cyanogenmod/filemanager/activities/MainActivity.java b/src/com/cyanogenmod/filemanager/activities/MainActivity.java
index bd86fdef..51726a67 100755
--- a/src/com/cyanogenmod/filemanager/activities/MainActivity.java
+++ b/src/com/cyanogenmod/filemanager/activities/MainActivity.java
@@ -32,6 +32,7 @@ import android.graphics.drawable.StateListDrawable;
import android.net.Uri;
import android.nfc.NfcAdapter;
import android.os.Bundle;
+import android.support.annotation.VisibleForTesting;
import android.support.design.widget.NavigationView;
import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
@@ -425,7 +426,8 @@ public class MainActivity extends ActionBarActivity
}
}
- private boolean isCurrentFragment(FragmentType fragmentType) {
+ @VisibleForTesting
+ protected boolean isCurrentFragment(FragmentType fragmentType) {
if (fragmentType == FragmentType.HOME) {
return getSupportFragmentManager().getFragments().size() <= 0;
} else {