Skip to content

test(GradeNowDialog): add UI tests for the GradeNowDialog.kt#20445

Merged
david-allison merged 1 commit intoankidroid:mainfrom
BinaryBhaskar:gradeNowDialogTests
Mar 16, 2026
Merged

test(GradeNowDialog): add UI tests for the GradeNowDialog.kt#20445
david-allison merged 1 commit intoankidroid:mainfrom
BinaryBhaskar:gradeNowDialogTests

Conversation

@BinaryBhaskar
Copy link
Copy Markdown
Contributor

@BinaryBhaskar BinaryBhaskar commented Mar 12, 2026

Purpose / Description

GradeNowDialog needed some unit tests to be implemented to check if UI handling and menu displaying with options work as intended.

Fixes

@NeedsTest in the GradeNowDialog.kt file, a part of issue no. #13283

Approach

Adds Unit Tests for the following:

  • Dialog loads Properly
  • Dialog options (Easy, Good, Hard, Again) show up
  • Clicking an option correctly suspends the dialog
  • Dialog to not be shows if any card isn't selected
    Removed @NeedsTest from GradeNowDialog.kt

How Has This Been Tested?

Emulator: Android Studio Pixel 9 Pro

Checklist

Please, go through these checks before submitting the PR.

  • You have a descriptive commit message with a short title (first line, max 50 chars).
  • You have commented your code, particularly in hard-to-understand areas
  • You have performed a self-review of your own code
  • UI changes: include screenshots of all affected screens (in particular showing any new or changed strings)
  • UI Changes: You have tested your change using the Google Accessibility Scanner

Copilot AI review requested due to automatic review settings March 12, 2026 04:10
@welcome
Copy link
Copy Markdown

welcome Bot commented Mar 12, 2026

First PR! 🚀 We sincerely appreciate that you have taken the time to propose a change to AnkiDroid! Please have patience with us as we are all volunteers - we will get to this as soon as possible.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds Android instrumentation coverage for GradeNowDialog and removes the corresponding @NeedsTest markers in production code.

Changes:

  • Removed @NeedsTest annotations from GradeNowDialog.kt.
  • Added GradeNowDialogTest instrumentation tests for dialog visibility and basic interactions.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
AnkiDroid/src/main/java/com/ichi2/anki/dialogs/GradeNowDialog.kt Removes @NeedsTest markers previously tracking missing UI coverage.
AnkiDroid/src/androidTest/java/com/ichi2/anki/dialogs/GradeNowDialogTest.kt Adds Espresso tests for dialog title/options visibility, click-to-dismiss, and empty-selection behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread AnkiDroid/src/androidTest/java/com/ichi2/anki/dialogs/GradeNowDialogTest.kt Outdated
Comment thread AnkiDroid/src/androidTest/java/com/ichi2/anki/dialogs/GradeNowDialogTest.kt Outdated
Comment thread AnkiDroid/src/main/java/com/ichi2/anki/dialogs/GradeNowDialog.kt
@BinaryBhaskar BinaryBhaskar force-pushed the gradeNowDialogTests branch 2 times, most recently from 7f794d9 to 536df18 Compare March 12, 2026 05:21
Copy link
Copy Markdown
Member

@david-allison david-allison left a comment

Choose a reason for hiding this comment

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

We use unit tests, typically with Robolectric by default, could you move these tests to /test instead of /androidTest

@BinaryBhaskar
Copy link
Copy Markdown
Contributor Author

We use unit tests, typically with Robolectric by default, could you move these tests to /test instead of /androidTest

working on it.

Any other suggestions would be helpful as I don't have much experience with tests.

@david-allison david-allison added the Needs Author Reply Waiting for a reply from the original author label Mar 12, 2026
@DoomsCoder
Copy link
Copy Markdown
Contributor

Hi @BinaryBhaskar 👋

I noticed this pr is related to the @NeedsTest issue (#13283 ) but the issue number isn't mentioned in the PR description.
Could you please link the issue (For example: Related to #13283 ) so it's helps track issue the PR resolves, and it's good practice for future PRs. Thanks!

@BinaryBhaskar
Copy link
Copy Markdown
Contributor Author

Hi @BinaryBhaskar 👋

I noticed this pr is related to the @NeedsTest issue (#13283 ) but the issue number isn't mentioned in the PR description. Could you please link the issue (For example: Related to #13283 ) so it's helps track issue the PR resolves, and it's good practice for future PRs. Thanks!

Thanks for the suggestion. ❤️

@BinaryBhaskar
Copy link
Copy Markdown
Contributor Author

@david-allison
I've made the changes and pushed on a rebase commit, please review it.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread AnkiDroid/src/test/java/com/ichi2/anki/dialogs/GradeNowDialogTest.kt Outdated
Comment thread AnkiDroid/src/test/java/com/ichi2/anki/dialogs/GradeNowDialogTest.kt Outdated
@DoomsCoder
Copy link
Copy Markdown
Contributor

Hi @BinaryBhaskar 👋

I noticed the failing check seems to be in the Codecov step, and the logs show a GPG verification error (Can't check signature: No public Key).

Not sure if its related to the changes , but sometimes rerunning the workflow or pushing an empty commit can fix it.

@BinaryBhaskar
Copy link
Copy Markdown
Contributor Author

@DoomsCoder Thanks, re-pushed and all the tests are fine now.

@DoomsCoder
Copy link
Copy Markdown
Contributor

@DoomsCoder Thanks, re-pushed and all the tests are fine now.

Glad it helped!😊

Copy link
Copy Markdown
Member

@david-allison david-allison left a comment

Choose a reason for hiding this comment

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

We have a few helpers in our tests to reduce verbosity.

Index: AnkiDroid/src/test/java/com/ichi2/anki/dialogs/GradeNowDialogTest.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/AnkiDroid/src/test/java/com/ichi2/anki/dialogs/GradeNowDialogTest.kt b/AnkiDroid/src/test/java/com/ichi2/anki/dialogs/GradeNowDialogTest.kt
--- a/AnkiDroid/src/test/java/com/ichi2/anki/dialogs/GradeNowDialogTest.kt	(revision 95e00bf3d2229ef11e75930f9d47157b938d0d7d)
+++ b/AnkiDroid/src/test/java/com/ichi2/anki/dialogs/GradeNowDialogTest.kt	(date 1773584546507)
@@ -37,109 +37,88 @@
 /** Tests [GradeNowDialog] */
 @RunWith(RobolectricTestRunner::class)
 class GradeNowDialogTest : RobolectricTest() {
-    private lateinit var activityScenario: ActivityScenario<CardBrowser>
-
-    override fun setUp() {
-        super.setUp()
-
-        ensureCollectionLoadIsSynchronous()
-
-        activityScenario =
-            ActivityScenario.launch(CardBrowser::class.java).apply {
-                moveToState(Lifecycle.State.RESUMED)
-            }
-    }
-
-    override fun tearDown() {
-        super.tearDown()
-        activityScenario.close()
-    }
-
     @Test
     fun dialogLoads() {
-        val note = addBasicNote()
-        val cardId = note.cards(col)[0].id
-
-        lateinit var translatedTitle: String
+        val cardId = addBasicNote().firstCard().id
+        
+        val cardBrowser = super.startRegularActivity<CardBrowser>()
 
-        activityScenario.onActivity { activity ->
-            translatedTitle =
-                TR
-                    .actionsGradeNow()
-                    .toSentenceCase(activity, R.string.sentence_grade_now)
+        val translatedTitle =
+            TR
+                .actionsGradeNow()
+                .toSentenceCase(cardBrowser, R.string.sentence_grade_now)
 
-            GradeNowDialog.showDialog(activity, listOf(cardId))
-        }
+        GradeNowDialog.showDialog(cardBrowser, listOf(cardId))
 
         onView(withText(translatedTitle))
             .inRoot(isDialog())
             .check(matches(isDisplayed()))
     }
-
-    @Test
-    fun showsAllGradeOptions() {
-        val note = addBasicNote()
-        val cardId = note.cards(col)[0].id
-
-        activityScenario.onActivity { activity ->
-            GradeNowDialog.showDialog(activity, listOf(cardId))
-        }
-
-        onView(withText(TR.studyingAgain()))
-            .inRoot(isDialog())
-            .check(matches(isDisplayed()))
-
-        onView(withText(TR.studyingHard()))
-            .inRoot(isDialog())
-            .check(matches(isDisplayed()))
-
-        onView(withText(TR.studyingGood()))
-            .inRoot(isDialog())
-            .check(matches(isDisplayed()))
-
-        onView(withText(TR.studyingEasy()))
-            .inRoot(isDialog())
-            .check(matches(isDisplayed()))
-    }
-
-    @Test
-    fun clickingGradeDismissesDialog() {
-        val note = addBasicNote()
-        val cardId = note.cards(col)[0].id
-
-        lateinit var translatedTitle: String
-
-        activityScenario.onActivity { activity ->
-            translatedTitle =
-                TR
-                    .actionsGradeNow()
-                    .toSentenceCase(activity, R.string.sentence_grade_now)
-
-            GradeNowDialog.showDialog(activity, listOf(cardId))
-        }
-
-        onView(withText(TR.studyingGood()))
-            .inRoot(isDialog())
-            .perform(click())
-
-        onView(withText(translatedTitle))
-            .check(doesNotExist())
-    }
-
-    @Test
-    fun dialogNotShownIfNoCardsSelected() {
-        lateinit var translatedTitle: String
-
-        activityScenario.onActivity { activity ->
-            translatedTitle =
-                TR
-                    .actionsGradeNow()
-                    .toSentenceCase(activity, R.string.sentence_grade_now)
-
-            GradeNowDialog.showDialog(activity, emptyList())
-        }
-
-        onView(withText(translatedTitle))
-            .check(doesNotExist())
-    }
+//
+//    @Test
+//    fun showsAllGradeOptions() {
+//        val note = addBasicNote()
+//        val cardId = note.cards(col)[0].id
+//
+//        activityScenario.onActivity { activity ->
+//            GradeNowDialog.showDialog(activity, listOf(cardId))
+//        }
+//
+//        onView(withText(TR.studyingAgain()))
+//            .inRoot(isDialog())
+//            .check(matches(isDisplayed()))
+//
+//        onView(withText(TR.studyingHard()))
+//            .inRoot(isDialog())
+//            .check(matches(isDisplayed()))
+//
+//        onView(withText(TR.studyingGood()))
+//            .inRoot(isDialog())
+//            .check(matches(isDisplayed()))
+//
+//        onView(withText(TR.studyingEasy()))
+//            .inRoot(isDialog())
+//            .check(matches(isDisplayed()))
+//    }
+//
+//    @Test
+//    fun clickingGradeDismissesDialog() {
+//        val note = addBasicNote()
+//        val cardId = note.cards(col)[0].id
+//
+//        lateinit var translatedTitle: String
+//
+//        activityScenario.onActivity { activity ->
+//            translatedTitle =
+//                TR
+//                    .actionsGradeNow()
+//                    .toSentenceCase(activity, R.string.sentence_grade_now)
+//
+//            GradeNowDialog.showDialog(activity, listOf(cardId))
+//        }
+//
+//        onView(withText(TR.studyingGood()))
+//            .inRoot(isDialog())
+//            .perform(click())
+//
+//        onView(withText(translatedTitle))
+//            .check(doesNotExist())
+//    }
+//
+//    @Test
+//    fun dialogNotShownIfNoCardsSelected() {
+//        lateinit var translatedTitle: String
+//
+//        activityScenario.onActivity { activity ->
+//            translatedTitle =
+//                TR
+//                    .actionsGradeNow()
+//                    .toSentenceCase(activity, R.string.sentence_grade_now)
+//
+//            GradeNowDialog.showDialog(activity, emptyList())
+//        }
+//
+//        onView(withText(translatedTitle))
+//            .check(doesNotExist())
+//    }
 }

@BinaryBhaskar
Copy link
Copy Markdown
Contributor Author

@david-allison thanks for the review.. I've now updated the commit. you may review it again.

Copy link
Copy Markdown
Member

@david-allison david-allison left a comment

Choose a reason for hiding this comment

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

Beautiful, thanks so much

@david-allison david-allison added this pull request to the merge queue Mar 16, 2026
Merged via the queue into ankidroid:main with commit 4932952 Mar 16, 2026
15 checks passed
@github-actions github-actions Bot removed Needs Author Reply Waiting for a reply from the original author Needs Review labels Mar 16, 2026
@github-actions github-actions Bot added this to the 2.24 release milestone Mar 16, 2026
@BinaryBhaskar BinaryBhaskar deleted the gradeNowDialogTests branch March 16, 2026 03:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants