Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/develop' into pr-361-trace-to-gh
Browse files Browse the repository at this point in the history
  • Loading branch information
miltonials committed Nov 25, 2024
2 parents 9f555ee + 803f57c commit aad41c2
Show file tree
Hide file tree
Showing 10 changed files with 169 additions and 35 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ dependencies {

// Required for instrumented tests
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
androidTestImplementation 'androidx.test:rules:1.4.0'

implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import net.osmtracker.activity.ButtonsPresets;
import net.osmtracker.activity.Preferences;
import net.osmtracker.util.CustomLayoutsUtils;
import net.osmtracker.util.TestUtils;

import org.junit.Rule;
import org.junit.Test;
Expand All @@ -20,6 +21,7 @@
import static androidx.test.espresso.action.ViewActions.longClick;
import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static net.osmtracker.util.LogcatHelper.checkLogForMessage;
import static net.osmtracker.util.TestUtils.checkToastIsShownWith;
import static net.osmtracker.util.TestUtils.getLayoutsDirectory;
import static net.osmtracker.util.TestUtils.getStringResource;
Expand Down Expand Up @@ -47,10 +49,6 @@ protected void beforeActivityLaunched() {
}
};

// Storage permissions are required
@Rule
public GrantPermissionRule writePermission = GrantPermissionRule.grant(Manifest.permission.WRITE_EXTERNAL_STORAGE);

private static String layoutName = "mock";
private static String ISOLanguageCode = "es";

Expand All @@ -77,6 +75,8 @@ public void layoutDeletionTest(){

deleteLayout(layoutName);

checkLogForMessage("TOAST", TestUtils.getStringResource(R.string.buttons_presets_successful_delete));

// Check the informative Toast is shown
checkToastIsShownWith(getStringResource(R.string.buttons_presets_successful_delete));

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,28 @@
package net.osmtracker.layouts;

import static androidx.test.espresso.Espresso.onData;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.scrollTo;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.PreferenceMatchers.withTitleText;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.isRoot;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static junit.framework.TestCase.fail;
import static net.osmtracker.util.LogcatHelper.checkLogForMessage;
import static net.osmtracker.util.WaitForView.waitForView;

import android.Manifest;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;

import androidx.test.espresso.Espresso;
import androidx.test.espresso.assertion.ViewAssertions;
import androidx.test.rule.ActivityTestRule;
import androidx.test.rule.GrantPermissionRule;

import net.osmtracker.OSMTracker;
import net.osmtracker.R;
Expand All @@ -18,19 +35,19 @@

import java.util.Locale;

import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static androidx.test.espresso.Espresso.onData;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.scrollTo;
import static androidx.test.espresso.matcher.PreferenceMatchers.withTitleText;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static junit.framework.TestCase.fail;

public class DownloadLayoutTest {

private final int WAIT_VIEW_TIMEOUT = 5000;

@Rule
public GrantPermissionRule fineLocationPermission = GrantPermissionRule.grant(Manifest.permission.ACCESS_FINE_LOCATION);
@Rule
public GrantPermissionRule coarseLocationPermission = GrantPermissionRule.grant(Manifest.permission.ACCESS_COARSE_LOCATION);
@Rule
public GrantPermissionRule backgroundLocationPermission = GrantPermissionRule.grant(Manifest.permission.ACCESS_BACKGROUND_LOCATION);
@Rule
public GrantPermissionRule serviceLocationPermission = GrantPermissionRule.grant(Manifest.permission.FOREGROUND_SERVICE_LOCATION);

@Rule
public ActivityTestRule<TrackManager> mRule = new ActivityTestRule(TrackManager.class) {
@Override
Expand Down Expand Up @@ -71,13 +88,16 @@ public void deleteLayoutsDirectory(){
/**
* Assuming being in TrackManager
*/
public void navigateToAvailableLayouts(){
public void navigateToAvailableLayouts() {
// Open options menu in the Action Bar
openActionBarOverflowOrOptionsMenu(getInstrumentation().getTargetContext());

// Click on "Settings" in this menu
onView(withText(TestUtils.getStringResource(R.string.menu_settings))).perform(click());

// Click on "Buttons presets" settings
onData(withTitleText(TestUtils.getStringResource(R.string.prefs_ui_buttons_layout))).perform(scrollTo(), click());

// Wait for "+" to be visible
onView(isRoot()).perform(waitForView(R.id.launch_available, WAIT_VIEW_TIMEOUT));
// Perform a click action on the "+" button
onView(withId(R.id.launch_available)).perform(click());
}

Expand All @@ -91,7 +111,7 @@ private void makePostDownloadAssertions(String layoutName) {
Espresso.pressBack();

// Check the layout appears as a new option in AvailableLayouts
onView(withText(layoutName.toLowerCase())).check(ViewAssertions.matches(isDisplayed()));
onView(withText(layoutName.toLowerCase())).check(matches(isDisplayed()));

// Select the layout
onView(withText(layoutName.toLowerCase())).perform(click());
Expand All @@ -104,7 +124,7 @@ private void makePostDownloadAssertions(String layoutName) {
// Check the buttons are loaded correctly
String expectedButtonsLabels[] = new String[]{"A", "B", "C"};
for(String label : expectedButtonsLabels)
onView(withText(label)).check(ViewAssertions.matches(isDisplayed()));
onView(withText(label)).check(matches(isDisplayed()));

}

Expand All @@ -120,6 +140,8 @@ private void clickButtonsToDownloadLayout(String layoutName) {
onView(withText(TestUtils.getStringResource(R.string.available_layouts_description_dialog_positive_confirmation))).
perform(click());

checkLogForMessage("TOAST", TestUtils.getStringResource(R.string.available_layouts_successful_download));

TestUtils.checkToastIsShownWith(TestUtils.getStringResource(R.string.available_layouts_successful_download));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import net.osmtracker.OSMTracker;
import net.osmtracker.R;
import net.osmtracker.activity.AvailableLayouts;
import net.osmtracker.util.TestUtils;

import org.hamcrest.Matcher;
import org.junit.Rule;
Expand All @@ -23,6 +24,7 @@
import static androidx.test.espresso.matcher.ViewMatchers.isEnabled;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static net.osmtracker.util.LogcatHelper.checkLogForMessage;
import static net.osmtracker.util.TestUtils.checkToastIsShownWith;
import static net.osmtracker.util.TestUtils.getStringResource;
import static org.hamcrest.core.IsNot.not;
Expand Down Expand Up @@ -80,6 +82,8 @@ public void checkRepositoryValidity(String user, String repo, String branch, boo
String expectedMessage = (isValid) ? getStringResource(R.string.github_repository_settings_valid_server) :
getStringResource(R.string.github_repository_settings_invalid_server);

checkLogForMessage("TOAST", expectedMessage);

checkToastIsShownWith(expectedMessage);

ViewAssertion expectedDialogState = (isValid) ? doesNotExist() : matches(isDisplayed());
Expand Down
29 changes: 29 additions & 0 deletions app/src/androidTest/java/net/osmtracker/util/LogcatHelper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package net.osmtracker.util;

import android.util.Log;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.regex.Pattern;

public class LogcatHelper {

public static boolean checkLogForMessage(String tag, String message) {
try {
Process process = Runtime.getRuntime().exec("logcat -d " + tag + ":I *:S");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));

String line;
Pattern pattern = Pattern.compile(".*\\b" + Pattern.quote(message) + "\\b.*");

while ((line = bufferedReader.readLine()) != null) {
if (pattern.matcher(line).matches()) {
return true;
}
}
} catch (Exception e) {
Log.e("LogcatHelper", "Error reading logcat output", e);
}

return false;
}
}
9 changes: 7 additions & 2 deletions app/src/androidTest/java/net/osmtracker/util/TestUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import android.content.Context;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Environment;
import android.preference.PreferenceManager;
import androidx.test.platform.app.InstrumentationRegistry;
Expand Down Expand Up @@ -118,8 +119,12 @@ public static File getLayoutsDirectory(){
}

public static void checkToastIsShownWith(String text){
onView(withText(text)).inRoot(new ToastMatcher())
.check(matches(isDisplayed()));
// Espresso can not check Toast for android >= 11
// https://github.com/android/android-test/issues/803
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
onView(withText(text)).inRoot(new ToastMatcher())
.check(matches(isDisplayed()));
}
}

public static String getStringResource(int resourceId){
Expand Down
65 changes: 65 additions & 0 deletions app/src/androidTest/java/net/osmtracker/util/WaitForView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package net.osmtracker.util;

import android.view.View;
import androidx.test.espresso.PerformException;
import androidx.test.espresso.UiController;
import androidx.test.espresso.ViewAction;
import androidx.test.espresso.matcher.ViewMatchers;
import androidx.test.espresso.util.HumanReadables;
import androidx.test.espresso.util.TreeIterables;

import org.hamcrest.Matcher;

import java.util.concurrent.TimeoutException;

public class WaitForView implements ViewAction {
private final int viewId;
private final long timeout;

/**
* This ViewAction tells espresso to wait till a certain view is found in the view hierarchy.
* @param viewId The id of the view to wait for.
* @param timeout The maximum time which espresso will wait for the view to show up (in milliseconds)
*/
public WaitForView(int viewId, long timeout) {
this.viewId = viewId;
this.timeout = timeout;
}

@Override
public Matcher<View> getConstraints() {
return ViewMatchers.isRoot();
}

@Override
public String getDescription() {
return "wait for a specific view with id " + viewId + " during " + timeout + " millis.";
}

@Override
public void perform(UiController uiController, View rootView) {
uiController.loopMainThreadUntilIdle();
long startTime = System.currentTimeMillis();
long endTime = startTime + timeout;
Matcher<View> viewMatcher = ViewMatchers.withId(viewId);

do {
for (View child : TreeIterables.breadthFirstViewTraversal(rootView)) {
if (viewMatcher.matches(child)) {
return;
}
}
uiController.loopMainThreadForAtLeast(100);
} while (System.currentTimeMillis() < endTime);

throw new PerformException.Builder()
.withCause(new TimeoutException())
.withActionDescription(this.getDescription())
.withViewDescription(HumanReadables.describe(rootView))
.build();
}

public static ViewAction waitForView(final int viewId, final long timeout) {
return new WaitForView(viewId, timeout);
}
}
10 changes: 8 additions & 2 deletions app/src/main/java/net/osmtracker/activity/AvailableLayouts.java
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,9 @@ public void onClick(DialogInterface dialog, int which) {
protected void onPostExecute(Boolean result){
//validating the github repository
if(result){
Toast.makeText(AvailableLayouts.this, getResources().getString(R.string.github_repository_settings_valid_server), Toast.LENGTH_SHORT).show();
String message = getResources().getString(R.string.github_repository_settings_valid_server);
Log.i("TOAST", message);
Toast.makeText(AvailableLayouts.this, message, Toast.LENGTH_SHORT).show();
//save the entered options into the shared preferences file
editor.putString(OSMTracker.Preferences.KEY_GITHUB_USERNAME, repositoryCustomOptions[0]);
editor.putString(OSMTracker.Preferences.KEY_REPOSITORY_NAME, repositoryCustomOptions[1]);
Expand All @@ -257,7 +259,9 @@ protected void onPostExecute(Boolean result){
tmpSharedPref.edit().putBoolean("isCallBack", false).commit();
retrieveAvailableLayouts();
}else{
Toast.makeText(AvailableLayouts.this, getResources().getString(R.string.github_repository_settings_invalid_server), Toast.LENGTH_SHORT).show();
String message = getResources().getString(R.string.github_repository_settings_invalid_server);
Log.e("TOAST", message);
Toast.makeText(AvailableLayouts.this, message, Toast.LENGTH_SHORT).show();
tmpSharedPref.edit().putString(OSMTracker.Preferences.KEY_GITHUB_USERNAME, repositoryCustomOptions[0]).commit();
tmpSharedPref.edit().putString(OSMTracker.Preferences.KEY_REPOSITORY_NAME, repositoryCustomOptions[1]).commit();
tmpSharedPref.edit().putString(OSMTracker.Preferences.KEY_BRANCH_NAME, repositoryCustomOptions[2]).commit();
Expand Down Expand Up @@ -492,9 +496,11 @@ protected void onPostExecute(Boolean status){
String message="";
if (status) {
message = getResources().getString(R.string.available_layouts_successful_download);
Log.i("TOAST", message);
}
else {
message = getResources().getString(R.string.available_layouts_unsuccessful_download);
Log.e("TOAST", message);
}
Toast.makeText(getApplicationContext(),message,Toast.LENGTH_LONG).show();
dialog.dismiss();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,8 +285,11 @@ public void onClick(DialogInterface dialog, int which) {

int messageToShowId = (successfulDeletion) ? R.string.buttons_presets_successful_delete :
R.string.buttons_presets_unsuccessful_delete;
String message = getResources().getString(messageToShowId);

Toast.makeText(getApplicationContext(), getResources().getString(messageToShowId), Toast.LENGTH_SHORT).show();
Log.println(successfulDeletion ? Log.INFO : Log.ERROR, "TOAST", message);

Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();

//reload the activity
refreshActivity();
Expand Down
12 changes: 6 additions & 6 deletions app/src/main/res/values-pl/strings-preferences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@
</string-array>
<string name="prefs_ui_buttons_layout">Układ przycisków</string>
<string name="prefs_ui_buttons_layout_summary">Wybierz własny układ przycisków (zobacz dokumentację)</string>
<string name="prefs_ui_buttons_layout_default_section">DOMYŚLNY LAYOUT</string>
<string name="prefs_ui_buttons_layout_default_section">UKŁAD DOMYŚLNY</string>
<string name="prefs_ui_buttons_layout_defaut">Domyślnie</string>
<string name="prefs_ui_buttons_layout_downloaded_section">POBRANY LAYOUT</string>
<string name="prefs_ui_buttons_layout_empty_section">Nie masz pobranych plików z layout-ami</string>
<string name="prefs_ui_available_layout">Dostępne Layout-y</string>
<string name="prefs_ui_buttons_layout_downloaded_section">POBRANY UKŁAD</string>
<string name="prefs_ui_buttons_layout_empty_section">Nie masz pobranych plików układu</string>
<string name="prefs_ui_available_layout">Dostępne układy</string>
<string name="prefs_ui_github_repository_settings">Ustawienia repozytorium Github</string>
<string name="prefs_ui_orientation">Orientacja</string>
<string name="prefs_ui_orientation_summary">Preferowana orientacja przycisków na ekranie</string>
Expand All @@ -56,9 +56,9 @@
<string name="prefs_displaytrack_osm_summary">Włącza mapy OSM w podglądzie śladu. Wymaga aktywnego połączenia z Internetem.</string>
<string name="prefs_displaytrack_osm_summary_ask">Wyświetlać zawsze tło OpenStreetMap? Wymaga połączenia z internetem</string>
<string name="prefs_output">Ustawienia GPX</string>
<string name="prefs_storage_dir">Folder na karcie pamięci</string>
<string name="prefs_storage_dir">Katalog przechowywania w dokumentach</string>
<string name="prefs_storage_dir_hint">Zmiana zadziała przy następnym śladzie</string>
<string name="prefs_output_one_dir_per_track">Osobny folder dla każdego śladu</string>
<string name="prefs_output_one_dir_per_track">Osobny katalog dla każdego śladu</string>
<string name="prefs_output_one_dir_per_track_summary">Zapisuje każdy ślad wraz z powiązanymi plikami w oddzielnych folderach</string>
<string name="prefs_output_filename">Nazwy plików śladów</string>
<string name="prefs_output_filename_summary">Schemat dla nazwanych śladów</string>
Expand Down

0 comments on commit aad41c2

Please sign in to comment.