Skip to content

Upload UI tests #2626

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
Mar 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ dependencies {
// Android testing
androidTestImplementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$KOTLIN_VERSION"
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-intents:3.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.1.1'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test:rules:1.1.1'
Expand Down Expand Up @@ -193,6 +194,8 @@ android {
buildConfigField "String", "BOOKMARK_AUTHORITY", "\"fr.free.nrw.commons.bookmarks.contentprovider\""
buildConfigField "String", "BOOKMARK_LOCATIONS_AUTHORITY", "\"fr.free.nrw.commons.bookmarks.locations.contentprovider\""
buildConfigField "String", "COMMIT_SHA", "\"" + getBuildVersion().toString() + "\""
buildConfigField "String", "TEST_USERNAME", "\"" + System.getenv("test_user_name") + "\""
buildConfigField "String", "TEST_PASSWORD", "\"" + System.getenv("test_user_password") + "\""

dimension 'tier'
}
Expand Down Expand Up @@ -223,6 +226,8 @@ android {
buildConfigField "String", "BOOKMARK_AUTHORITY", "\"fr.free.nrw.commons.beta.bookmarks.contentprovider\""
buildConfigField "String", "BOOKMARK_LOCATIONS_AUTHORITY", "\"fr.free.nrw.commons.beta.bookmarks.locations.contentprovider\""
buildConfigField "String", "COMMIT_SHA", "\"" + getBuildVersion().toString() + "\""
buildConfigField "String", "TEST_USERNAME", "\"" + System.getenv("test_user_name") + "\""
buildConfigField "String", "TEST_PASSWORD", "\"" + System.getenv("test_user_password") + "\""

dimension 'tier'
}
Expand Down
211 changes: 211 additions & 0 deletions app/src/androidTest/java/fr/free/nrw/commons/UploadTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
package fr.free.nrw.commons;

import android.Manifest;
import android.app.Activity;
import android.app.Instrumentation.ActivityResult;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Environment;
import android.view.autofill.AutofillManager;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

import androidx.test.espresso.NoMatchingViewException;
import androidx.test.espresso.intent.rule.IntentsTestRule;
import androidx.test.filters.LargeTest;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.rule.ActivityTestRule;
import androidx.test.rule.GrantPermissionRule;
import androidx.test.runner.AndroidJUnit4;
import fr.free.nrw.commons.auth.LoginActivity;
import fr.free.nrw.commons.utils.ConfigUtils;
import timber.log.Timber;

import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.clearText;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.replaceText;
import static androidx.test.espresso.action.ViewActions.typeText;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.intent.Intents.intended;
import static androidx.test.espresso.intent.Intents.intending;
import static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction;
import static androidx.test.espresso.intent.matcher.IntentMatchers.hasType;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withParent;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.core.AllOf.allOf;

@LargeTest
@RunWith(AndroidJUnit4.class)
public class UploadTest {
@Rule
public GrantPermissionRule permissionRule = GrantPermissionRule.grant(Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.ACCESS_FINE_LOCATION);

@Rule
public ActivityTestRule activityRule = new IntentsTestRule<>(LoginActivity.class);

@Before
public void setup() {

saveToInternalStorage();
}

private void saveToInternalStorage() {
Bitmap bitmapImage = getRandomBitmap();
Context applicationContext = InstrumentationRegistry.getInstrumentation().getTargetContext().getApplicationContext();
ContextWrapper cw = new ContextWrapper(applicationContext);
// path to /data/data/yourapp/app_data/imageDir
File mypath = new File(Environment.getExternalStorageDirectory(), "image.jpg");

Timber.d("Filepath: %s", mypath.getPath());

Timber.d("Absolute Filepath: %s", mypath.getAbsolutePath());

FileOutputStream fos = null;
try {
fos = new FileOutputStream(mypath);
// Use the compress method on the BitMap object to write image to the OutputStream
bitmapImage.compress(Bitmap.CompressFormat.JPEG, 100, fos);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (fos != null) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

private Bitmap getRandomBitmap() {
Random random = new Random();
Bitmap bitmap = Bitmap.createBitmap(200, 200, Bitmap.Config.ARGB_8888);
bitmap.eraseColor(random.nextInt(255));
return bitmap;
}

private void getToMainActivity() {
try {
//Skip tutorial
onView(withId(R.id.finishTutorialButton))
.perform(click());

//Perform Login
onView(withId(R.id.loginUsername))
.perform(clearText(), typeText(BuildConfig.TEST_USERNAME));
onView(withId(R.id.loginPassword))
.perform(clearText(), typeText(BuildConfig.TEST_PASSWORD));
onView(withId(R.id.loginButton))
.perform(click());
} catch (NoMatchingViewException ignored) {
}
}

@Test
public void uploadTest() {
if (!ConfigUtils.isBetaFlavour()) {
throw new Error("This test should only be run in Beta!");
}

getToMainActivity();

// Uri to return by our mock gallery selector
// Requires file 'image.jpg' to be placed at root of file structure
Uri imageUri = Uri.parse("file://mnt/sdcard/image.jpg");

// Build a result to return from the Camera app
Intent intent = new Intent();
intent.setData(imageUri);
ActivityResult result = new ActivityResult(Activity.RESULT_OK, intent);

// Stub out the File picker. When an intent is sent to the File picker, this tells
// Espresso to respond with the ActivityResult we just created
intending(allOf(hasAction(Intent.ACTION_GET_CONTENT), hasType("image/*"))).respondWith(result);

// Open FAB
onView(allOf(withId(R.id.fab_plus), isDisplayed()))
.perform(click());

// Click gallery
onView(allOf(withId(R.id.fab_gallery), isDisplayed()))
.perform(click());

// Validate that an intent to get an image is sent
intended(allOf(hasAction(Intent.ACTION_GET_CONTENT), hasType("image/*")));

// Create filename with the current time (to prevent overwrites)
SimpleDateFormat dateFormat = new SimpleDateFormat("yyMMdd-hhmmss");
String commonsFileName = "MobileTest " + dateFormat.format(new Date());

// Try to dismiss the error, if there is one (probably about duplicate files on Commons)
try {
onView(withText("Yes"))
.check(matches(isDisplayed()))
.perform(click());
} catch (NoMatchingViewException ignored) {}

onView(allOf(withId(R.id.description_item_edit_text), withParent(withParent(withId(R.id.image_title_container)))))
.perform(replaceText(commonsFileName));

onView(withId(R.id.bottom_card_next))
.perform(click());

try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}

onView(withId(R.id.category_search))
.perform(replaceText("Uploaded with Mobile/Android Tests"));

try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}

onView(withParent(withId(R.id.categories)))
.perform(click());

onView(withId(R.id.category_next))
.perform(click());

try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}

onView(withId(R.id.submit))
.perform(click());

try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}

String fileUrl = "https://commons.wikimedia.beta.wmflabs.org/wiki/File:" +
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we enhance this bit as well? We can probably call media wiki api to assert if the image was uploaded.

commonsFileName.replace(' ', '_') + ".jpg";
Timber.i("File should be uploaded to " + fileUrl);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,6 @@
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import com.google.android.material.tabs.TabLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.core.view.GravityCompat;
import androidx.viewpager.widget.ViewPager;
import androidx.drawerlayout.widget.DrawerLayout;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
Expand All @@ -20,18 +13,24 @@
import android.widget.ImageView;
import android.widget.TextView;

import com.google.android.material.tabs.TabLayout;

import java.util.List;

import javax.inject.Inject;
import javax.inject.Named;

import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.viewpager.widget.ViewPager;
import butterknife.BindView;
import butterknife.ButterKnife;
import fr.free.nrw.commons.BuildConfig;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.auth.AuthenticatedActivity;
import fr.free.nrw.commons.auth.SessionManager;
import fr.free.nrw.commons.kvstore.JsonKvStore;
import fr.free.nrw.commons.location.LocationServiceManager;
import fr.free.nrw.commons.nearby.NearbyFragment;
import fr.free.nrw.commons.nearby.NearbyNotificationCardView;
Expand Down Expand Up @@ -464,6 +463,7 @@ private void updateContributionFragmentTabContent(boolean isContributionsListFra

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Timber.d(data.toString());
super.onActivityResult(requestCode, resultCode, data);
controller.handleActivityResult(this, requestCode, resultCode, data);
}
Expand Down