diff --git a/.github/workflows/android_tests.yml b/.github/workflows/android_tests.yml index ef0f030a7..d95fe639c 100644 --- a/.github/workflows/android_tests.yml +++ b/.github/workflows/android_tests.yml @@ -75,8 +75,9 @@ jobs: disk-size: 500M # needed for saving org and json files force-avd-creation: false # it's picky on the parameters - emulator-options: -no-boot-anim -no-window -accel on # -gpu host + emulator-options: -no-boot-anim -no-window disable-animations: true + disable-spellchecker: true # starts the emulator, runs this script, then closes the emulator script: | # wait for it to finish booting, then take a screenshot @@ -106,8 +107,9 @@ jobs: disk-size: 500M force-avd-creation: false disable-animations: true - # -gpu swiftshader_indirect - emulator-options: -no-snapshot-save -verbose -no-boot-anim -no-window + disable-spellchecker: true + # TODO test -gpu host + emulator-options: -no-snapshot-save -verbose -no-boot-anim -no-window -accel on # -gpu host script: bash ./github_on_emu_started.sh - name: upload the generated files diff --git a/app/src/androidTest/java/com/nononsenseapps/notepad/espresso_tests/EspressoHelper.java b/app/src/androidTest/java/com/nononsenseapps/notepad/espresso_tests/EspressoHelper.java index cee154652..2564695b2 100644 --- a/app/src/androidTest/java/com/nononsenseapps/notepad/espresso_tests/EspressoHelper.java +++ b/app/src/androidTest/java/com/nononsenseapps/notepad/espresso_tests/EspressoHelper.java @@ -5,6 +5,7 @@ import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard; import static androidx.test.espresso.action.ViewActions.typeText; import static androidx.test.espresso.assertion.ViewAssertions.matches; +import static androidx.test.espresso.matcher.RootMatchers.isDialog; import static androidx.test.espresso.matcher.ViewMatchers.isClickable; import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; import static androidx.test.espresso.matcher.ViewMatchers.isRoot; @@ -16,6 +17,7 @@ import android.app.UiAutomation; import android.os.SystemClock; +import androidx.annotation.IdRes; import androidx.test.espresso.AmbiguousViewMatcherException; import androidx.test.espresso.Espresso; import androidx.test.espresso.ViewInteraction; @@ -107,20 +109,29 @@ public static void createTaskList(String taskListName) { } // TODO regularly crashes here in the google_apis - API23 emulator image - onView(withId(R.id.titleField)).check(matches(isDisplayed())); + onViewWithIdInDialog(R.id.titleField).check(matches(isDisplayed())); // fill the popup - onView(withId(R.id.titleField)).perform(typeText(taskListName)); - onView(withId(R.id.dialog_yes)).check(matches(isDisplayed())); - onView(withId(R.id.dialog_yes)).perform(click()); + onViewWithIdInDialog(R.id.titleField).perform(typeText(taskListName)); + onViewWithIdInDialog(R.id.dialog_yes).check(matches(isDisplayed())); + onViewWithIdInDialog(R.id.dialog_yes).perform(click()); try { // check if the dialog is still visible (it shouldn't be) - onView(withId(R.id.dialog_yes)).check(matches(not(isDisplayed()))); + onViewWithIdInDialog(R.id.dialog_yes).check(matches(not(isDisplayed()))); } catch (Exception ex) { NnnLogger.exception(ex); } } + /** + * shorthand for onView(withId(viewId)).inRoot(isDialog()) + * + * @param viewId it's R.id.something + */ + public static ViewInteraction onViewWithIdInDialog(@IdRes int viewId) { + return onView(withId(viewId)).inRoot(isDialog()); + } + /** * @return TRUE if the app is in tablet mode, FALSE in phone mode */ diff --git a/app/src/androidTest/java/com/nononsenseapps/notepad/espresso_tests/TestPasswords.java b/app/src/androidTest/java/com/nononsenseapps/notepad/espresso_tests/TestPasswords.java index af25383ba..3e0a4dbe3 100644 --- a/app/src/androidTest/java/com/nononsenseapps/notepad/espresso_tests/TestPasswords.java +++ b/app/src/androidTest/java/com/nononsenseapps/notepad/espresso_tests/TestPasswords.java @@ -5,6 +5,7 @@ import static androidx.test.espresso.action.ViewActions.click; import static androidx.test.espresso.action.ViewActions.typeText; import static androidx.test.espresso.assertion.ViewAssertions.matches; +import static androidx.test.espresso.matcher.RootMatchers.isDialog; import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; import static androidx.test.espresso.matcher.ViewMatchers.withId; import static androidx.test.espresso.matcher.ViewMatchers.withText; @@ -44,11 +45,13 @@ public void testAddNoteLockWithPassword() { onView(withId(R.id.passwordVerificationField)).perform(typeText(password)); onView(withId(R.id.dialog_yes)).perform(click()); + EspressoHelper.waitUi(); // then it opens the popup again, to ask the password - onView(withId(R.id.passwordField)).perform(typeText(password)); - onView(withId(R.id.dialog_yes)).check(matches(isDisplayed())); - onView(withId(R.id.dialog_yes)).perform(click()); + EspressoHelper.onViewWithIdInDialog(R.id.passwordField).check(matches(isDisplayed())); + EspressoHelper.onViewWithIdInDialog(R.id.passwordField).perform(typeText(password)); + EspressoHelper.onViewWithIdInDialog(R.id.dialog_yes).check(matches(isDisplayed())); + EspressoHelper.onViewWithIdInDialog(R.id.dialog_yes).perform(click()); // the note on the (custom) edittext should appear correctly onView(withId(R.id.taskText)).check(matches(withText(fullNoteText1))); diff --git a/app/src/androidTest/java/com/nononsenseapps/notepad/espresso_tests/TestSaveLoadJsonBackup.java b/app/src/androidTest/java/com/nononsenseapps/notepad/espresso_tests/TestSaveLoadJsonBackup.java index c6a67df1e..b20891f2a 100644 --- a/app/src/androidTest/java/com/nononsenseapps/notepad/espresso_tests/TestSaveLoadJsonBackup.java +++ b/app/src/androidTest/java/com/nononsenseapps/notepad/espresso_tests/TestSaveLoadJsonBackup.java @@ -6,6 +6,7 @@ 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.RootMatchers.isDialog; import static androidx.test.espresso.matcher.ViewMatchers.hasChildCount; import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; import static androidx.test.espresso.matcher.ViewMatchers.withId; @@ -65,8 +66,8 @@ public void testSaveLoadBackup() { openContextualActionModeOverflowMenu(); String CLEAR_COMPLETED = getStringResource(R.string.menu_clearcompleted); onView(withText(CLEAR_COMPLETED)).perform(click()); - onView(withId(android.R.id.button1)).check(matches(isDisplayed())); - onView(withId(android.R.id.button1)).perform(click()); + onView(withId(android.R.id.button1)).inRoot(isDialog()).check(matches(isDisplayed())); + onView(withId(android.R.id.button1)).inRoot(isDialog()).perform(click()); // restore the backup openContextualActionModeOverflowMenu(); diff --git a/app/src/androidTest/java/com/nononsenseapps/notepad/test/DBProviderTest.java b/app/src/androidTest/java/com/nononsenseapps/notepad/test/DBProviderTest.java index 589897c89..85b0766db 100644 --- a/app/src/androidTest/java/com/nononsenseapps/notepad/test/DBProviderTest.java +++ b/app/src/androidTest/java/com/nononsenseapps/notepad/test/DBProviderTest.java @@ -44,6 +44,8 @@ private void assertUriReturnsResult(final Uri uri, final String[] fields) { private void assertUriReturnsResult(final Uri uri, final String[] fields, final String where, final String[] whereArgs, final int count) { final Cursor c = mResolver.query(uri, fields, where, whereArgs, null); + NnnLogger.warning(DBProviderTest.class, + "'parameter' count = " + count + ", cursorCount = " + c.getCount()); if (count != c.getCount()) { // will crash. Let's get more info try { diff --git a/app/src/main/java/com/nononsenseapps/notepad/sync/orgsync/OrgSyncService.java b/app/src/main/java/com/nononsenseapps/notepad/sync/orgsync/OrgSyncService.java index afe665cb5..02ee73ff8 100644 --- a/app/src/main/java/com/nononsenseapps/notepad/sync/orgsync/OrgSyncService.java +++ b/app/src/main/java/com/nononsenseapps/notepad/sync/orgsync/OrgSyncService.java @@ -17,33 +17,25 @@ package com.nononsenseapps.notepad.sync.orgsync; -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; import android.app.Service; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.database.ContentObserver; import android.net.Uri; -import android.os.Build; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.Process; -import android.util.Log; -import androidx.core.app.NotificationCompat; import androidx.preference.PreferenceManager; import com.nononsenseapps.helpers.NnnLogger; -import com.nononsenseapps.helpers.NotificationHelper; import com.nononsenseapps.notepad.BuildConfig; import com.nononsenseapps.notepad.database.Task; import com.nononsenseapps.notepad.database.TaskList; -import com.nononsenseapps.notepad.prefs.PrefsActivity; import com.nononsenseapps.notepad.prefs.SyncPrefs; import com.nononsenseapps.notepad.sync.SyncAdapter; @@ -70,17 +62,25 @@ public class OrgSyncService extends Service { private final ArrayList synchronizers; public static void start(Context context) { + NnnLogger.debug(OrgSyncService.class, "got here #1"); context.startService(new Intent(context, OrgSyncService.class) // TODO startservice. does this work correctly in newer android versions ? .setAction(ACTION_START)); + NnnLogger.debug(OrgSyncService.class, "got here #2"); } + // TODO this service crashes in API 23 - default image on github + public static void pause(Context context) { + NnnLogger.debug(OrgSyncService.class, "got here #3"); context.startService(new Intent(context, OrgSyncService.class) // TODO startservice. does this work correctly in newer android versions ? .setAction(ACTION_PAUSE)); + NnnLogger.debug(OrgSyncService.class, "got here #4"); } public static void stop(Context context) { + NnnLogger.debug(OrgSyncService.class, "got here #5"); context.stopService(new Intent(context, OrgSyncService.class)); + NnnLogger.debug(OrgSyncService.class, "got here #6"); } public static boolean areAnyEnabled(Context context) {