From df0b883ccbeb7b3f20ed4d73dca1bb74dcbd8f3a Mon Sep 17 00:00:00 2001 From: Kristof Nemere <109959688+kristofnemere@users.noreply.github.com> Date: Fri, 11 Aug 2023 10:50:57 +0200 Subject: [PATCH 01/22] [MBL-16956][Student] Rubric LGO refs: MBL-16956 affects: Student release note: none * Rubric LGO * fixed tests * fixed pr comment --- .../SubmissionDetailsEffectHandler.kt | 17 +++++- .../SubmissionDetailsModels.kt | 6 ++- .../SubmissionDetailsPresenter.kt | 3 +- .../SubmissionDetailsUpdate.kt | 3 +- .../drawer/rubric/SubmissionRubricModels.kt | 1 + .../rubric/SubmissionRubricPresenter.kt | 12 ++--- .../rubric/ui/SubmissionRubricFragment.kt | 8 ++- .../ui/SubmissionDetailsViewState.kt | 3 +- .../ui/gradeCell/GradeCellViewState.kt | 28 +++++++--- .../assignment/details/GradeCellStateTest.kt | 52 +++++++++++++++++++ .../SubmissionDetailsEffectHandlerTest.kt | 4 ++ .../SubmissionRubricPresenterTest.kt | 21 ++++++++ 12 files changed, 137 insertions(+), 21 deletions(-) diff --git a/apps/student/src/main/java/com/instructure/student/mobius/assignmentDetails/submissionDetails/SubmissionDetailsEffectHandler.kt b/apps/student/src/main/java/com/instructure/student/mobius/assignmentDetails/submissionDetails/SubmissionDetailsEffectHandler.kt index 1c7bb33fc3..bd88b91d10 100644 --- a/apps/student/src/main/java/com/instructure/student/mobius/assignmentDetails/submissionDetails/SubmissionDetailsEffectHandler.kt +++ b/apps/student/src/main/java/com/instructure/student/mobius/assignmentDetails/submissionDetails/SubmissionDetailsEffectHandler.kt @@ -122,7 +122,22 @@ class SubmissionDetailsEffectHandler : EffectHandler?, val studioLTIToolResult: DataResult?, val isObserver: Boolean = false, - val assignmentEnhancementsEnabled: Boolean + val assignmentEnhancementsEnabled: Boolean, + val restrictQuantitativeData: Boolean = false ) : SubmissionDetailsEvent() data class SubmissionCommentsUpdated(val submissionComments: List) : SubmissionDetailsEvent() } @@ -74,7 +75,8 @@ data class SubmissionDetailsModel( val ltiTool: DataResult? = null, val initialSelectedSubmissionAttempt: Long? = null, val submissionComments: List? = null, - val assignmentEnhancementsEnabled: Boolean = false + val assignmentEnhancementsEnabled: Boolean = false, + val restrictQuantitativeData: Boolean = false ) sealed class SubmissionDetailsContentType { diff --git a/apps/student/src/main/java/com/instructure/student/mobius/assignmentDetails/submissionDetails/SubmissionDetailsPresenter.kt b/apps/student/src/main/java/com/instructure/student/mobius/assignmentDetails/submissionDetails/SubmissionDetailsPresenter.kt index 3bd581fc50..cade1dc24a 100644 --- a/apps/student/src/main/java/com/instructure/student/mobius/assignmentDetails/submissionDetails/SubmissionDetailsPresenter.kt +++ b/apps/student/src/main/java/com/instructure/student/mobius/assignmentDetails/submissionDetails/SubmissionDetailsPresenter.kt @@ -80,7 +80,8 @@ object SubmissionDetailsPresenter : Presenter = emptyMap() ) diff --git a/apps/student/src/main/java/com/instructure/student/mobius/assignmentDetails/submissionDetails/drawer/rubric/SubmissionRubricPresenter.kt b/apps/student/src/main/java/com/instructure/student/mobius/assignmentDetails/submissionDetails/drawer/rubric/SubmissionRubricPresenter.kt index 0cad9f9bb6..a16d2f8595 100644 --- a/apps/student/src/main/java/com/instructure/student/mobius/assignmentDetails/submissionDetails/drawer/rubric/SubmissionRubricPresenter.kt +++ b/apps/student/src/main/java/com/instructure/student/mobius/assignmentDetails/submissionDetails/drawer/rubric/SubmissionRubricPresenter.kt @@ -24,12 +24,10 @@ import com.instructure.canvasapi2.models.RubricCriterionRating import com.instructure.canvasapi2.utils.NumberHelper import com.instructure.canvasapi2.utils.isValid import com.instructure.canvasapi2.utils.validOrNull -import com.instructure.pandautils.utils.ColorKeeper import com.instructure.pandautils.utils.textAndIconColor import com.instructure.student.R import com.instructure.student.mobius.assignmentDetails.ui.gradeCell.GradeCellViewState import com.instructure.student.mobius.common.ui.Presenter -import java.util.HashMap object SubmissionRubricPresenter : Presenter { @@ -46,7 +44,7 @@ object SubmissionRubricPresenter : Presenter RatingData( diff --git a/apps/student/src/main/java/com/instructure/student/mobius/assignmentDetails/submissionDetails/drawer/rubric/ui/SubmissionRubricFragment.kt b/apps/student/src/main/java/com/instructure/student/mobius/assignmentDetails/submissionDetails/drawer/rubric/ui/SubmissionRubricFragment.kt index 053e9241ce..a8268a84c0 100644 --- a/apps/student/src/main/java/com/instructure/student/mobius/assignmentDetails/submissionDetails/drawer/rubric/ui/SubmissionRubricFragment.kt +++ b/apps/student/src/main/java/com/instructure/student/mobius/assignmentDetails/submissionDetails/drawer/rubric/ui/SubmissionRubricFragment.kt @@ -22,6 +22,7 @@ import com.instructure.canvasapi2.models.Assignment import com.instructure.canvasapi2.models.Submission import com.instructure.pandautils.analytics.SCREEN_VIEW_SUBMISSION_RUBRIC import com.instructure.pandautils.analytics.ScreenView +import com.instructure.pandautils.utils.BooleanArg import com.instructure.pandautils.utils.Const import com.instructure.pandautils.utils.ParcelableArg import com.instructure.student.databinding.FragmentSubmissionRubricBinding @@ -29,11 +30,14 @@ import com.instructure.student.mobius.assignmentDetails.submissionDetails.drawer import com.instructure.student.mobius.assignmentDetails.submissionDetails.ui.SubmissionDetailsTabData import com.instructure.student.mobius.common.ui.MobiusFragment +private const val RESTRICT_QUANTITATIVE_DATA = "restrictQuantitativeData" + @ScreenView(SCREEN_VIEW_SUBMISSION_RUBRIC) class SubmissionRubricFragment : MobiusFragment() { private var submission by ParcelableArg(key = Const.SUBMISSION) private var assignment by ParcelableArg(key = Const.ASSIGNMENT) + private var restrictQuantitativeData by BooleanArg(key = RESTRICT_QUANTITATIVE_DATA) override fun makeEffectHandler() = SubmissionRubricEffectHandler() @@ -43,13 +47,13 @@ class SubmissionRubricFragment : override fun makePresenter() = SubmissionRubricPresenter - override fun makeInitModel() = SubmissionRubricModel(assignment, submission) + override fun makeInitModel() = SubmissionRubricModel(assignment, submission, restrictQuantitativeData) companion object { fun newInstance(data: SubmissionDetailsTabData.RubricData) = SubmissionRubricFragment().apply { submission = data.submission assignment = data.assignment + restrictQuantitativeData = data.restrictQuantitativeData } } - } diff --git a/apps/student/src/main/java/com/instructure/student/mobius/assignmentDetails/submissionDetails/ui/SubmissionDetailsViewState.kt b/apps/student/src/main/java/com/instructure/student/mobius/assignmentDetails/submissionDetails/ui/SubmissionDetailsViewState.kt index 2fb7cfcd08..a956c7e85f 100644 --- a/apps/student/src/main/java/com/instructure/student/mobius/assignmentDetails/submissionDetails/ui/SubmissionDetailsViewState.kt +++ b/apps/student/src/main/java/com/instructure/student/mobius/assignmentDetails/submissionDetails/ui/SubmissionDetailsViewState.kt @@ -50,7 +50,8 @@ sealed class SubmissionDetailsTabData(val tabName: String) { data class RubricData( val name: String, val assignment: Assignment, - val submission: Submission + val submission: Submission, + val restrictQuantitativeData: Boolean = false ) : SubmissionDetailsTabData(name) } diff --git a/apps/student/src/main/java/com/instructure/student/mobius/assignmentDetails/ui/gradeCell/GradeCellViewState.kt b/apps/student/src/main/java/com/instructure/student/mobius/assignmentDetails/ui/gradeCell/GradeCellViewState.kt index 0f0bc8b7e9..42cf48e75c 100644 --- a/apps/student/src/main/java/com/instructure/student/mobius/assignmentDetails/ui/gradeCell/GradeCellViewState.kt +++ b/apps/student/src/main/java/com/instructure/student/mobius/assignmentDetails/ui/gradeCell/GradeCellViewState.kt @@ -24,7 +24,6 @@ import com.instructure.canvasapi2.models.Assignment import com.instructure.canvasapi2.models.CanvasContext import com.instructure.canvasapi2.models.Submission import com.instructure.canvasapi2.utils.NumberHelper -import com.instructure.pandautils.utils.ColorKeeper import com.instructure.pandautils.utils.getContentDescriptionForMinusGradeString import com.instructure.pandautils.utils.textAndIconColor import com.instructure.student.R @@ -69,10 +68,12 @@ sealed class GradeCellViewState { fun fromSubmission( context: Context, assignment: Assignment, - submission: Submission? + submission: Submission?, + restrictQuantitativeData: Boolean = false ): GradeCellViewState { - // Return empty state if unsubmitted and ungraded, or "Not Graded" grading type - if ((submission?.submittedAt == null && submission?.isGraded != true) || assignment.gradingType == Assignment.NOT_GRADED_TYPE) { + // Return empty state if unsubmitted and ungraded, or "Not Graded" grading type or quantitative data is restricted + val hideGrades = restrictQuantitativeData && assignment.isGradingTypeQuantitative && submission?.excused != true + if ((submission?.submittedAt == null && submission?.isGraded != true) || assignment.gradingType == Assignment.NOT_GRADED_TYPE || hideGrades) { return Empty } @@ -87,8 +88,8 @@ sealed class GradeCellViewState { /* The 'Out of' text abbreviates the word "points" to "pts" which is read as "P T S" by screen readers, so * we use a second string with the full word "points" as a content description. */ val pointsPossibleText = NumberHelper.formatDecimal(assignment.pointsPossible, 2, true) - val outOfText = context.getString(R.string.outOfPointsAbbreviatedFormatted, pointsPossibleText) - val outOfContentDescriptionText = context.getString(R.string.outOfPointsFormatted, pointsPossibleText) + val outOfText = if (restrictQuantitativeData) "" else context.getString(R.string.outOfPointsAbbreviatedFormatted, pointsPossibleText) + val outOfContentDescriptionText = if (restrictQuantitativeData) "" else context.getString(R.string.outOfPointsFormatted, pointsPossibleText) // Excused if (submission.excused) { @@ -116,6 +117,21 @@ sealed class GradeCellViewState { ) } + if (restrictQuantitativeData) { + val grade = submission.grade.orEmpty() + val accessibleGradeString = getContentDescriptionForMinusGradeString(grade, context) + val gradeCellContentDescription = context.getString(R.string.a11y_gradeCellContentDescriptionLetterGradeOnly, accessibleGradeString) + + return GradeData( + showCompleteIcon = true, + graphPercent = 1.0f, + accentColor = accentColor, + grade = grade, + gradeContentDescription = accessibleGradeString, + gradeCellContentDescription = gradeCellContentDescription + ) + } + val score = NumberHelper.formatDecimal(submission.enteredScore, 2, true) val graphPercent = (submission.enteredScore / assignment.pointsPossible).coerceIn(0.0, 1.0).toFloat() diff --git a/apps/student/src/test/java/com/instructure/student/test/assignment/details/GradeCellStateTest.kt b/apps/student/src/test/java/com/instructure/student/test/assignment/details/GradeCellStateTest.kt index f2ab5c245c..461a326251 100644 --- a/apps/student/src/test/java/com/instructure/student/test/assignment/details/GradeCellStateTest.kt +++ b/apps/student/src/test/java/com/instructure/student/test/assignment/details/GradeCellStateTest.kt @@ -140,6 +140,8 @@ class GradeCellStateTest : Assert() { graphPercent = 1.0f, showCompleteIcon = true, grade = "Excused", + outOf = "Out of 100 pts", + outOfContentDescription = "Out of 100 points", gradeCellContentDescription = "" ) val actual = GradeCellViewState.fromSubmission(context, baseAssignment, submission) @@ -243,6 +245,8 @@ class GradeCellStateTest : Assert() { showPointsLabel = true, grade = "B+", gradeContentDescription = "B+", + outOf = "Out of 100 pts", + outOfContentDescription = "Out of 100 points", gradeCellContentDescription = "85 Out of 100 points, B+" ) val actual = GradeCellViewState.fromSubmission(context, assignment, submission) @@ -388,4 +392,52 @@ class GradeCellStateTest : Assert() { assertEquals(expected, actual.stats) } + @Test + fun `Returns empty state when assignment is quantitative and quantitative data is restricted`() { + val assignment = baseAssignment.copy( + gradingType = Assignment.POINTS_TYPE + ) + val expected = GradeCellViewState.Empty + val actual = GradeCellViewState.fromSubmission(context, assignment, Submission(), true) + assertEquals(expected, actual) + } + + @Test + fun `Create excused grade cell without points when assignment is quantitative and quantitative data is restricted`() { + val submission = baseSubmission.copy( + excused = true + ) + val expected = baseGradedState.copy( + graphPercent = 1.0f, + showCompleteIcon = true, + grade = "Excused", + outOf = "", + outOfContentDescription = "", + gradeCellContentDescription = "" + ) + val actual = GradeCellViewState.fromSubmission(context, baseAssignment, submission, true) + assertEquals(expected, actual) + } + + @Test + fun `Create letter grade cell without points when quantitative data is restricted`() { + val assignment = baseAssignment.copy( + gradingType = Assignment.LETTER_GRADE_TYPE + ) + val submission = baseSubmission.copy( + grade = "B+" + ) + val expected = baseGradedState.copy( + graphPercent = 1.0f, + score = "", + showCompleteIcon = true, + grade = "B+", + gradeContentDescription = "B+", + outOf = "", + outOfContentDescription = "", + gradeCellContentDescription = "Grade: B+" + ) + val actual = GradeCellViewState.fromSubmission(context, assignment, submission, true) + assertEquals(expected, actual) + } } diff --git a/apps/student/src/test/java/com/instructure/student/test/assignment/details/submissionDetails/SubmissionDetailsEffectHandlerTest.kt b/apps/student/src/test/java/com/instructure/student/test/assignment/details/submissionDetails/SubmissionDetailsEffectHandlerTest.kt index 1ada21d48d..93ea7990e7 100644 --- a/apps/student/src/test/java/com/instructure/student/test/assignment/details/submissionDetails/SubmissionDetailsEffectHandlerTest.kt +++ b/apps/student/src/test/java/com/instructure/student/test/assignment/details/submissionDetails/SubmissionDetailsEffectHandlerTest.kt @@ -51,9 +51,13 @@ class SubmissionDetailsEffectHandlerTest : Assert() { fun setup() { Dispatchers.setMain(Executors.newSingleThreadExecutor().asCoroutineDispatcher()) mockkObject(FeaturesManager) + mockkObject(CourseManager) every { FeaturesManager.getEnabledFeaturesForCourseAsync(any(), any()) } returns mockk { coEvery { await() } returns DataResult.Success(listOf("assignments_2_student")) } + every { CourseManager.getCourseSettingsAsync(any(), any()) } returns mockk { + coEvery { await() } returns DataResult.Success(CourseSettings()) + } } @Test diff --git a/apps/student/src/test/java/com/instructure/student/test/assignment/details/submissionDetails/rubricTab/SubmissionRubricPresenterTest.kt b/apps/student/src/test/java/com/instructure/student/test/assignment/details/submissionDetails/rubricTab/SubmissionRubricPresenterTest.kt index 3f8690ec89..b6fbee35fb 100644 --- a/apps/student/src/test/java/com/instructure/student/test/assignment/details/submissionDetails/rubricTab/SubmissionRubricPresenterTest.kt +++ b/apps/student/src/test/java/com/instructure/student/test/assignment/details/submissionDetails/rubricTab/SubmissionRubricPresenterTest.kt @@ -455,4 +455,25 @@ class SubmissionRubricPresenterTest : Assert() { val actualState = SubmissionRubricPresenter.present(model, context) assertEquals(expectedState, actualState) } + + @Test + fun `Returns correct state when quantitative data is restricted`() { + val model = modelTemplate.copy( + restrictQuantitativeData = true + ) + val expectedState = SubmissionRubricViewState( + listOf( + RubricListData.Grade(GradeCellViewState.fromSubmission(context, assignmentTemplate, submissionTemplate, true)), + criterionTemplate.copy( + ratings = listOf( + RatingData("_id1", "Rating 1 Title", isSelected = false, isAssessed = false, useSmallText = true), + RatingData("_id2", "Rating 2 Title", isSelected = true, isAssessed = true, useSmallText = true), + RatingData("_id3", "Rating 3 Title", isSelected = false, isAssessed = false, useSmallText = true) + ) + ) + ) + ) + val actualState = SubmissionRubricPresenter.present(model, context) + assertEquals(expectedState, actualState) + } } From 1709bcf466ea4f849c4110fb06d4900ab57a8d71 Mon Sep 17 00:00:00 2001 From: Kristof Deak <92309696+kdeakinstructure@users.noreply.github.com> Date: Tue, 15 Aug 2023 14:46:41 +0200 Subject: [PATCH 02/22] [MBL-16941][Student][Teacher] - Introduce SearchablePage interface (#2090) --- .../student/ui/e2e/AnnouncementsE2ETest.kt | 10 ++-- .../student/ui/e2e/AssignmentsE2ETest.kt | 4 +- .../student/ui/e2e/DiscussionsE2ETest.kt | 6 +-- .../student/ui/e2e/FilesE2ETest.kt | 8 ++- .../student/ui/e2e/PagesE2ETest.kt | 20 ++++++++ .../student/ui/e2e/QuizzesE2ETest.kt | 1 + .../AnnouncementInteractionTest.kt | 19 +++++-- .../student/ui/pages/AnnouncementListPage.kt | 2 +- .../student/ui/pages/AssignmentListPage.kt | 34 +++++++++---- .../student/ui/pages/DiscussionListPage.kt | 17 +------ .../student/ui/pages/FileListPage.kt | 23 ++------- .../student/ui/pages/PageListPage.kt | 24 ++++++--- .../student/ui/utils/StudentTest.kt | 9 ++-- .../teacher/ui/AnnouncementsListPageTest.kt | 8 +-- .../teacher/ui/DiscussionsListPageTest.kt | 8 +-- .../teacher/ui/PageListPageTest.kt | 4 +- .../teacher/ui/QuizListPageTest.kt | 4 +- .../teacher/ui/e2e/AnnouncementsE2ETest.kt | 6 +-- .../teacher/ui/e2e/DiscussionsE2ETest.kt | 15 ++++-- .../teacher/ui/e2e/FilesE2ETest.kt | 12 ++--- .../teacher/ui/e2e/PagesE2ETest.kt | 8 ++- .../teacher/ui/e2e/PeopleE2ETest.kt | 8 +-- .../teacher/ui/pages/AnnouncementsListPage.kt | 50 +------------------ .../teacher/ui/pages/DiscussionsListPage.kt | 25 ++-------- .../teacher/ui/pages/FileListPage.kt | 35 +------------ .../teacher/ui/pages/PageListPage.kt | 25 +--------- .../teacher/ui/pages/PeopleListPage.kt | 27 +--------- .../teacher/ui/pages/QuizListPage.kt | 20 +------- .../teacher/ui/utils/TeacherTest.kt | 14 +++--- .../espresso/CustomViewAssertions.kt | 20 ++++++++ .../com/instructure/espresso/Searchable.kt | 25 ++++++++++ .../espresso/matchers/WaitForViewMatcher.kt | 4 +- 32 files changed, 209 insertions(+), 286 deletions(-) create mode 100644 automation/espresso/src/main/kotlin/com/instructure/espresso/Searchable.kt diff --git a/apps/student/src/androidTest/java/com/instructure/student/ui/e2e/AnnouncementsE2ETest.kt b/apps/student/src/androidTest/java/com/instructure/student/ui/e2e/AnnouncementsE2ETest.kt index d34e9611d7..65b44544cd 100644 --- a/apps/student/src/androidTest/java/com/instructure/student/ui/e2e/AnnouncementsE2ETest.kt +++ b/apps/student/src/androidTest/java/com/instructure/student/ui/e2e/AnnouncementsE2ETest.kt @@ -92,8 +92,8 @@ class AnnouncementsE2ETest : StudentTest() { Log.d(STEP_TAG,"Click on Search button and type ${announcement.title} to the search input field.") Espresso.pressBack() - discussionListPage.clickOnSearchButton() - discussionListPage.typeToSearchBar(announcement.title) + discussionListPage.searchable.clickOnSearchButton() + discussionListPage.searchable.typeToSearchBar(announcement.title) Log.d(STEP_TAG,"Assert that only the matching announcement is displayed on the Discussion List Page.") discussionListPage.pullToUpdate() @@ -101,12 +101,12 @@ class AnnouncementsE2ETest : StudentTest() { discussionListPage.assertTopicNotDisplayed(lockedAnnouncement.title) Log.d(STEP_TAG,"Clear search input field value and assert if all the announcements are displayed again on the Discussion List Page.") - discussionListPage.clickOnClearSearchButton() + discussionListPage.searchable.clickOnClearSearchButton() discussionListPage.waitForDiscussionTopicToDisplay(lockedAnnouncement.title) discussionListPage.assertTopicDisplayed(announcement.title) Log.d(STEP_TAG,"Type a search value to the search input field which does not much with any of the existing announcements.") - discussionListPage.typeToSearchBar("Non existing announcement title") + discussionListPage.searchable.typeToSearchBar("Non existing announcement title") sleep(3000) //We need this wait here to let make sure the search process has finished. Log.d(STEP_TAG,"Assert that the empty view is displayed and none of the announcements are appearing on the page.") @@ -115,7 +115,7 @@ class AnnouncementsE2ETest : StudentTest() { discussionListPage.assertTopicNotDisplayed(lockedAnnouncement.title) Log.d(STEP_TAG,"Clear search input field value and assert if all the announcements are displayed again on the Discussion List Page.") - discussionListPage.clickOnClearSearchButton() + discussionListPage.searchable.clickOnClearSearchButton() discussionListPage.waitForDiscussionTopicToDisplay(lockedAnnouncement.title) discussionListPage.assertTopicDisplayed(announcement.title) diff --git a/apps/student/src/androidTest/java/com/instructure/student/ui/e2e/AssignmentsE2ETest.kt b/apps/student/src/androidTest/java/com/instructure/student/ui/e2e/AssignmentsE2ETest.kt index 2d98a6a603..018271a8d4 100644 --- a/apps/student/src/androidTest/java/com/instructure/student/ui/e2e/AssignmentsE2ETest.kt +++ b/apps/student/src/androidTest/java/com/instructure/student/ui/e2e/AssignmentsE2ETest.kt @@ -386,10 +386,10 @@ class AssignmentsE2ETest: StudentTest() { assignmentListPage.expandCollapseAssignmentGroup("Assignments") Log.d(STEP_TAG, "Click on the 'Search' (magnifying glass) icon at the toolbar.") - assignmentListPage.clickOnSearchButton() + assignmentListPage.searchable.clickOnSearchButton() Log.d(STEP_TAG, "Type the name of the '${missingAssignment.name}' assignment.") - assignmentListPage.typeToSearchBar(missingAssignment.name.drop(5)) + assignmentListPage.searchable.typeToSearchBar(missingAssignment.name.drop(5)) Log.d(STEP_TAG, "Assert that the '${missingAssignment.name}' assignment has been found by previously typed search string.") sleep(3000) // Allow the search input to propagate diff --git a/apps/student/src/androidTest/java/com/instructure/student/ui/e2e/DiscussionsE2ETest.kt b/apps/student/src/androidTest/java/com/instructure/student/ui/e2e/DiscussionsE2ETest.kt index 891abc37ce..85506cb028 100644 --- a/apps/student/src/androidTest/java/com/instructure/student/ui/e2e/DiscussionsE2ETest.kt +++ b/apps/student/src/androidTest/java/com/instructure/student/ui/e2e/DiscussionsE2ETest.kt @@ -88,8 +88,8 @@ class DiscussionsE2ETest: StudentTest() { Espresso.pressBack() Log.d(STEP_TAG,"Click on the 'Search' button and search for ${announcement2.title}. announcement.") - discussionListPage.clickOnSearchButton() - discussionListPage.typeToSearchBar(announcement2.title) + discussionListPage.searchable.clickOnSearchButton() + discussionListPage.searchable.typeToSearchBar(announcement2.title) Log.d(STEP_TAG,"Refresh the page. Assert that the searching method is working well, so ${announcement.title} won't be displayed and ${announcement2.title} is displayed.") discussionListPage.pullToUpdate() @@ -97,7 +97,7 @@ class DiscussionsE2ETest: StudentTest() { discussionListPage.assertTopicNotDisplayed(announcement.title) Log.d(STEP_TAG,"Clear the search input field and assert that both announcements, ${announcement.title} and ${announcement2.title} has been diplayed.") - discussionListPage.clickOnClearSearchButton() + discussionListPage.searchable.clickOnClearSearchButton() discussionListPage.waitForDiscussionTopicToDisplay(announcement.title) discussionListPage.assertTopicDisplayed(announcement2.title) diff --git a/apps/student/src/androidTest/java/com/instructure/student/ui/e2e/FilesE2ETest.kt b/apps/student/src/androidTest/java/com/instructure/student/ui/e2e/FilesE2ETest.kt index b7e1f53e7e..794c7dc02b 100644 --- a/apps/student/src/androidTest/java/com/instructure/student/ui/e2e/FilesE2ETest.kt +++ b/apps/student/src/androidTest/java/com/instructure/student/ui/e2e/FilesE2ETest.kt @@ -20,7 +20,6 @@ import android.os.Environment import android.util.Log import androidx.test.espresso.Espresso import com.instructure.canvas.espresso.E2E -import com.instructure.canvas.espresso.refresh import com.instructure.canvasapi2.managers.DiscussionManager import com.instructure.canvasapi2.models.CanvasContext import com.instructure.canvasapi2.models.DiscussionEntry @@ -186,14 +185,14 @@ class FilesE2ETest: StudentTest() { fileListPage.assertItemDisplayed("unfiled") // Our discussion attachment goes under "unfiled" Log.d(STEP_TAG, "Click on 'Search' (magnifying glass) icon and type '${discussionAttachmentFile.name}', the file's name to the search input field.") - fileListPage.clickSearchButton() - fileListPage.typeSearchInput(discussionAttachmentFile.name) + fileListPage.searchable.clickOnSearchButton() + fileListPage.searchable.typeToSearchBar(discussionAttachmentFile.name) Log.d(STEP_TAG, "Assert that only 1 file matches for the search text, and it is '${discussionAttachmentFile.name}', and no directories has been shown in the result. Press search back button the quit from search result view.") fileListPage.assertSearchResultCount(1) fileListPage.assertItemDisplayed(discussionAttachmentFile.name) fileListPage.assertItemNotDisplayed("unfiled") - fileListPage.pressSearchBackButton() + fileListPage.searchable.pressSearchBackButton() Log.d(STEP_TAG,"Select 'unfiled' directory. Assert that ${discussionAttachmentFile.name} file is displayed on the File List Page.") fileListPage.selectItem("unfiled") @@ -214,7 +213,6 @@ class FilesE2ETest: StudentTest() { Log.d(STEP_TAG, "Navigate back to global File List Page. Assert that the 'unfiled' folder has 0 items because we deleted the only item in it recently.") Espresso.pressBack() - refresh() //TODO after this bugfix: https://instructure.atlassian.net/browse/MBL-16937?atlOrigin=eyJpIjoiNWJjODY1MTI4NDE0NGQxM2E3ZjBiYTQzZDdlM2IwOWIiLCJwIjoiaiJ9 fileListPage.assertFolderSize("unfiled", 0) val testFolderName = "Krissinho's Test Folder" diff --git a/apps/student/src/androidTest/java/com/instructure/student/ui/e2e/PagesE2ETest.kt b/apps/student/src/androidTest/java/com/instructure/student/ui/e2e/PagesE2ETest.kt index 1dac3ed502..2f48aaacd3 100644 --- a/apps/student/src/androidTest/java/com/instructure/student/ui/e2e/PagesE2ETest.kt +++ b/apps/student/src/androidTest/java/com/instructure/student/ui/e2e/PagesE2ETest.kt @@ -81,6 +81,26 @@ class PagesE2ETest: StudentTest() { Log.d(STEP_TAG,"Assert that '${pageUnpublished.title}' unpublished page is NOT displayed.") pageListPage.assertPageNotDisplayed(pageUnpublished) + Log.d(STEP_TAG, "Click on 'Search' (magnifying glass) icon and type '${pagePublishedFront.title}', the page's name to the search input field.") + pageListPage.searchable.clickOnSearchButton() + pageListPage.searchable.typeToSearchBar(pagePublishedFront.title) + + Log.d(STEP_TAG,"Assert that '${pagePublished.title}' published page is NOT displayed and there is only one page (the front page) is displayed.") + pageListPage.assertPageNotDisplayed(pagePublished) + pageListPage.assertPageListItemCount(1) + + Log.d(STEP_TAG, "Click on clear search icon (X).") + pageListPage.searchable.clickOnClearSearchButton() + + Log.d(STEP_TAG,"Assert that '${pagePublishedFront.title}' published front page is displayed.") + pageListPage.assertFrontPageDisplayed(pagePublishedFront) + + Log.d(STEP_TAG,"Assert that '${pagePublished.title}' published page is displayed.") + pageListPage.assertRegularPageDisplayed(pagePublished) + + Log.d(STEP_TAG,"Assert that '${pageUnpublished.title}' unpublished page is NOT displayed.") + pageListPage.assertPageNotDisplayed(pageUnpublished) + Log.d(STEP_TAG,"Open '${pagePublishedFront.title}' page. Assert that it is really a front (published) page via web view assertions.") pageListPage.selectFrontPage(pagePublishedFront) canvasWebViewPage.runTextChecks(WebViewTextCheck(Locator.ID, "header1", "Front Page Text")) diff --git a/apps/student/src/androidTest/java/com/instructure/student/ui/e2e/QuizzesE2ETest.kt b/apps/student/src/androidTest/java/com/instructure/student/ui/e2e/QuizzesE2ETest.kt index 472584de69..13261cd33e 100644 --- a/apps/student/src/androidTest/java/com/instructure/student/ui/e2e/QuizzesE2ETest.kt +++ b/apps/student/src/androidTest/java/com/instructure/student/ui/e2e/QuizzesE2ETest.kt @@ -248,4 +248,5 @@ class QuizzesE2ETest: StudentTest() { // answers = listOf() // ) ) + } \ No newline at end of file diff --git a/apps/student/src/androidTest/java/com/instructure/student/ui/interaction/AnnouncementInteractionTest.kt b/apps/student/src/androidTest/java/com/instructure/student/ui/interaction/AnnouncementInteractionTest.kt index a857544b3b..187ff93b34 100644 --- a/apps/student/src/androidTest/java/com/instructure/student/ui/interaction/AnnouncementInteractionTest.kt +++ b/apps/student/src/androidTest/java/com/instructure/student/ui/interaction/AnnouncementInteractionTest.kt @@ -17,8 +17,17 @@ package com.instructure.student.ui.interaction import androidx.test.espresso.Espresso import androidx.test.espresso.web.webdriver.Locator -import com.instructure.canvas.espresso.mockCanvas.* -import com.instructure.canvasapi2.models.* +import com.instructure.canvas.espresso.mockCanvas.MockCanvas +import com.instructure.canvas.espresso.mockCanvas.addCoursePermissions +import com.instructure.canvas.espresso.mockCanvas.addDiscussionTopicToCourse +import com.instructure.canvas.espresso.mockCanvas.addGroupToCourse +import com.instructure.canvas.espresso.mockCanvas.init +import com.instructure.canvasapi2.models.CanvasContextPermission +import com.instructure.canvasapi2.models.Course +import com.instructure.canvasapi2.models.DiscussionTopicHeader +import com.instructure.canvasapi2.models.Group +import com.instructure.canvasapi2.models.Tab +import com.instructure.canvasapi2.models.User import com.instructure.panda_annotations.FeatureCategory import com.instructure.panda_annotations.Priority import com.instructure.panda_annotations.TestCategory @@ -219,14 +228,14 @@ class AnnouncementInteractionTest : StudentTest() { discussionListPage.createAnnouncement(testAnnouncementName, "description") discussionListPage.assertAnnouncementCreated(testAnnouncementName) - discussionListPage.clickOnSearchButton() - discussionListPage.typeToSearchBar(testAnnouncementName) + discussionListPage.searchable.clickOnSearchButton() + discussionListPage.searchable.typeToSearchBar(testAnnouncementName) discussionListPage.pullToUpdate() discussionListPage.assertTopicDisplayed(testAnnouncementName) discussionListPage.assertTopicNotDisplayed(existingAnnouncementName) - discussionListPage.clickOnClearSearchButton() + discussionListPage.searchable.clickOnClearSearchButton() discussionListPage.waitForDiscussionTopicToDisplay(existingAnnouncementName!!) discussionListPage.assertTopicDisplayed(testAnnouncementName) } diff --git a/apps/student/src/androidTest/java/com/instructure/student/ui/pages/AnnouncementListPage.kt b/apps/student/src/androidTest/java/com/instructure/student/ui/pages/AnnouncementListPage.kt index d56e3f34e0..d4986a1d9e 100644 --- a/apps/student/src/androidTest/java/com/instructure/student/ui/pages/AnnouncementListPage.kt +++ b/apps/student/src/androidTest/java/com/instructure/student/ui/pages/AnnouncementListPage.kt @@ -26,7 +26,7 @@ import com.instructure.espresso.page.withParent import com.instructure.espresso.page.withText import com.instructure.student.R -class AnnouncementListPage : BasePage(R.id.discussionListPage) { +class AnnouncementListPage() : BasePage(R.id.discussionListPage) { fun assertToolbarTitle() { WaitForViewMatcher.waitForView(withParent(R.id.discussionListToolbar) + withText(R.string.announcements)).assertDisplayed() diff --git a/apps/student/src/androidTest/java/com/instructure/student/ui/pages/AssignmentListPage.kt b/apps/student/src/androidTest/java/com/instructure/student/ui/pages/AssignmentListPage.kt index cb79a791e3..6244425c93 100644 --- a/apps/student/src/androidTest/java/com/instructure/student/ui/pages/AssignmentListPage.kt +++ b/apps/student/src/androidTest/java/com/instructure/student/ui/pages/AssignmentListPage.kt @@ -27,14 +27,34 @@ import com.instructure.canvas.espresso.waitForMatcherWithRefreshes import com.instructure.canvasapi2.models.Assignment import com.instructure.dataseeding.model.AssignmentApiModel import com.instructure.dataseeding.model.QuizApiModel -import com.instructure.espresso.* -import com.instructure.espresso.page.* +import com.instructure.espresso.OnViewWithId +import com.instructure.espresso.RecyclerViewItemCountAssertion +import com.instructure.espresso.Searchable +import com.instructure.espresso.WaitForViewWithId +import com.instructure.espresso.WaitForViewWithText +import com.instructure.espresso.assertDisplayed +import com.instructure.espresso.assertHasText +import com.instructure.espresso.assertNotDisplayed +import com.instructure.espresso.assertVisible +import com.instructure.espresso.click +import com.instructure.espresso.page.BasePage +import com.instructure.espresso.page.onView +import com.instructure.espresso.page.plus +import com.instructure.espresso.page.waitForView +import com.instructure.espresso.page.waitForViewWithText +import com.instructure.espresso.page.withAncestor +import com.instructure.espresso.page.withId +import com.instructure.espresso.page.withParent +import com.instructure.espresso.page.withText +import com.instructure.espresso.scrollTo +import com.instructure.espresso.swipeDown +import com.instructure.espresso.waitForCheck import com.instructure.student.R import org.hamcrest.Matcher import org.hamcrest.Matchers.allOf import org.hamcrest.Matchers.containsString -class AssignmentListPage : BasePage(pageResId = R.id.assignmentListPage) { +class AssignmentListPage(val searchable: Searchable) : BasePage(pageResId = R.id.assignmentListPage) { private val assignmentListToolbar by OnViewWithId(R.id.toolbar) private val gradingPeriodHeader by WaitForViewWithId(R.id.termSpinnerLayout) @@ -84,14 +104,6 @@ class AssignmentListPage : BasePage(pageResId = R.id.assignmentListPage) { onView(withId(R.id.points) + withParent(hasSibling(pointsMatcher))).assertNotDisplayed() } - fun clickOnSearchButton() { - onView(withId(R.id.search)).click() - } - - fun typeToSearchBar(textToType: String) { - waitForViewWithId(R.id.search_src_text).replaceText(textToType) - } - fun assertAssignmentNotDisplayed(assignmentName: String) { onView(withText(assignmentName) + withId(R.id.title) + hasSibling(withId(R.id.description))).check(doesNotExist()) } diff --git a/apps/student/src/androidTest/java/com/instructure/student/ui/pages/DiscussionListPage.kt b/apps/student/src/androidTest/java/com/instructure/student/ui/pages/DiscussionListPage.kt index 5e7d5468a3..3e6bebfce7 100644 --- a/apps/student/src/androidTest/java/com/instructure/student/ui/pages/DiscussionListPage.kt +++ b/apps/student/src/androidTest/java/com/instructure/student/ui/pages/DiscussionListPage.kt @@ -27,6 +27,7 @@ import com.instructure.canvas.espresso.waitForMatcherWithRefreshes import com.instructure.canvasapi2.models.DiscussionTopicHeader import com.instructure.espresso.OnViewWithId import com.instructure.espresso.RecyclerViewItemCountAssertion +import com.instructure.espresso.Searchable import com.instructure.espresso.assertDisplayed import com.instructure.espresso.assertNotDisplayed import com.instructure.espresso.click @@ -35,12 +36,10 @@ import com.instructure.espresso.page.onView import com.instructure.espresso.page.onViewWithText import com.instructure.espresso.page.plus import com.instructure.espresso.page.waitForView -import com.instructure.espresso.page.waitForViewWithId import com.instructure.espresso.page.withAncestor import com.instructure.espresso.page.withDescendant import com.instructure.espresso.page.withId import com.instructure.espresso.page.withText -import com.instructure.espresso.replaceText import com.instructure.espresso.scrollTo import com.instructure.espresso.swipeDown import com.instructure.espresso.waitForCheck @@ -50,7 +49,7 @@ import org.hamcrest.Matchers.allOf import org.hamcrest.Matchers.anyOf import org.hamcrest.Matchers.containsString -class DiscussionListPage : BasePage(R.id.discussionListPage) { +class DiscussionListPage(val searchable: Searchable) : BasePage(R.id.discussionListPage) { private val createNewDiscussion by OnViewWithId(R.id.createNewDiscussion) private val announcementsRecyclerView by OnViewWithId(R.id.discussionRecyclerView) @@ -150,18 +149,6 @@ class DiscussionListPage : BasePage(R.id.discussionListPage) { onView(withContentDescription("Close")).click() } - fun clickOnSearchButton() { - onView(withId(R.id.search)).click() - } - - fun typeToSearchBar(textToType: String) { - waitForViewWithId(R.id.search_src_text).replaceText(textToType) - } - - fun clickOnClearSearchButton() { - onView(withId(R.id.search_close_btn)).click() - } - fun verifyExitWithoutSavingDialog() { onView(withText(R.string.exitWithoutSavingMessage)).check(matches(isDisplayed())) } diff --git a/apps/student/src/androidTest/java/com/instructure/student/ui/pages/FileListPage.kt b/apps/student/src/androidTest/java/com/instructure/student/ui/pages/FileListPage.kt index a3c35dc8e9..7ebf099da4 100644 --- a/apps/student/src/androidTest/java/com/instructure/student/ui/pages/FileListPage.kt +++ b/apps/student/src/androidTest/java/com/instructure/student/ui/pages/FileListPage.kt @@ -28,6 +28,7 @@ import com.instructure.canvas.espresso.containsTextCaseInsensitive import com.instructure.canvas.espresso.scrollRecyclerView import com.instructure.canvas.espresso.withCustomConstraints import com.instructure.espresso.OnViewWithId +import com.instructure.espresso.Searchable import com.instructure.espresso.assertDisplayed import com.instructure.espresso.assertNotDisplayed import com.instructure.espresso.clearText @@ -39,7 +40,6 @@ import com.instructure.espresso.page.waitForView import com.instructure.espresso.page.waitForViewWithId import com.instructure.espresso.page.withAncestor import com.instructure.espresso.page.withId -import com.instructure.espresso.replaceText import com.instructure.espresso.scrollTo import com.instructure.espresso.typeText import com.instructure.student.R @@ -47,7 +47,7 @@ import org.hamcrest.Matchers.allOf // Tests that files submitted for submissions, submission comments and discussions are // properly displayed. -class FileListPage : BasePage(R.id.fileListPage) { +class FileListPage(val searchable: Searchable) : BasePage(R.id.fileListPage) { private val addButton by OnViewWithId(R.id.addFab) private val uploadFileButton by OnViewWithId(R.id.addFileFab, autoAssert = false) @@ -124,19 +124,6 @@ class FileListPage : BasePage(R.id.fileListPage) { onView(allOf(withId(R.id.emptyView), isDisplayed())).assertDisplayed() } - fun clickSearchButton() { - onView(withId(R.id.search)).click() - } - - fun typeSearchInput(searchText: String) { - onView(withId(R.id.queryInput)).replaceText(searchText) - } - - fun clickResetSearchText() { - waitForView(withId(R.id.clearButton)).click() - onView(withId(R.id.backButton)).click() - } - fun assertSearchResultCount(expectedCount: Int) { Thread.sleep(2000) onView(withId(R.id.fileSearchRecyclerView) + withAncestor(R.id.container)).check( @@ -151,11 +138,7 @@ class FileListPage : BasePage(R.id.fileListPage) { ) } - fun pressSearchBackButton() { - onView(withId(R.id.backButton)).click() - } - fun assertFolderSize(folderName: String, expectedSize: Int) { - onView(allOf(withId(R.id.fileSize), hasSibling(withId(R.id.fileName) + withText(folderName)))).check(matches(containsTextCaseInsensitive("$expectedSize ${if (expectedSize == 1) "item" else "items"}"))) + waitForView(allOf(withId(R.id.fileSize), hasSibling(withId(R.id.fileName) + withText(folderName)))).check(matches(containsTextCaseInsensitive("$expectedSize ${if (expectedSize == 1) "item" else "items"}"))) } } \ No newline at end of file diff --git a/apps/student/src/androidTest/java/com/instructure/student/ui/pages/PageListPage.kt b/apps/student/src/androidTest/java/com/instructure/student/ui/pages/PageListPage.kt index b8f938bf65..71dea6a596 100644 --- a/apps/student/src/androidTest/java/com/instructure/student/ui/pages/PageListPage.kt +++ b/apps/student/src/androidTest/java/com/instructure/student/ui/pages/PageListPage.kt @@ -17,22 +17,28 @@ package com.instructure.student.ui.pages import android.view.View -import androidx.test.espresso.Espresso.onView -import androidx.test.espresso.assertion.ViewAssertions.doesNotExist +import androidx.test.espresso.matcher.ViewMatchers import androidx.test.espresso.matcher.ViewMatchers.hasSibling -import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withText import com.instructure.canvas.espresso.scrollRecyclerView import com.instructure.canvasapi2.models.Page import com.instructure.dataseeding.model.PageApiModel +import com.instructure.espresso.DoesNotExistAssertion +import com.instructure.espresso.RecyclerViewItemCountAssertion +import com.instructure.espresso.Searchable import com.instructure.espresso.assertDisplayed import com.instructure.espresso.click import com.instructure.espresso.page.BasePage +import com.instructure.espresso.page.onView +import com.instructure.espresso.page.plus +import com.instructure.espresso.page.withAncestor +import com.instructure.espresso.page.withId +import com.instructure.espresso.waitForCheck import com.instructure.student.R import org.hamcrest.Matcher import org.hamcrest.Matchers.allOf -class PageListPage : BasePage(R.id.pageListPage) { +class PageListPage(val searchable: Searchable) : BasePage(R.id.pageListPage) { fun assertFrontPageDisplayed(page: PageApiModel) { val matcher = getFrontPageMatcher(page) @@ -96,9 +102,15 @@ class PageListPage : BasePage(R.id.pageListPage) { fun assertPageNotDisplayed(page: PageApiModel) { // Check for front page - onView(allOf(withId(R.id.homeSubLabel), withText(page.title))).check(doesNotExist()) + onView(allOf(withId(R.id.homeSubLabel), withText(page.title))).check(DoesNotExistAssertion(10000L)) // Check for regular page - onView(allOf(withId(R.id.title), withText(page.title))).check(doesNotExist()) + onView(allOf(withId(R.id.title), withText(page.title))).check(DoesNotExistAssertion(10000L)) + } + + fun assertPageListItemCount(expectedCount: Int) { + onView(allOf(withId(R.id.listView) + + ViewMatchers.withParent(withId(R.id.swipeRefreshLayout)) + + withAncestor(withId(R.id.pageListPage)))).waitForCheck(RecyclerViewItemCountAssertion(expectedCount)) } } \ No newline at end of file diff --git a/apps/student/src/androidTest/java/com/instructure/student/ui/utils/StudentTest.kt b/apps/student/src/androidTest/java/com/instructure/student/ui/utils/StudentTest.kt index ad59621f01..2285f6c0ce 100644 --- a/apps/student/src/androidTest/java/com/instructure/student/ui/utils/StudentTest.kt +++ b/apps/student/src/androidTest/java/com/instructure/student/ui/utils/StudentTest.kt @@ -34,6 +34,7 @@ import androidx.test.espresso.matcher.ViewMatchers import androidx.test.platform.app.InstrumentationRegistry import com.instructure.canvas.espresso.CanvasTest import com.instructure.espresso.InstructureActivityTestRule +import com.instructure.espresso.Searchable import com.instructure.espresso.swipeRight import com.instructure.pandautils.utils.Const import com.instructure.student.BuildConfig @@ -144,7 +145,7 @@ abstract class StudentTest : CanvasTest() { val annotationCommentListPage = AnnotationCommentListPage() val announcementListPage = AnnouncementListPage() val assignmentDetailsPage = AssignmentDetailsPage() - val assignmentListPage = AssignmentListPage() + val assignmentListPage = AssignmentListPage(Searchable(R.id.search, R.id.search_src_text)) val bookmarkPage = BookmarkPage() val calendarEventPage = CalendarEventPage() val canvasWebViewPage = CanvasWebViewPage() @@ -157,9 +158,9 @@ abstract class StudentTest : CanvasTest() { val dashboardPage = DashboardPage() val leftSideNavigationDrawerPage = LeftSideNavigationDrawerPage() val discussionDetailsPage = DiscussionDetailsPage() - val discussionListPage = DiscussionListPage() + val discussionListPage = DiscussionListPage(Searchable(R.id.search, R.id.search_src_text, R.id.search_close_btn)) val editDashboardPage = EditDashboardPage() - val fileListPage = FileListPage() + val fileListPage = FileListPage(Searchable(R.id.search, R.id.queryInput, R.id.clearButton, R.id.backButton)) val fileUploadPage = FileUploadPage() val helpPage = HelpPage() val inboxConversationPage = InboxConversationPage() @@ -173,7 +174,7 @@ abstract class StudentTest : CanvasTest() { val modulesPage = ModulesPage() val newMessagePage = NewMessagePage() val notificationPage = NotificationPage() - val pageListPage = PageListPage() + val pageListPage = PageListPage(Searchable(R.id.search, R.id.search_src_text, R.id.search_close_btn)) val pairObserverPage = PairObserverPage() val pandaAvatarPage = PandaAvatarPage() val peopleListPage = PeopleListPage() diff --git a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/AnnouncementsListPageTest.kt b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/AnnouncementsListPageTest.kt index b53c9c5578..64934a2262 100644 --- a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/AnnouncementsListPageTest.kt +++ b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/AnnouncementsListPageTest.kt @@ -35,8 +35,8 @@ import com.instructure.teacher.R import com.instructure.teacher.ui.utils.TeacherTest import com.instructure.teacher.ui.utils.tokenLogin import dagger.hilt.android.testing.HiltAndroidTest -import org.hamcrest.Matchers.`is` import org.hamcrest.Matchers.allOf +import org.hamcrest.Matchers.`is` import org.junit.Test @HiltAndroidTest @@ -76,9 +76,9 @@ class AnnouncementsListPageTest : TeacherTest() { val searchAnnouncement = announcements[2] announcementsListPage.assertAnnouncementCount(announcements.size + 1) // +1 to account for header - announcementsListPage.openSearch() - announcementsListPage.enterSearchQuery(searchAnnouncement.title!!.take(searchAnnouncement.title!!.length / 2)) - announcementsListPage.assertAnnouncementCount(2) // header + single search result + announcementsListPage.searchable.clickOnSearchButton() + announcementsListPage.searchable.typeToSearchBar(searchAnnouncement.title!!.take(searchAnnouncement.title!!.length / 2)) + announcementsListPage.assertSearchResultCount(1) announcementsListPage.assertHasAnnouncement(searchAnnouncement) } diff --git a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/DiscussionsListPageTest.kt b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/DiscussionsListPageTest.kt index 80f1b5803d..1f962bc1a0 100644 --- a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/DiscussionsListPageTest.kt +++ b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/DiscussionsListPageTest.kt @@ -49,10 +49,10 @@ class DiscussionsListPageTest : TeacherTest() { fun searchesDiscussions() { val discussions = getToDiscussionsListPage(discussionCount = 3).courseDiscussionTopicHeaders[course.id]!! val searchDiscussion = discussions[2] - discussionsListPage.assertDiscussionCount(discussions.size + 1) // +1 to account for header - discussionsListPage.openSearch() - discussionsListPage.enterSearchQuery(searchDiscussion.title!!.take(searchDiscussion.title!!.length / 2)) - discussionsListPage.assertDiscussionCount(2) // header + single search result + discussionsListPage.assertDiscussionCount(discussions.size) + discussionsListPage.searchable.clickOnSearchButton() + discussionsListPage.searchable.typeToSearchBar(searchDiscussion.title!!.take(searchDiscussion.title!!.length / 2)) + discussionsListPage.assertDiscussionCount(1) discussionsListPage.assertHasDiscussion(searchDiscussion) } diff --git a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/PageListPageTest.kt b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/PageListPageTest.kt index 5492ddcc65..db39f7c554 100644 --- a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/PageListPageTest.kt +++ b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/PageListPageTest.kt @@ -41,8 +41,8 @@ class PageListPageTest : TeacherTest() { val pages = getToPageListPage(pageCount = 3) val searchPage = pages[2] pageListPage.assertPageCount(pages.size) - pageListPage.openSearch() - pageListPage.enterSearchQuery(searchPage.title!!.take(searchPage.title!!.length / 2)) + pageListPage.searchable.clickOnSearchButton() + pageListPage.searchable.typeToSearchBar(searchPage.title!!.take(searchPage.title!!.length / 2)) pageListPage.assertPageCount(1) pageListPage.assertHasPage(searchPage) } diff --git a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/QuizListPageTest.kt b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/QuizListPageTest.kt index 878a911118..f57ccc6c44 100644 --- a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/QuizListPageTest.kt +++ b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/QuizListPageTest.kt @@ -56,8 +56,8 @@ class QuizListPageTest : TeacherTest() { val quizzes = getToQuizzesPage(quizCount = 3) val searchQuiz = quizzes[2] quizListPage.assertQuizCount(quizzes.size + 1) // +1 to account for header - quizListPage.openSearch() - quizListPage.enterSearchQuery(searchQuiz.title!!.take(searchQuiz.title!!.length / 2)) + quizListPage.searchable.clickOnSearchButton() + quizListPage.searchable.typeToSearchBar(searchQuiz.title!!.take(searchQuiz.title!!.length / 2)) quizListPage.assertQuizCount(2) // header + single search result quizListPage.assertHasQuiz(searchQuiz) } diff --git a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/e2e/AnnouncementsE2ETest.kt b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/e2e/AnnouncementsE2ETest.kt index 6f8268f398..fb91c72a4a 100644 --- a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/e2e/AnnouncementsE2ETest.kt +++ b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/e2e/AnnouncementsE2ETest.kt @@ -70,15 +70,15 @@ class AnnouncementsE2ETest : TeacherTest() { announcementsListPage.assertHasAnnouncement(announcement) Log.d(STEP_TAG, "Click on 'Search' (magnifying glass) icon and type '${announcement2.title}', one of the announcements' name to the search input field.") - announcementsListPage.clickSearchButton() - announcementsListPage.typeSearchInput(announcement2.title) + announcementsListPage.searchable.clickOnSearchButton() + announcementsListPage.searchable.typeToSearchBar(announcement2.title) Log.d(STEP_TAG, "Assert that only 1 announcement matches for the search text, and it is '${announcement2.title}'.") announcementsListPage.assertSearchResultCount(1) announcementsListPage.assertHasAnnouncement(announcement2) Log.d(STEP_TAG, "Click on 'Reset' search (cross) icon and assert that all the announcements are displayed (2).") - announcementsListPage.clickResetSearchText() + announcementsListPage.searchable.clickOnClearSearchButton() announcementsListPage.assertSearchResultCount(2) Log.d(STEP_TAG,"Edit ${announcement.title} announcement's name to 'Haha'. Save the modifications.") diff --git a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/e2e/DiscussionsE2ETest.kt b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/e2e/DiscussionsE2ETest.kt index 676ee37d3d..17132fd6d5 100644 --- a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/e2e/DiscussionsE2ETest.kt +++ b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/e2e/DiscussionsE2ETest.kt @@ -121,23 +121,28 @@ class DiscussionsE2ETest : TeacherTest() { Espresso.pressBack() Log.d(STEP_TAG,"Click on the Search icon and type some search query string which matches only with the previously created discussion's title.") - discussionsListPage.openSearch() - discussionsListPage.enterSearchQuery("Test Discussion") + discussionsListPage.searchable.clickOnSearchButton() + discussionsListPage.searchable.typeToSearchBar("Test Discussion") Log.d(STEP_TAG,"Assert that the '$newDiscussionTitle' discussion is displayed and it is the only one.") - discussionsListPage.assertDiscussionCount(2) // header + single search result + discussionsListPage.assertDiscussionCount(1) discussionsListPage.assertHasDiscussion(newDiscussionTitle) Espresso.pressBack() // need to press back to exit from the search input field Log.d(STEP_TAG,"Collapse the discussion list and assert that the '$newDiscussionTitle' discussion can NOT be seen.") discussionsListPage.toggleCollapseExpandIcon() - discussionsListPage.assertDiscussionCount(1) // header only + discussionsListPage.assertDiscussionCount(0) // header only discussionsListPage.assertDiscussionDoesNotExist(newDiscussionTitle) Log.d(STEP_TAG,"Expand the discussion list and assert that the '$newDiscussionTitle' discussion can be seen.") discussionsListPage.toggleCollapseExpandIcon() - discussionsListPage.assertDiscussionCount(2) // header only + single search result + discussionsListPage.assertDiscussionCount(1) discussionsListPage.assertHasDiscussion(newDiscussionTitle) + Log.d(STEP_TAG, "Click on the clear search input button (X) on the toolbar. Assert that the default state, so both of the discussions will be displayed.") + discussionsListPage.searchable.clickOnClearSearchButton() + discussionsListPage.assertHasDiscussion(discussion) + discussionsListPage.assertHasDiscussion(discussion2) + discussionsListPage.assertDiscussionCount(2) } } \ No newline at end of file diff --git a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/e2e/FilesE2ETest.kt b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/e2e/FilesE2ETest.kt index 0fa4c283b7..71aab3cde4 100644 --- a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/e2e/FilesE2ETest.kt +++ b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/e2e/FilesE2ETest.kt @@ -166,8 +166,8 @@ class FilesE2ETest: TeacherTest() { fileListPage.assertItemDisplayed("unfiled") Log.d(STEP_TAG, "Click on 'Search' (magnifying glass) icon and type '${discussionAttachmentFile.name}', the file's name to the search input field.") - fileListPage.clickSearchButton() - fileListPage.typeSearchInput(discussionAttachmentFile.name) + fileListPage.searchable.clickOnSearchButton() + fileListPage.searchable.typeToSearchBar(discussionAttachmentFile.name) Log.d(STEP_TAG, "Assert that only 1 file matches for the search text, and it is '${discussionAttachmentFile.name}', and no directories has been shown in the result.") fileListPage.assertSearchResultCount(1) @@ -175,7 +175,7 @@ class FilesE2ETest: TeacherTest() { fileListPage.assertItemNotDisplayed("unfiled") Log.d(STEP_TAG, "Click on 'Reset' search (cross) icon and assert that all the root level directories and files are displayed (1).") - fileListPage.clickResetSearchText() + fileListPage.searchable.clickOnClearSearchButton() fileListPage.assertFileListCount(1) Log.d(STEP_TAG,"Select 'unfiled' directory. Assert that ${discussionAttachmentFile.name} file is displayed on the File List Page.") @@ -210,12 +210,12 @@ class FilesE2ETest: TeacherTest() { fileListPage.assertItemDisplayed(newFolderName) Log.d(STEP_TAG, "Click on 'Search' (magnifying glass) icon and type '${newFolderName}', the file's name to the search input field.") - fileListPage.clickSearchButton() - fileListPage.typeSearchInput(newFolderName) + fileListPage.searchable.clickOnSearchButton() + fileListPage.searchable.typeToSearchBar(newFolderName) Log.d(STEP_TAG,"Assert that empty view is displayed after deletion, because no folders will not be displayed in search result. Press back button (top one) to escape from Search 'view'.") fileListPage.assertViewEmpty() - fileListPage.pressSearchBackButton() + fileListPage.searchable.pressSearchBackButton() Log.d(STEP_TAG, "Select '$newFolderName' folder and delete it. Assert that it has been disappeared from the File List Page.") fileListPage.deleteFolder(newFolderName) diff --git a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/e2e/PagesE2ETest.kt b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/e2e/PagesE2ETest.kt index c54d283d5d..874ddd528b 100644 --- a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/e2e/PagesE2ETest.kt +++ b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/e2e/PagesE2ETest.kt @@ -147,12 +147,16 @@ class PagesE2ETest : TeacherTest() { pageListPage.assertPageIsPublished(newPageTitle) Log.d(STEP_TAG,"Click on the Search icon and type some search query string which matches only with the previously created page's title.") - pageListPage.openSearch() - pageListPage.enterSearchQuery("Test") + pageListPage.searchable.clickOnSearchButton() + pageListPage.searchable.typeToSearchBar("Test") Log.d(STEP_TAG,"Assert that the '$newPageTitle' titled page is displayed and it is the only one.") pageListPage.assertPageIsPublished(newPageTitle) pageListPage.assertPageCount(1) + + Log.d(STEP_TAG, "Click on the clear search input button (X) on the toolbar. Assert that the default state, so all the 4 pages will be displayed.") + pageListPage.searchable.clickOnClearSearchButton() + pageListPage.assertPageCount(4) } private fun createCoursePage( diff --git a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/e2e/PeopleE2ETest.kt b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/e2e/PeopleE2ETest.kt index 08d0a0f2d5..5baed3c839 100644 --- a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/e2e/PeopleE2ETest.kt +++ b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/e2e/PeopleE2ETest.kt @@ -139,15 +139,15 @@ class PeopleE2ETest: TeacherTest() { Espresso.pressBack() Log.d(STEP_TAG, "Click on 'Search' (magnifying glass) icon and type '${gradedStudent.name}', the graded student's name to the search input field.") - peopleListPage.clickSearchButton() - peopleListPage.typeSearchInput(gradedStudent.name) + peopleListPage.searchable.clickOnSearchButton() + peopleListPage.searchable.typeToSearchBar(gradedStudent.name) Log.d(STEP_TAG, "Assert that only 1 person matches for the search text, and it is '${gradedStudent.name}', the graded student.") peopleListPage.assertSearchResultCount(1) peopleListPage.assertPersonListed(gradedStudent) - Log.d(STEP_TAG, "Click on 'Reset' search (cross) icon and assert that all the poeple are displayed (5).") - peopleListPage.clickResetSearchText() + Log.d(STEP_TAG, "Click on 'Reset' search (X) icon and assert that all the poeple are displayed (5).") + peopleListPage.searchable.clickOnClearSearchButton() peopleListPage.assertSearchResultCount(5) Log.d(STEP_TAG, "Navigate back to Dashboard Page. Click on the Inbox bottom menu. Assert that the 'All' section is empty.") diff --git a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/pages/AnnouncementsListPage.kt b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/pages/AnnouncementsListPage.kt index be005e6b5e..d8c9ad7b7f 100644 --- a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/pages/AnnouncementsListPage.kt +++ b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/pages/AnnouncementsListPage.kt @@ -17,14 +17,13 @@ package com.instructure.teacher.ui.pages import androidx.test.espresso.Espresso -import androidx.test.espresso.action.ViewActions import androidx.test.espresso.assertion.ViewAssertions import androidx.test.espresso.matcher.ViewMatchers import com.instructure.canvasapi2.models.DiscussionTopicHeader import com.instructure.dataseeding.model.DiscussionApiModel import com.instructure.espresso.OnViewWithId import com.instructure.espresso.RecyclerViewItemCountAssertion -import com.instructure.espresso.WaitForViewWithId +import com.instructure.espresso.Searchable import com.instructure.espresso.assertDisplayed import com.instructure.espresso.click import com.instructure.espresso.page.BasePage @@ -32,7 +31,6 @@ import com.instructure.espresso.page.onView import com.instructure.espresso.page.onViewWithContentDescription import com.instructure.espresso.page.onViewWithText import com.instructure.espresso.page.plus -import com.instructure.espresso.page.waitForView import com.instructure.espresso.page.waitForViewWithText import com.instructure.espresso.page.withAncestor import com.instructure.espresso.page.withId @@ -48,13 +46,11 @@ import com.instructure.teacher.ui.utils.TypeInRCETextEditor * * @constructor Create empty Announcements list page */ -class AnnouncementsListPage : BasePage() { +class AnnouncementsListPage(val searchable: Searchable) : BasePage() { private val announcementListToolbar by OnViewWithId(R.id.discussionListToolbar) private val announcementsFAB by OnViewWithId(R.id.createNewDiscussion) private val announcementsRecyclerView by OnViewWithId(R.id.discussionRecyclerView) - private val searchButton by OnViewWithId(R.id.search) - private val searchInput by WaitForViewWithId(androidx.appcompat.R.id.search_src_text) private val createNewDiscussion by OnViewWithId(R.id.createNewDiscussion) /** @@ -110,23 +106,6 @@ class AnnouncementsListPage : BasePage() { announcementsFAB.assertDisplayed() } - /** - * Click on search button. - * - */ - fun openSearch() { - searchButton.click() - } - - /** - * Fill the search input field with the given query string. - * - * @param query: Query string parameter. - */ - fun enterSearchQuery(query: String) { - searchInput.perform(ViewActions.replaceText(query)) - } - /** * Assert that the announcements recyclerview count is equals to the given one. * @@ -206,31 +185,6 @@ class AnnouncementsListPage : BasePage() { onViewWithText(R.string.exitUnsaved).click() } - /** - * Click search button. - * - */ - fun clickSearchButton() { - onView(withId(R.id.search)).click() - } - - /** - * Type the given search text into the search input field. - * - * @param searchText: The search text query parameter. - */ - fun typeSearchInput(searchText: String) { - onView(withId(R.id.search_src_text)).replaceText(searchText.dropLast(1)) - } - - /** - * Click reset search text. - * - */ - fun clickResetSearchText() { - waitForView(withId(R.id.search_close_btn)).click() - } - /** * Assert search result count is equals to the expected. * diff --git a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/pages/DiscussionsListPage.kt b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/pages/DiscussionsListPage.kt index 87394c2577..f6f8b9848c 100644 --- a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/pages/DiscussionsListPage.kt +++ b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/pages/DiscussionsListPage.kt @@ -16,14 +16,13 @@ */ package com.instructure.teacher.ui.pages -import androidx.test.espresso.action.ViewActions import androidx.test.espresso.assertion.ViewAssertions.doesNotExist import androidx.test.espresso.matcher.ViewMatchers import com.instructure.canvasapi2.models.DiscussionTopicHeader import com.instructure.dataseeding.model.DiscussionApiModel import com.instructure.espresso.OnViewWithId import com.instructure.espresso.RecyclerViewItemCountAssertion -import com.instructure.espresso.WaitForViewWithId +import com.instructure.espresso.Searchable import com.instructure.espresso.assertDisplayed import com.instructure.espresso.click import com.instructure.espresso.page.BasePage @@ -43,13 +42,11 @@ import com.instructure.teacher.R /** * Represents the Discussions List page. */ -class DiscussionsListPage : BasePage() { +class DiscussionsListPage(val searchable: Searchable) : BasePage() { private val discussionListToolbar by OnViewWithId(R.id.discussionListToolbar) private val discussionsFAB by OnViewWithId(R.id.createNewDiscussion) private val discussionsRecyclerView by OnViewWithId(R.id.discussionRecyclerView) - private val searchButton by OnViewWithId(R.id.search) - private val searchInput by WaitForViewWithId(androidx.appcompat.R.id.search_src_text) /** * Clicks on the specified [discussion] in the discussions list. @@ -112,29 +109,13 @@ class DiscussionsListPage : BasePage() { waitForViewWithText(discussion.title!!).assertDisplayed() } - /** - * Opens the search functionality in the discussions list. - */ - fun openSearch() { - searchButton.click() - } - - /** - * Enters the specified [query] into the search input field. - * - * @param query The search query to be entered. - */ - fun enterSearchQuery(query: String) { - searchInput.perform(ViewActions.replaceText(query)) - } - /** * Asserts the number of discussions in the discussions list. * * @param count The expected number of discussions. */ fun assertDiscussionCount(count: Int) { - discussionsRecyclerView.waitForCheck(RecyclerViewItemCountAssertion(count)) + discussionsRecyclerView.waitForCheck(RecyclerViewItemCountAssertion(count + 1)) //Because of the header. } /** diff --git a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/pages/FileListPage.kt b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/pages/FileListPage.kt index 49b03d3e4a..52634c0ee2 100644 --- a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/pages/FileListPage.kt +++ b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/pages/FileListPage.kt @@ -28,6 +28,7 @@ import com.instructure.canvas.espresso.containsTextCaseInsensitive import com.instructure.canvas.espresso.scrollRecyclerView import com.instructure.canvas.espresso.withCustomConstraints import com.instructure.espresso.OnViewWithId +import com.instructure.espresso.Searchable import com.instructure.espresso.assertDisplayed import com.instructure.espresso.clearText import com.instructure.espresso.click @@ -37,7 +38,6 @@ import com.instructure.espresso.page.plus import com.instructure.espresso.page.waitForView import com.instructure.espresso.page.withAncestor import com.instructure.espresso.page.withId -import com.instructure.espresso.replaceText import com.instructure.espresso.scrollTo import com.instructure.espresso.typeText import com.instructure.teacher.R @@ -54,7 +54,7 @@ import org.hamcrest.Matchers.allOf * * @constructor Creates an instance of the FileListPage class. */ -class FileListPage : BasePage(R.id.fileListPage) { +class FileListPage(val searchable: Searchable) : BasePage(R.id.fileListPage) { private val addButton by OnViewWithId(R.id.addFab) private val uploadFileButton by OnViewWithId(R.id.addFileFab, autoAssert = false) @@ -169,30 +169,6 @@ class FileListPage : BasePage(R.id.fileListPage) { onView(allOf(isAssignableFrom(AppCompatButton::class.java), containsTextCaseInsensitive("DELETE"), isDisplayed())).click() } - /** - * Clicks the search button. - */ - fun clickSearchButton() { - onView(withId(R.id.search)).click() - } - - /** - * Types the specified search text into the search input field. - * - * @param searchText The text to be typed in the search input field. - */ - fun typeSearchInput(searchText: String) { - onView(withId(R.id.queryInput)).replaceText(searchText) - } - - /** - * Clicks the reset search text button. - */ - fun clickResetSearchText() { - waitForView(withId(R.id.clearButton)).click() - onView(withId(R.id.backButton)).click() - } - /** * Asserts the count of search results matches the expected count. * @@ -216,11 +192,4 @@ class FileListPage : BasePage(R.id.fileListPage) { ViewAssertions.matches(hasChildCount(expectedCount)) ) } - - /** - * Presses the back button in the search view. - */ - fun pressSearchBackButton() { - onView(withId(R.id.backButton)).click() - } } diff --git a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/pages/PageListPage.kt b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/pages/PageListPage.kt index 6704501117..a42d4c9639 100644 --- a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/pages/PageListPage.kt +++ b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/pages/PageListPage.kt @@ -17,14 +17,13 @@ package com.instructure.teacher.ui.pages import android.view.View import androidx.test.espresso.Espresso -import androidx.test.espresso.action.ViewActions import androidx.test.espresso.matcher.ViewMatchers.hasSibling import androidx.test.espresso.matcher.ViewMatchers.withContentDescription import com.instructure.canvas.espresso.scrollRecyclerView import com.instructure.canvasapi2.models.Page import com.instructure.espresso.OnViewWithId import com.instructure.espresso.RecyclerViewItemCountAssertion -import com.instructure.espresso.WaitForViewWithId +import com.instructure.espresso.Searchable import com.instructure.espresso.assertDisplayed import com.instructure.espresso.click import com.instructure.espresso.page.BasePage @@ -44,11 +43,7 @@ import org.hamcrest.Matchers.containsString * This page extends the BasePage class and provides functionality for interacting with the elements on the "Page List" page. * It contains methods for clicking on the create new page button, opening a page, performing a search, and asserting various page-related conditions. */ -class PageListPage : BasePage() { - - private val searchButton by OnViewWithId(R.id.search) - - private val searchInput by WaitForViewWithId(androidx.appcompat.R.id.search_src_text) +class PageListPage(val searchable: Searchable) : BasePage() { private val pageRecyclerView by OnViewWithId(R.id.pageRecyclerView) @@ -81,22 +76,6 @@ class PageListPage : BasePage() { onView(matcher).click() } - /** - * Opens the search bar. - */ - fun openSearch() { - searchButton.click() - } - - /** - * Enters the search query in the search bar. - * - * @param query The search query to be entered. - */ - fun enterSearchQuery(query: String) { - searchInput.perform(ViewActions.replaceText(query)) - } - /** * Asserts the number of pages in the page list. * diff --git a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/pages/PeopleListPage.kt b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/pages/PeopleListPage.kt index 009486633f..a9458e6012 100644 --- a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/pages/PeopleListPage.kt +++ b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/pages/PeopleListPage.kt @@ -23,6 +23,7 @@ import androidx.test.espresso.matcher.ViewMatchers import androidx.test.espresso.matcher.ViewMatchers.hasChildCount import androidx.test.espresso.matcher.ViewMatchers.hasSibling import com.instructure.dataseeding.model.CanvasUserApiModel +import com.instructure.espresso.Searchable import com.instructure.espresso.assertDisplayed import com.instructure.espresso.click import com.instructure.espresso.page.BasePage @@ -33,7 +34,6 @@ import com.instructure.espresso.page.waitForViewWithText import com.instructure.espresso.page.withAncestor import com.instructure.espresso.page.withId import com.instructure.espresso.page.withText -import com.instructure.espresso.replaceText import com.instructure.teacher.R import org.hamcrest.Matcher import org.hamcrest.Matchers @@ -45,7 +45,7 @@ import org.hamcrest.Matchers * It contains methods for clicking on a person, asserting the presence of a person in the list with optional role filtering, asserting the search result count, * scrolling to a specific person, performing search actions, and asserting the visibility of the empty view and person role. */ -class PeopleListPage : BasePage(R.id.peopleListPage) { +class PeopleListPage(val searchable: Searchable) : BasePage(R.id.peopleListPage) { /** * Clicks on a person in the list. @@ -113,29 +113,6 @@ class PeopleListPage : BasePage(R.id.peopleListPage) { ) } - /** - * Clicks the search button. - */ - fun clickSearchButton() { - onView(withId(R.id.search)).click() - } - - /** - * Enters the search text. - * - * @param searchText The text to enter in the search input. - */ - fun typeSearchInput(searchText: String) { - onView(withId(R.id.search_src_text)).replaceText(searchText) - } - - /** - * Clicks the reset search text button. - */ - fun clickResetSearchText() { - waitForView(withId(R.id.search_close_btn)).click() - } - /** * Asserts that the empty view is displayed. */ diff --git a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/pages/QuizListPage.kt b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/pages/QuizListPage.kt index 1e32f11b1c..1068d36295 100644 --- a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/pages/QuizListPage.kt +++ b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/pages/QuizListPage.kt @@ -16,10 +16,10 @@ */ package com.instructure.teacher.ui.pages -import androidx.test.espresso.action.ViewActions import com.instructure.canvasapi2.models.Quiz import com.instructure.espresso.OnViewWithId import com.instructure.espresso.RecyclerViewItemCountAssertion +import com.instructure.espresso.Searchable import com.instructure.espresso.WaitForViewWithId import com.instructure.espresso.assertDisplayed import com.instructure.espresso.click @@ -39,7 +39,7 @@ import com.instructure.teacher.R * Additionally, it provides methods for asserting the display of the "No Quizzes" view, checking the presence of a quiz, clicking on a quiz, opening the search bar, entering a search query, * asserting the quiz count, and refreshing the page. */ -class QuizListPage : BasePage() { +class QuizListPage(val searchable: Searchable) : BasePage() { /** * The quiz list toolbar view on the page. @@ -100,22 +100,6 @@ class QuizListPage : BasePage() { waitForViewWithText(quizTitle).click() } - /** - * Opens the search bar. - */ - fun openSearch() { - searchButton.click() - } - - /** - * Enters a search query in the search input. - * - * @param query The search query to be entered. - */ - fun enterSearchQuery(query: String) { - searchInput.perform(ViewActions.replaceText(query)) - } - /** * Asserts the count of quizzes on the page. * diff --git a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/utils/TeacherTest.kt b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/utils/TeacherTest.kt index d80b8e4783..7dafc5a3ab 100644 --- a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/utils/TeacherTest.kt +++ b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/utils/TeacherTest.kt @@ -25,7 +25,9 @@ import androidx.test.espresso.ViewAction import androidx.test.espresso.matcher.ViewMatchers import com.instructure.canvas.espresso.CanvasTest import com.instructure.espresso.InstructureActivityTestRule +import com.instructure.espresso.Searchable import com.instructure.teacher.BuildConfig +import com.instructure.teacher.R import com.instructure.teacher.activities.LoginActivity import com.instructure.teacher.ui.espresso.TeacherHiltTestApplication_Application import com.instructure.teacher.ui.pages.AboutPage @@ -121,7 +123,7 @@ abstract class TeacherTest : CanvasTest() { * Required for auto complete of page objects within tests */ val addMessagePage = AddMessagePage() - val announcementsListPage = AnnouncementsListPage() + val announcementsListPage = AnnouncementsListPage(Searchable(R.id.search, R.id.search_src_text, R.id.search_close_btn)) val assigneeListPage = AssigneeListPage() val assignmentDetailsPage = AssignmentDetailsPage() val assignmentDueDatesPage = AssignmentDueDatesPage() @@ -144,7 +146,7 @@ abstract class TeacherTest : CanvasTest() { val profileSettingsPage = ProfileSettingsPage() val editProfileSettingsPage = EditProfileSettingsPage() val discussionsDetailsPage = DiscussionsDetailsPage() - val discussionsListPage = DiscussionsListPage() + val discussionsListPage = DiscussionsListPage(Searchable(R.id.search, R.id.search_src_text, R.id.search_close_btn)) val editAnnouncementPage = EditAnnouncementPage() val editAssignmentDetailsPage = EditAssignmentDetailsPage() val editDiscussionsDetailsPage = EditDiscussionsDetailsPage() @@ -159,10 +161,10 @@ abstract class TeacherTest : CanvasTest() { val modulesPage = ModulesPage() val navDrawerPage = NavDrawerPage() val notATeacherPage = NotATeacherPage() - val pageListPage = PageListPage() - val peopleListPage = PeopleListPage() + val pageListPage = PageListPage(Searchable(R.id.search, R.id.search_src_text, R.id.search_close_btn)) + val peopleListPage = PeopleListPage(Searchable(R.id.search, R.id.search_src_text, R.id.search_close_btn)) val quizDetailsPage = QuizDetailsPage() - val quizListPage = QuizListPage() + val quizListPage = QuizListPage(Searchable(R.id.search, R.id.search_src_text, R.id.clearButton, R.id.backButton)) val quizSubmissionListPage = QuizSubmissionListPage() val speedGraderCommentsPage = SpeedGraderCommentsPage() val speedGraderFilesPage = SpeedGraderFilesPage() @@ -174,7 +176,7 @@ abstract class TeacherTest : CanvasTest() { val syllabusPage = SyllabusPage() val todoPage = TodoPage() val webViewLoginPage = WebViewLoginPage() - val fileListPage = FileListPage() + val fileListPage = FileListPage(Searchable(R.id.search, R.id.queryInput, R.id.clearButton, R.id.backButton)) } diff --git a/automation/espresso/src/main/kotlin/com/instructure/espresso/CustomViewAssertions.kt b/automation/espresso/src/main/kotlin/com/instructure/espresso/CustomViewAssertions.kt index a6248e7e21..a9c27b5bc9 100644 --- a/automation/espresso/src/main/kotlin/com/instructure/espresso/CustomViewAssertions.kt +++ b/automation/espresso/src/main/kotlin/com/instructure/espresso/CustomViewAssertions.kt @@ -23,9 +23,11 @@ import androidx.annotation.IdRes import androidx.recyclerview.widget.RecyclerView import androidx.test.espresso.NoMatchingViewException import androidx.test.espresso.ViewAssertion +import androidx.test.espresso.assertion.ViewAssertions.doesNotExist import androidx.test.espresso.matcher.ViewMatchers import androidx.viewpager.widget.ViewPager import com.google.android.material.bottomnavigation.BottomNavigationView +import junit.framework.AssertionFailedError import org.hamcrest.Matchers import org.junit.Assert.assertEquals @@ -74,3 +76,21 @@ class NotificationBadgeAssertion(@IdRes private val menuItemId: Int, private val assertEquals(badgeCount, expectedCount) } } + +class DoesNotExistAssertion(private val timeout: Long, private val pollInterval: Long = 500L) : ViewAssertion { + override fun check(view: View?, noViewFoundException: NoMatchingViewException?) { + var elapsedTime = 0L + + while (elapsedTime < timeout) { + try { + doesNotExist() + return + } catch (e: AssertionFailedError) { + Thread.sleep(pollInterval) + elapsedTime += pollInterval + } + } + + throw AssertionError("View still exists after $timeout milliseconds.") + } +} \ No newline at end of file diff --git a/automation/espresso/src/main/kotlin/com/instructure/espresso/Searchable.kt b/automation/espresso/src/main/kotlin/com/instructure/espresso/Searchable.kt new file mode 100644 index 0000000000..b8d5902141 --- /dev/null +++ b/automation/espresso/src/main/kotlin/com/instructure/espresso/Searchable.kt @@ -0,0 +1,25 @@ +package com.instructure.espresso + +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.action.ViewActions +import androidx.test.espresso.matcher.ViewMatchers.withId +import com.instructure.espresso.matchers.WaitForViewMatcher.waitForView + +class Searchable(private val searchButtonId: Int? = null, private val queryInputId: Int? = null, private val clearButtonId: Int? = null, private val backButtonId: Int? = null) { + + fun clickOnSearchButton() { + onView(searchButtonId?.let { withId(it) }).click() + } + + fun typeToSearchBar(textToType: String) { + onView(queryInputId?.let { withId(it) }).perform(ViewActions.replaceText(textToType)) + } + + fun clickOnClearSearchButton() { + waitForView(clearButtonId?.let { withId(it) }).click() + } + + fun pressSearchBackButton() { + onView(backButtonId?.let { withId(it) }).click() + } +} \ No newline at end of file diff --git a/automation/espresso/src/main/kotlin/com/instructure/espresso/matchers/WaitForViewMatcher.kt b/automation/espresso/src/main/kotlin/com/instructure/espresso/matchers/WaitForViewMatcher.kt index c31c9a5dd9..0d543a6b25 100644 --- a/automation/espresso/src/main/kotlin/com/instructure/espresso/matchers/WaitForViewMatcher.kt +++ b/automation/espresso/src/main/kotlin/com/instructure/espresso/matchers/WaitForViewMatcher.kt @@ -41,9 +41,9 @@ object WaitForViewMatcher { // https://github.com/braintree/braintree_android/blob/25513d76da88fe2ce9f476c4dc51f24cf6e26104/TestUtils/src/main/java/com/braintreepayments/testutils/ui/ViewHelper.java#L30 // The viewMatcher is called on every view to determine what matches. Must be fast! - fun waitForView(viewMatcher: Matcher, duration: Long = 10): ViewInteraction { + fun waitForView(viewMatcher: Matcher?, duration: Long = 10): ViewInteraction { log.i("Wait for View to be visible.") - return waitForViewWithCustomMatcher(viewMatcher, duration, withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)) + return waitForViewWithCustomMatcher(viewMatcher!!, duration, withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)) } fun waitForViewToBeClickable(viewMatcher: Matcher, duration: Long = 10): ViewInteraction { From eb0592658766c61e86541d526004afb666873e6a Mon Sep 17 00:00:00 2001 From: Tamas Kozmer Date: Tue, 15 Aug 2023 15:06:50 +0200 Subject: [PATCH 03/22] Updated version --- apps/student/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/student/build.gradle b/apps/student/build.gradle index 43afe3bf59..bc4c0c3bec 100644 --- a/apps/student/build.gradle +++ b/apps/student/build.gradle @@ -50,8 +50,8 @@ android { applicationId "com.instructure.candroid" minSdkVersion Versions.MIN_SDK targetSdkVersion Versions.TARGET_SDK - versionCode = 253 - versionName = '6.25.1' + versionCode = 254 + versionName = '6.26.0' vectorDrawables.useSupportLibrary = true multiDexEnabled = true From 61167ca85ce0e8133c822b86c742f70efda61bbb Mon Sep 17 00:00:00 2001 From: Tamas Kozmer Date: Wed, 16 Aug 2023 10:03:32 +0200 Subject: [PATCH 04/22] Landscape test fixes. --- .../student/ui/pages/AssignmentListPage.kt | 4 +++- .../com/instructure/student/ui/pages/ModulesPage.kt | 11 +++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/apps/student/src/androidTest/java/com/instructure/student/ui/pages/AssignmentListPage.kt b/apps/student/src/androidTest/java/com/instructure/student/ui/pages/AssignmentListPage.kt index 6244425c93..bb5a6ef6b5 100644 --- a/apps/student/src/androidTest/java/com/instructure/student/ui/pages/AssignmentListPage.kt +++ b/apps/student/src/androidTest/java/com/instructure/student/ui/pages/AssignmentListPage.kt @@ -93,7 +93,9 @@ class AssignmentListPage(val searchable: Searchable) : BasePage(pageResId = R.id } fun assertAssignmentDisplayedWithGrade(assignmentName: String, gradeString: String) { - onView(withId(R.id.title) + withParent(R.id.textContainer) + withText(assignmentName)).assertDisplayed() + val matcher = withId(R.id.title) + withParent(R.id.textContainer) + withText(assignmentName) + scrollRecyclerView(R.id.listView, matcher) + onView(matcher).assertDisplayed() val pointsMatcher = withId(R.id.title) + withText(assignmentName) onView(withId(R.id.points) + withParent(hasSibling(pointsMatcher))).assertHasText(gradeString) } diff --git a/apps/student/src/androidTest/java/com/instructure/student/ui/pages/ModulesPage.kt b/apps/student/src/androidTest/java/com/instructure/student/ui/pages/ModulesPage.kt index b6e915e336..0dc2cd51cd 100644 --- a/apps/student/src/androidTest/java/com/instructure/student/ui/pages/ModulesPage.kt +++ b/apps/student/src/androidTest/java/com/instructure/student/ui/pages/ModulesPage.kt @@ -19,6 +19,7 @@ package com.instructure.student.ui.pages import androidx.test.espresso.NoMatchingViewException import androidx.test.espresso.PerformException import androidx.test.espresso.action.ViewActions.swipeDown +import androidx.test.espresso.action.ViewActions.swipeUp import androidx.test.espresso.assertion.ViewAssertions.doesNotExist import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.ViewMatchers.* @@ -87,11 +88,17 @@ class ModulesPage : BasePage(R.id.modulesPage) { } fun assertPossiblePointsDisplayed(points: String) { - onView(withId(R.id.points) + withText("$points pts")).assertDisplayed() + val matcher = withId(R.id.points) + withText("$points pts") + + scrollRecyclerView(R.id.listView, matcher) + onView(matcher).assertDisplayed() } fun assertPossiblePointsNotDisplayed(name: String) { - onView(withParent(hasSibling(withChild(withId(R.id.title) + withText(name)))) + withId(R.id.points)).assertNotDisplayed() + val matcher = withParent(hasSibling(withChild(withId(R.id.title) + withText(name)))) + withId(R.id.points) + + scrollRecyclerView(R.id.listView, matcher) + onView(matcher).assertNotDisplayed() } /** From 155fab52499cbc9e440d61f178373239e361c4af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81kos=20Hermann?= Date: Wed, 16 Aug 2023 16:23:06 +0200 Subject: [PATCH 05/22] fix foreground notifications --- .../file/download/FileDownloadWorker.kt | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/libs/pandautils/src/main/java/com/instructure/pandautils/features/file/download/FileDownloadWorker.kt b/libs/pandautils/src/main/java/com/instructure/pandautils/features/file/download/FileDownloadWorker.kt index f8fb695dd3..954d39fdd5 100644 --- a/libs/pandautils/src/main/java/com/instructure/pandautils/features/file/download/FileDownloadWorker.kt +++ b/libs/pandautils/src/main/java/com/instructure/pandautils/features/file/download/FileDownloadWorker.kt @@ -51,11 +51,13 @@ class FileDownloadWorker @AssistedInject constructor( private val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager - override suspend fun doWork(): Result { - val fileName = inputData.getString(INPUT_FILE_NAME) ?: "" - val fileUrl = inputData.getString(INPUT_FILE_URL) ?: "" - val notificationId = Random.nextInt() + private val fileName = inputData.getString(INPUT_FILE_NAME) ?: "" + private val fileUrl = inputData.getString(INPUT_FILE_URL) ?: "" + private val notificationId = Random.nextInt() + + private var foregroundInfo: ForegroundInfo = createForegroundInfo(notificationId, fileName, 0) + override suspend fun doWork(): Result { registerNotificationChannel(context) val downloadFileName = createDownloadFileName(fileName) @@ -63,14 +65,21 @@ class FileDownloadWorker @AssistedInject constructor( val downloadedFile = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), downloadFileName) - setForeground(createForegroundInfo(notificationId, fileName, 0)) + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) { + setForeground(foregroundInfo) + } var result = Result.retry() fileDownloadApi.downloadFile(fileUrl).saveFile(downloadedFile) .collect { downloadState -> when (downloadState) { is DownloadState.InProgress -> { - setForeground(createForegroundInfo(notificationId, fileName, downloadState.progress)) + foregroundInfo = createForegroundInfo(notificationId, fileName, downloadState.progress) + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) { + setForeground(foregroundInfo) + } else { + updateForegroundNotification() + } } is DownloadState.Failure -> { @@ -138,8 +147,6 @@ class FileDownloadWorker @AssistedInject constructor( val notification = NotificationCompat.Builder(applicationContext, FileUploadWorker.CHANNEL_ID) .setSmallIcon(R.drawable.ic_notification_canvas_logo) - .setProgress(100, 100, false) - .setOngoing(false) .setContentTitle(context.getString(R.string.downloadSuccessful)) .setContentText(fileName) .setContentIntent(pendingIntent) @@ -150,14 +157,20 @@ class FileDownloadWorker @AssistedInject constructor( private fun updateNotificationFailed(notificationId: Int, fileName: String) { val notification = NotificationCompat.Builder(applicationContext, FileUploadWorker.CHANNEL_ID) .setSmallIcon(R.drawable.ic_notification_canvas_logo) - .setProgress(100, 100, false) - .setOngoing(false) .setContentTitle(context.getString(R.string.downloadFailed)) .setContentText(fileName) .build() notificationManager.notify(notificationId + 1, notification) } + override suspend fun getForegroundInfo(): ForegroundInfo { + return foregroundInfo + } + + private fun updateForegroundNotification() { + notificationManager.notify(notificationId, foregroundInfo.notification) + } + companion object { const val INPUT_FILE_NAME = "fileName" const val INPUT_FILE_URL = "fileUrl" From cd575704fa1d6c2a1188574612ef3a052fb03880 Mon Sep 17 00:00:00 2001 From: Kristof Deak <92309696+kdeakinstructure@users.noreply.github.com> Date: Sat, 19 Aug 2023 20:38:31 +0200 Subject: [PATCH 06/22] [MBL-16737][Student] - Implement not favorited group interaction test on dashboard (#2105) --- .../interaction/GroupLinksInteractionTest.kt | 37 ++++++++++++++++++- .../student/ui/pages/DashboardPage.kt | 9 +++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/apps/student/src/androidTest/java/com/instructure/student/ui/interaction/GroupLinksInteractionTest.kt b/apps/student/src/androidTest/java/com/instructure/student/ui/interaction/GroupLinksInteractionTest.kt index 79c3f4a137..aa1c84ccdf 100644 --- a/apps/student/src/androidTest/java/com/instructure/student/ui/interaction/GroupLinksInteractionTest.kt +++ b/apps/student/src/androidTest/java/com/instructure/student/ui/interaction/GroupLinksInteractionTest.kt @@ -25,6 +25,7 @@ import com.instructure.canvas.espresso.mockCanvas.addFolderToCourse import com.instructure.canvas.espresso.mockCanvas.addGroupToCourse import com.instructure.canvas.espresso.mockCanvas.addPageToCourse import com.instructure.canvas.espresso.mockCanvas.init +import com.instructure.canvas.espresso.refresh import com.instructure.canvasapi2.models.Course import com.instructure.canvasapi2.models.DiscussionTopicHeader import com.instructure.canvasapi2.models.Group @@ -72,6 +73,38 @@ class GroupLinksInteractionTest : StudentTest() { dashboardPage.assertDisplaysGroup(group, course) } + // Test not favorite group on dashboard + @Test + @TestMetaData(Priority.IMPORTANT, FeatureCategory.GROUPS, TestCategory.INTERACTION, false, SecondaryFeatureCategory.GROUPS_DASHBOARD) + fun testGroupLink_dashboard_favoriteLogics() { + val data = setUpGroupAndSignIn() + val user = data.users.values.first() + val nonFavoriteGroup = data.addGroupToCourse( + course = course, + members = listOf(user), + isFavorite = false + ) + refresh() //Need to refresh because when we navigated to Dashboard page the nonFavoriteGroup was not existed yet. (However it won't be displayed because it's not favorite) + dashboardPage.assertGroupNotDisplayed(nonFavoriteGroup) + dashboardPage.assertDisplaysGroup(group, course) + } + + // Test that if no groups has selected as favorite then we display all groups + @Test + @TestMetaData(Priority.IMPORTANT, FeatureCategory.GROUPS, TestCategory.INTERACTION, false, SecondaryFeatureCategory.GROUPS_DASHBOARD) + fun testGroupLink_dashboard_not_selected_displays_all() { + val data = setUpGroupAndSignIn(isFavorite = false) + val user = data.users.values.first() + val group2 = data.addGroupToCourse( + course = course, + members = listOf(user), + isFavorite = false + ) + refresh() //Need to refresh because when we navigated to Dashboard page the group2 was not existed yet. + dashboardPage.assertDisplaysGroup(group, course) + dashboardPage.assertDisplaysGroup(group2, course) + } + // Link to file preview opens file - eg: "/groups/:id/files/folder/:id?preview=:id" @Test @TestMetaData(Priority.MANDATORY, FeatureCategory.GROUPS, TestCategory.INTERACTION, false, SecondaryFeatureCategory.GROUPS_FILES) @@ -196,7 +229,7 @@ class GroupLinksInteractionTest : StudentTest() { // Mock a single student and course, mock a group and a number of items associated with the group, // sign in, then navigate to the dashboard. - private fun setUpGroupAndSignIn(): MockCanvas { + private fun setUpGroupAndSignIn(isFavorite: Boolean = true): MockCanvas { // Basic info val data = MockCanvas.init( @@ -211,7 +244,7 @@ class GroupLinksInteractionTest : StudentTest() { group = data.addGroupToCourse( course = course, members = listOf(user), - isFavorite = true + isFavorite = isFavorite ) // Add a discussion diff --git a/apps/student/src/androidTest/java/com/instructure/student/ui/pages/DashboardPage.kt b/apps/student/src/androidTest/java/com/instructure/student/ui/pages/DashboardPage.kt index 229d1253ee..caa43663b0 100644 --- a/apps/student/src/androidTest/java/com/instructure/student/ui/pages/DashboardPage.kt +++ b/apps/student/src/androidTest/java/com/instructure/student/ui/pages/DashboardPage.kt @@ -279,6 +279,15 @@ class DashboardPage : BasePage(R.id.dashboardPage) { onView(matcher).check(doesNotExist()) } + fun assertGroupNotDisplayed(group: Group) { + val matcher = allOf( + withText(group.name), + withId(R.id.titleTextView), + withAncestor(R.id.swipeRefreshLayout) + ) + onView(matcher).check(doesNotExist()) + } + fun changeCourseNickname(changeTo: String) { onView(withId(R.id.newCourseNickname)).replaceText(changeTo) onView(withText(android.R.string.ok) + withAncestor(R.id.buttonPanel)).click() From 02930945abface39174a3a16bf9dd4cd790ac051 Mon Sep 17 00:00:00 2001 From: Tamas Kozmer <72397075+tamaskozmer@users.noreply.github.com> Date: Tue, 22 Aug 2023 09:52:12 +0200 Subject: [PATCH 07/22] [MBL-16983][Student][Teacher] Login help text change #2112 refs: MBL-16983 affects: Teacher, Student release note: none --- libs/login-api-2/src/main/res/layout/adapter_account_footer.xml | 2 +- libs/login-api-2/src/main/res/values-ar/strings.xml | 1 - .../login-api-2/src/main/res/values-b+da+DK+instk12/strings.xml | 1 - .../login-api-2/src/main/res/values-b+en+AU+unimelb/strings.xml | 1 - .../src/main/res/values-b+en+GB+instukhe/strings.xml | 1 - .../login-api-2/src/main/res/values-b+nb+NO+instk12/strings.xml | 1 - .../login-api-2/src/main/res/values-b+sv+SE+instk12/strings.xml | 1 - libs/login-api-2/src/main/res/values-b+zh+HK/strings.xml | 1 - libs/login-api-2/src/main/res/values-b+zh+Hans/strings.xml | 1 - libs/login-api-2/src/main/res/values-b+zh+Hant/strings.xml | 1 - libs/login-api-2/src/main/res/values-ca/strings.xml | 1 - libs/login-api-2/src/main/res/values-cy/strings.xml | 1 - libs/login-api-2/src/main/res/values-da/strings.xml | 1 - libs/login-api-2/src/main/res/values-de/strings.xml | 1 - libs/login-api-2/src/main/res/values-en-rAU/strings.xml | 1 - libs/login-api-2/src/main/res/values-en-rCA/strings.xml | 1 - libs/login-api-2/src/main/res/values-en-rCY/strings.xml | 1 - libs/login-api-2/src/main/res/values-en-rGB/strings.xml | 1 - libs/login-api-2/src/main/res/values-es-rES/strings.xml | 1 - libs/login-api-2/src/main/res/values-es/strings.xml | 1 - libs/login-api-2/src/main/res/values-fi/strings.xml | 1 - libs/login-api-2/src/main/res/values-fr-rCA/strings.xml | 1 - libs/login-api-2/src/main/res/values-fr/strings.xml | 1 - libs/login-api-2/src/main/res/values-ht/strings.xml | 1 - libs/login-api-2/src/main/res/values-is/strings.xml | 1 - libs/login-api-2/src/main/res/values-it/strings.xml | 1 - libs/login-api-2/src/main/res/values-ja/strings.xml | 1 - libs/login-api-2/src/main/res/values-mi/strings.xml | 1 - libs/login-api-2/src/main/res/values-ms/strings.xml | 1 - libs/login-api-2/src/main/res/values-nb/strings.xml | 1 - libs/login-api-2/src/main/res/values-nl/strings.xml | 1 - libs/login-api-2/src/main/res/values-pl/strings.xml | 1 - libs/login-api-2/src/main/res/values-pt-rBR/strings.xml | 1 - libs/login-api-2/src/main/res/values-pt-rPT/strings.xml | 1 - libs/login-api-2/src/main/res/values-ru/strings.xml | 1 - libs/login-api-2/src/main/res/values-sl/strings.xml | 1 - libs/login-api-2/src/main/res/values-sv/strings.xml | 1 - libs/login-api-2/src/main/res/values-th/strings.xml | 1 - libs/login-api-2/src/main/res/values-vi/strings.xml | 1 - libs/login-api-2/src/main/res/values-zh/strings.xml | 1 - libs/login-api-2/src/main/res/values/strings.xml | 2 +- 41 files changed, 2 insertions(+), 41 deletions(-) diff --git a/libs/login-api-2/src/main/res/layout/adapter_account_footer.xml b/libs/login-api-2/src/main/res/layout/adapter_account_footer.xml index d42dbae34d..380e298d7c 100644 --- a/libs/login-api-2/src/main/res/layout/adapter_account_footer.xml +++ b/libs/login-api-2/src/main/res/layout/adapter_account_footer.xml @@ -44,6 +44,6 @@ android:textColor="@color/textInfo" android:fontFamily="@font/lato_font_family" android:textSize="16sp" - android:text="@string/accountDomainFooterLink"/> + android:text="@string/accountDomainFooterLoginHelp"/> \ No newline at end of file diff --git a/libs/login-api-2/src/main/res/values-ar/strings.xml b/libs/login-api-2/src/main/res/values-ar/strings.xml index a6dc6fea19..23551097f6 100644 --- a/libs/login-api-2/src/main/res/values-ar/strings.xml +++ b/libs/login-api-2/src/main/res/values-ar/strings.xml @@ -109,7 +109,6 @@ school.instructure.com حذف المستخدم السابق ألا تستطيع العثور على مدرستك؟ حاول كتابة رابط URL الكامل للمدرسة. - اضغط هنا للحصول على المساعدة. لا يوجد اتصال بالإنترنت يتطلب هذا الإجراء اتصالاً بالإنترنت. diff --git a/libs/login-api-2/src/main/res/values-b+da+DK+instk12/strings.xml b/libs/login-api-2/src/main/res/values-b+da+DK+instk12/strings.xml index c14f873ae4..2f2c627f22 100644 --- a/libs/login-api-2/src/main/res/values-b+da+DK+instk12/strings.xml +++ b/libs/login-api-2/src/main/res/values-b+da+DK+instk12/strings.xml @@ -111,7 +111,6 @@ school.instructure.com Fjern forrige bruger Kan du ikke finde din skole? Prøv at indtaste skolens fulde URL. - Tryk her for at få hjælp. Ingen internetforbindelse Denne handling kræver en internetforbindelse. diff --git a/libs/login-api-2/src/main/res/values-b+en+AU+unimelb/strings.xml b/libs/login-api-2/src/main/res/values-b+en+AU+unimelb/strings.xml index 562a29b642..de85b5f2a0 100644 --- a/libs/login-api-2/src/main/res/values-b+en+AU+unimelb/strings.xml +++ b/libs/login-api-2/src/main/res/values-b+en+AU+unimelb/strings.xml @@ -109,7 +109,6 @@ school.instructure.com Remove Previous User Can\'t find your school? Try typing the full school URL. - Tap here for help. No Internet Connection This action requires an internet connection. diff --git a/libs/login-api-2/src/main/res/values-b+en+GB+instukhe/strings.xml b/libs/login-api-2/src/main/res/values-b+en+GB+instukhe/strings.xml index 2008cc1293..9ad8745705 100644 --- a/libs/login-api-2/src/main/res/values-b+en+GB+instukhe/strings.xml +++ b/libs/login-api-2/src/main/res/values-b+en+GB+instukhe/strings.xml @@ -111,7 +111,6 @@ school.instructure.com Remove Previous User Can\'t find your school? Try typing the full school URL. - Tap here for help. No Internet Connection This action requires an internet connection. diff --git a/libs/login-api-2/src/main/res/values-b+nb+NO+instk12/strings.xml b/libs/login-api-2/src/main/res/values-b+nb+NO+instk12/strings.xml index ec5a6c20af..527ce5beb1 100644 --- a/libs/login-api-2/src/main/res/values-b+nb+NO+instk12/strings.xml +++ b/libs/login-api-2/src/main/res/values-b+nb+NO+instk12/strings.xml @@ -110,7 +110,6 @@ school.instructure.com Fjerne forrige bruker Finner du ikke skolen din? Prøv å skrive hele skolens URL. - Trykk her for hjelp. Ingen Internett-tilkobling Denne handlingen krever Internett-tilkobling. diff --git a/libs/login-api-2/src/main/res/values-b+sv+SE+instk12/strings.xml b/libs/login-api-2/src/main/res/values-b+sv+SE+instk12/strings.xml index 6545349e99..cd28a78c01 100644 --- a/libs/login-api-2/src/main/res/values-b+sv+SE+instk12/strings.xml +++ b/libs/login-api-2/src/main/res/values-b+sv+SE+instk12/strings.xml @@ -111,7 +111,6 @@ school.instructure.com Ta bort tidigare användare Kan du inte hitta din skola? Försök att skriva in skolans fullständiga URL. - Tryck här för hjälp. Ingen internetanslutning Den här åtgärden kräver internetanslutning. diff --git a/libs/login-api-2/src/main/res/values-b+zh+HK/strings.xml b/libs/login-api-2/src/main/res/values-b+zh+HK/strings.xml index 7617208253..438733e270 100644 --- a/libs/login-api-2/src/main/res/values-b+zh+HK/strings.xml +++ b/libs/login-api-2/src/main/res/values-b+zh+HK/strings.xml @@ -109,7 +109,6 @@ school.instructure.com 移除先前使用者 找不到您的學校?請嘗試輸入學校完整URL。 - 點擊此處獲取支援。 沒有網絡連線 此動作需要網絡連線。 diff --git a/libs/login-api-2/src/main/res/values-b+zh+Hans/strings.xml b/libs/login-api-2/src/main/res/values-b+zh+Hans/strings.xml index 871b422f6d..72d0ea9c83 100644 --- a/libs/login-api-2/src/main/res/values-b+zh+Hans/strings.xml +++ b/libs/login-api-2/src/main/res/values-b+zh+Hans/strings.xml @@ -109,7 +109,6 @@ school.instructure.com 删除上一个用户 找不到您的学校?尝试键入完整的学校 URL。 - 轻击此处获取帮助。 无互联网连接 此操作需要互联网连接。 diff --git a/libs/login-api-2/src/main/res/values-b+zh+Hant/strings.xml b/libs/login-api-2/src/main/res/values-b+zh+Hant/strings.xml index 7617208253..438733e270 100644 --- a/libs/login-api-2/src/main/res/values-b+zh+Hant/strings.xml +++ b/libs/login-api-2/src/main/res/values-b+zh+Hant/strings.xml @@ -109,7 +109,6 @@ school.instructure.com 移除先前使用者 找不到您的學校?請嘗試輸入學校完整URL。 - 點擊此處獲取支援。 沒有網絡連線 此動作需要網絡連線。 diff --git a/libs/login-api-2/src/main/res/values-ca/strings.xml b/libs/login-api-2/src/main/res/values-ca/strings.xml index 36169a8672..6bbb991bd4 100644 --- a/libs/login-api-2/src/main/res/values-ca/strings.xml +++ b/libs/login-api-2/src/main/res/values-ca/strings.xml @@ -111,7 +111,6 @@ school.instructure.com Eliminar l\'usuari anterior No trobeu la vostra escola? Proveu d\'escriure l\'URL de l\'escola complet. - Toqueu aquí per obtenir ajuda. No hi ha cap connexió a Internet Per dur a terme aquesta acció cal tenir una connexió a Internet. diff --git a/libs/login-api-2/src/main/res/values-cy/strings.xml b/libs/login-api-2/src/main/res/values-cy/strings.xml index 0e1d15dd39..11cfe6cf52 100644 --- a/libs/login-api-2/src/main/res/values-cy/strings.xml +++ b/libs/login-api-2/src/main/res/values-cy/strings.xml @@ -109,7 +109,6 @@ school.instructure.com Tynnu defnyddiwr blaenorol? Methu dod o hyd i’ch ysgol? Ceisiwch deipio URL llawn yr ysgol. - Tapiwch yma i gael help. Dim cysylltiad â\'r rhyngrwyd Mae angen cysylltiad â\'r rhyngrwyd i wneud hyn. diff --git a/libs/login-api-2/src/main/res/values-da/strings.xml b/libs/login-api-2/src/main/res/values-da/strings.xml index 1faf265adb..8f1838288b 100644 --- a/libs/login-api-2/src/main/res/values-da/strings.xml +++ b/libs/login-api-2/src/main/res/values-da/strings.xml @@ -109,7 +109,6 @@ school.instructure.com Fjern forrige bruger Kan du ikke finde din skole? Prøv at indtaste skolens fulde URL. - Tryk her for at få hjælp. Ingen internetforbindelse Denne handling kræver en internetforbindelse. diff --git a/libs/login-api-2/src/main/res/values-de/strings.xml b/libs/login-api-2/src/main/res/values-de/strings.xml index 8389e442df..47261dfc0b 100644 --- a/libs/login-api-2/src/main/res/values-de/strings.xml +++ b/libs/login-api-2/src/main/res/values-de/strings.xml @@ -109,7 +109,6 @@ school.instructure.com Vorherige/n Benutzer*in entfernen Finden Sie Ihre Schule nicht? Geben Sie den vollständigen URL der Schule ein. - Tippen Sie hier, um Hilfe zu erhalten. Keine Internetverbindung Diese Aktion erfordert eine Internetverbindung. diff --git a/libs/login-api-2/src/main/res/values-en-rAU/strings.xml b/libs/login-api-2/src/main/res/values-en-rAU/strings.xml index 562a29b642..de85b5f2a0 100644 --- a/libs/login-api-2/src/main/res/values-en-rAU/strings.xml +++ b/libs/login-api-2/src/main/res/values-en-rAU/strings.xml @@ -109,7 +109,6 @@ school.instructure.com Remove Previous User Can\'t find your school? Try typing the full school URL. - Tap here for help. No Internet Connection This action requires an internet connection. diff --git a/libs/login-api-2/src/main/res/values-en-rCA/strings.xml b/libs/login-api-2/src/main/res/values-en-rCA/strings.xml index d319e90b16..3727f20dd5 100644 --- a/libs/login-api-2/src/main/res/values-en-rCA/strings.xml +++ b/libs/login-api-2/src/main/res/values-en-rCA/strings.xml @@ -112,7 +112,6 @@ F school.instructure.com Remove Previous User Can\'t find your school? Try typing the full school URL. - Tap here for help. No Internet Connection This action requires an internet connection. diff --git a/libs/login-api-2/src/main/res/values-en-rCY/strings.xml b/libs/login-api-2/src/main/res/values-en-rCY/strings.xml index 2008cc1293..9ad8745705 100644 --- a/libs/login-api-2/src/main/res/values-en-rCY/strings.xml +++ b/libs/login-api-2/src/main/res/values-en-rCY/strings.xml @@ -111,7 +111,6 @@ school.instructure.com Remove Previous User Can\'t find your school? Try typing the full school URL. - Tap here for help. No Internet Connection This action requires an internet connection. diff --git a/libs/login-api-2/src/main/res/values-en-rGB/strings.xml b/libs/login-api-2/src/main/res/values-en-rGB/strings.xml index 4efa16bd21..4b3cdd4bcb 100644 --- a/libs/login-api-2/src/main/res/values-en-rGB/strings.xml +++ b/libs/login-api-2/src/main/res/values-en-rGB/strings.xml @@ -109,7 +109,6 @@ school.instructure.com Remove Previous User Can\'t find your school? Try typing the full school URL. - Tap here for help. No Internet Connection This action requires an internet connection. diff --git a/libs/login-api-2/src/main/res/values-es-rES/strings.xml b/libs/login-api-2/src/main/res/values-es-rES/strings.xml index 34f0ec1e70..feeaaaa281 100644 --- a/libs/login-api-2/src/main/res/values-es-rES/strings.xml +++ b/libs/login-api-2/src/main/res/values-es-rES/strings.xml @@ -110,7 +110,6 @@ school.instructure.com Eliminar usuario anterior ¿No puedes encontrar tu escuela? Intenta escribir la URL completa de la escuela. - Toca aquí para obtener ayuda. No hay conexión a Internet Esta acción requiere conexión a Internet. diff --git a/libs/login-api-2/src/main/res/values-es/strings.xml b/libs/login-api-2/src/main/res/values-es/strings.xml index f87d909f6e..3b4c42e957 100644 --- a/libs/login-api-2/src/main/res/values-es/strings.xml +++ b/libs/login-api-2/src/main/res/values-es/strings.xml @@ -111,7 +111,6 @@ school.instructure.com Eliminar usuario anterior ¿No puede encontrar su escuela? Intente escribir la URL completa de la escuela. - Presione aquí para obtener ayuda. Sin conexión a Internet Esta acción requiere conexión a Internet. diff --git a/libs/login-api-2/src/main/res/values-fi/strings.xml b/libs/login-api-2/src/main/res/values-fi/strings.xml index 4157a60613..f64c603f8d 100644 --- a/libs/login-api-2/src/main/res/values-fi/strings.xml +++ b/libs/login-api-2/src/main/res/values-fi/strings.xml @@ -111,7 +111,6 @@ school.instructure.com Poista edellinen käyttäjä Etkö löydä kouluasi? Yritä kirjoittaa koko koulun URL - Avaa ohje napauttamalla tässä. Ei Internet-yhteyttä Tähän toimintoon vaaditaan Internet-yhteys. diff --git a/libs/login-api-2/src/main/res/values-fr-rCA/strings.xml b/libs/login-api-2/src/main/res/values-fr-rCA/strings.xml index 060153b513..3ca2376d4b 100644 --- a/libs/login-api-2/src/main/res/values-fr-rCA/strings.xml +++ b/libs/login-api-2/src/main/res/values-fr-rCA/strings.xml @@ -109,7 +109,6 @@ school.instructure.com Retirer l\'utilisateur précédent Vous ne trouvez pas votre école? Essayez de saisir l\'URL complète de l’école. - Appuyer ici pour obtenir de l\'aide. Aucune connexion Internet Cette action nécessite une connexion Internet. diff --git a/libs/login-api-2/src/main/res/values-fr/strings.xml b/libs/login-api-2/src/main/res/values-fr/strings.xml index d2a7dedb52..538a698666 100644 --- a/libs/login-api-2/src/main/res/values-fr/strings.xml +++ b/libs/login-api-2/src/main/res/values-fr/strings.xml @@ -109,7 +109,6 @@ school.instructure.com Supprimer utilisateur précédent Vous ne trouvez pas votre école ? Essayez d’entrer l’URL complète de l’école - Appuyez ici pour obtenir de l’aide. Aucune connexion internet Cette action nécessite une connexion Internet. diff --git a/libs/login-api-2/src/main/res/values-ht/strings.xml b/libs/login-api-2/src/main/res/values-ht/strings.xml index 2eea2ac773..4303be39f4 100644 --- a/libs/login-api-2/src/main/res/values-ht/strings.xml +++ b/libs/login-api-2/src/main/res/values-ht/strings.xml @@ -109,7 +109,6 @@ school.instructure.com Elimine Ansyen Itilizatè Ou paka jwenn lekòl ou a? Eseye tape tout URL lekòl la - Tape la pou èd. Pa gen Koneksyon Internet Pou aksyon sa a ou bezwen konekte sou entènèt. diff --git a/libs/login-api-2/src/main/res/values-is/strings.xml b/libs/login-api-2/src/main/res/values-is/strings.xml index ab6760cb70..4ac89d3b60 100644 --- a/libs/login-api-2/src/main/res/values-is/strings.xml +++ b/libs/login-api-2/src/main/res/values-is/strings.xml @@ -111,7 +111,6 @@ school.instructure.com Fjarlægja fyrri notanda Finnurðu ekki skólann þinn? Prufaðu að slá inn alla vefslóð skólans. - Smelltu hér til að fá hjálp. Engin nettenging Þessi aðgerð krefst nettengingar. diff --git a/libs/login-api-2/src/main/res/values-it/strings.xml b/libs/login-api-2/src/main/res/values-it/strings.xml index 541ff2dc4e..675781a920 100644 --- a/libs/login-api-2/src/main/res/values-it/strings.xml +++ b/libs/login-api-2/src/main/res/values-it/strings.xml @@ -111,7 +111,6 @@ school.instructure.com Rimuovi utente precedente Non riesci a trova la tua scuola? Prova a digitare l’URL della scuola per intero. - Tocca qui per assistenza. Nessuna connessione a Internet Questa azione richiede una connessione a Internet. diff --git a/libs/login-api-2/src/main/res/values-ja/strings.xml b/libs/login-api-2/src/main/res/values-ja/strings.xml index 01da4c3a5d..13acaf4ee3 100644 --- a/libs/login-api-2/src/main/res/values-ja/strings.xml +++ b/libs/login-api-2/src/main/res/values-ja/strings.xml @@ -109,7 +109,6 @@ school.instructure.com 以前のユーザーを削除 学校が見つかりませんか?学校の完全なURLを入力してみてください。 - ここをタップしてヘルプを表示します。 インターネット接続なし この操作にはインターネット接続が必要です。 diff --git a/libs/login-api-2/src/main/res/values-mi/strings.xml b/libs/login-api-2/src/main/res/values-mi/strings.xml index 772695e3af..59b0fc3de9 100644 --- a/libs/login-api-2/src/main/res/values-mi/strings.xml +++ b/libs/login-api-2/src/main/res/values-mi/strings.xml @@ -111,7 +111,6 @@ school.instructure.com Tango Kaiwhakmahi o mua Kaore e kitea tō kura? Ngana ki te pātō te nuinga o te kura url - Pātō ki kōnei mo te awhina Kaore he hononga ipurangi Tēnei mahi ka mahi he hononga ipurangi diff --git a/libs/login-api-2/src/main/res/values-ms/strings.xml b/libs/login-api-2/src/main/res/values-ms/strings.xml index b8be733a44..4229891bcc 100644 --- a/libs/login-api-2/src/main/res/values-ms/strings.xml +++ b/libs/login-api-2/src/main/res/values-ms/strings.xml @@ -110,7 +110,6 @@ school.instructure.com Alih Keluar Pengguna Sebelumnya Tidak menemui sekolah anda? Cuba taip URL sekolah yang penuh. - Ketik di sini untuk mendapatkan bantuan. Tiada Sambungan Internet Tindakan ini memerlukan sambungan Internet diff --git a/libs/login-api-2/src/main/res/values-nb/strings.xml b/libs/login-api-2/src/main/res/values-nb/strings.xml index 1d7d7e6851..e062fe3ba6 100644 --- a/libs/login-api-2/src/main/res/values-nb/strings.xml +++ b/libs/login-api-2/src/main/res/values-nb/strings.xml @@ -111,7 +111,6 @@ school.instructure.com Fjerne forrige bruker Finner du ikke skolen din? Prøv å skrive hele skolens URL. - Trykk her for hjelp. Ingen Internett-tilkobling Denne handlingen krever Internett-tilkobling. diff --git a/libs/login-api-2/src/main/res/values-nl/strings.xml b/libs/login-api-2/src/main/res/values-nl/strings.xml index 0e4ae4a8f3..5b4e4a596b 100644 --- a/libs/login-api-2/src/main/res/values-nl/strings.xml +++ b/libs/login-api-2/src/main/res/values-nl/strings.xml @@ -109,7 +109,6 @@ school.instructure.com Vorige gebruiker verwijderen Kun je je school niet vinden? Typ de volledige URL van de school. - Tik hier voor hulp. Geen internetverbinding Voor deze actie is een internetverbinding vereist. diff --git a/libs/login-api-2/src/main/res/values-pl/strings.xml b/libs/login-api-2/src/main/res/values-pl/strings.xml index 552807641f..64e3193940 100644 --- a/libs/login-api-2/src/main/res/values-pl/strings.xml +++ b/libs/login-api-2/src/main/res/values-pl/strings.xml @@ -109,7 +109,6 @@ school.instructure.com Usuń poprzedniego użytkownika Nie możesz znaleźć swojej szkoły? Spróbuj wprowadzić pełen adres URL szkoły. - Stuknij tutaj, aby uzyskać pomoc. Brak połączenia internetowego To działanie wymaga połączenia internetowego. diff --git a/libs/login-api-2/src/main/res/values-pt-rBR/strings.xml b/libs/login-api-2/src/main/res/values-pt-rBR/strings.xml index 24542db009..21fd1ffc8e 100644 --- a/libs/login-api-2/src/main/res/values-pt-rBR/strings.xml +++ b/libs/login-api-2/src/main/res/values-pt-rBR/strings.xml @@ -111,7 +111,6 @@ school.instructure.com Remover usuário anterior Não consegue localizar a sua escola? Tente digitar a URL completa da escola. - Toque aqui para ajuda. Sem conexão à internet Esta ação exige conexão à internet. diff --git a/libs/login-api-2/src/main/res/values-pt-rPT/strings.xml b/libs/login-api-2/src/main/res/values-pt-rPT/strings.xml index e6147e54df..549dc0523c 100644 --- a/libs/login-api-2/src/main/res/values-pt-rPT/strings.xml +++ b/libs/login-api-2/src/main/res/values-pt-rPT/strings.xml @@ -109,7 +109,6 @@ school.instructure.com Remover utilizador anterior? Não vê sua escola? Tente digitar o URL completo da escola. - Toque aqui para ajuda. Sem ligação à Internet Esta ação requer uma conexão com a internet. diff --git a/libs/login-api-2/src/main/res/values-ru/strings.xml b/libs/login-api-2/src/main/res/values-ru/strings.xml index b2730ba446..ecaff5b7c8 100644 --- a/libs/login-api-2/src/main/res/values-ru/strings.xml +++ b/libs/login-api-2/src/main/res/values-ru/strings.xml @@ -109,7 +109,6 @@ school.instructure.com Удалить предыдущего пользователя Не удается найти свое учебное заведение? Попробуйте набрать полный адрес URL учебного заведения. - Прикоснитесь здесь для получения помощи. Нет интернет-соединения Для выполнения этого действия необходимо интернет-соединение. diff --git a/libs/login-api-2/src/main/res/values-sl/strings.xml b/libs/login-api-2/src/main/res/values-sl/strings.xml index 22206a77c5..9501e8172f 100644 --- a/libs/login-api-2/src/main/res/values-sl/strings.xml +++ b/libs/login-api-2/src/main/res/values-sl/strings.xml @@ -111,7 +111,6 @@ school.instructure.com Odstrani predhodnega uporabnika Ali svoje šole ne najdete? Poskusite vnesti poln naslov URL šole. - Za pomoč tapnite tukaj. Brez internetne povezave. Pri tem dejanju je potrebna internetna povezava. diff --git a/libs/login-api-2/src/main/res/values-sv/strings.xml b/libs/login-api-2/src/main/res/values-sv/strings.xml index 6545349e99..cd28a78c01 100644 --- a/libs/login-api-2/src/main/res/values-sv/strings.xml +++ b/libs/login-api-2/src/main/res/values-sv/strings.xml @@ -111,7 +111,6 @@ school.instructure.com Ta bort tidigare användare Kan du inte hitta din skola? Försök att skriva in skolans fullständiga URL. - Tryck här för hjälp. Ingen internetanslutning Den här åtgärden kräver internetanslutning. diff --git a/libs/login-api-2/src/main/res/values-th/strings.xml b/libs/login-api-2/src/main/res/values-th/strings.xml index 5ca4798884..fe43425e2e 100644 --- a/libs/login-api-2/src/main/res/values-th/strings.xml +++ b/libs/login-api-2/src/main/res/values-th/strings.xml @@ -110,7 +110,6 @@ school.instructure.com ลบผู้ใช้ก่อนหน้า ไม่พบโรงเรียนของคุณ ลองพิมพ์ URL เต็มของสถานศึกษา - กดเลือกที่นี่เพื่อรับความช่วยเหลือ ไม่มีการเชื่อมต่ออินเทอร์เน็ต การดำเนินการนี้ต้องมีการเชื่อมต่ออินเทอร์เน็ต diff --git a/libs/login-api-2/src/main/res/values-vi/strings.xml b/libs/login-api-2/src/main/res/values-vi/strings.xml index 0b1ef97420..301d0f6c50 100644 --- a/libs/login-api-2/src/main/res/values-vi/strings.xml +++ b/libs/login-api-2/src/main/res/values-vi/strings.xml @@ -110,7 +110,6 @@ school.instructure.com Loại Bỏ Người Dùng Trước Không tìm được trường của bạn? Hãy thử nhập URL đầy đủ của trường - Nhấn vào đây để được trợ giúp. Không Có Kết Nối Internet Thao tác này bắt buộc phải có kết nối internet. diff --git a/libs/login-api-2/src/main/res/values-zh/strings.xml b/libs/login-api-2/src/main/res/values-zh/strings.xml index 871b422f6d..72d0ea9c83 100644 --- a/libs/login-api-2/src/main/res/values-zh/strings.xml +++ b/libs/login-api-2/src/main/res/values-zh/strings.xml @@ -109,7 +109,6 @@ school.instructure.com 删除上一个用户 找不到您的学校?尝试键入完整的学校 URL。 - 轻击此处获取帮助。 无互联网连接 此操作需要互联网连接。 diff --git a/libs/login-api-2/src/main/res/values/strings.xml b/libs/login-api-2/src/main/res/values/strings.xml index 4acc7c102b..493fa8837d 100644 --- a/libs/login-api-2/src/main/res/values/strings.xml +++ b/libs/login-api-2/src/main/res/values/strings.xml @@ -112,7 +112,7 @@ F school.instructure.com Remove Previous User Can\'t find your school? Try typing the full school URL. - Tap here for help. + Tap here for login help. No Internet Connection This action requires an internet connection. From a9f5c02a82e2073c4912fd8a4732e130da6752a0 Mon Sep 17 00:00:00 2001 From: Kristof Nemere <109959688+kristofnemere@users.noreply.github.com> Date: Tue, 22 Aug 2023 09:53:22 +0200 Subject: [PATCH 08/22] [MBL-16972][All] Add alt text to the "Instructure" image at the bottom of the "About" dialog in Androids User Settings refs: MBL-16972 affects: Student, Teacher, Parent release note: none --- apps/flutter_parent/lib/l10n/app_localizations.dart | 3 +++ .../lib/screens/settings/settings_interactor.dart | 1 + libs/pandares/src/main/res/values/strings.xml | 1 + libs/pandautils/src/main/res/layout/fragment_about.xml | 2 +- 4 files changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/flutter_parent/lib/l10n/app_localizations.dart b/apps/flutter_parent/lib/l10n/app_localizations.dart index 26fa996e0b..4872b5fe70 100644 --- a/apps/flutter_parent/lib/l10n/app_localizations.dart +++ b/apps/flutter_parent/lib/l10n/app_localizations.dart @@ -1705,4 +1705,7 @@ class AppLocalizations { String get aboutVersionTitle => Intl.message('Version', desc: 'Title for Version field on about page'); + + String get aboutLogoSemanticsLabel => + Intl.message('Instructure logo', desc: 'Semantics label for the Instructure logo on the about page'); } diff --git a/apps/flutter_parent/lib/screens/settings/settings_interactor.dart b/apps/flutter_parent/lib/screens/settings/settings_interactor.dart index 74dffb7968..652a26fc44 100644 --- a/apps/flutter_parent/lib/screens/settings/settings_interactor.dart +++ b/apps/flutter_parent/lib/screens/settings/settings_interactor.dart @@ -96,6 +96,7 @@ class SettingsInteractor { SvgPicture.asset( 'assets/svg/ic_instructure_logo.svg', alignment: Alignment.bottomCenter, + semanticsLabel: L10n(context).aboutLogoSemanticsLabel, ) ], ), diff --git a/libs/pandares/src/main/res/values/strings.xml b/libs/pandares/src/main/res/values/strings.xml index c1648b020a..01f7f5f4cd 100644 --- a/libs/pandares/src/main/res/values/strings.xml +++ b/libs/pandares/src/main/res/values/strings.xml @@ -1400,4 +1400,5 @@ Email Version There was a problem reloading this assignment. Please check your connection and try again. + Instructure logo diff --git a/libs/pandautils/src/main/res/layout/fragment_about.xml b/libs/pandautils/src/main/res/layout/fragment_about.xml index 5d26338930..12b2463385 100644 --- a/libs/pandautils/src/main/res/layout/fragment_about.xml +++ b/libs/pandautils/src/main/res/layout/fragment_about.xml @@ -139,7 +139,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="32dp" - android:importantForAccessibility="no" + android:contentDescription="@string/instructure_logo" android:src="@drawable/ic_instructure_logo" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" From 67e0bf4cfc0066a72850c2c6f5d77b84a4c3835b Mon Sep 17 00:00:00 2001 From: Tamas Kozmer <72397075+tamaskozmer@users.noreply.github.com> Date: Tue, 22 Aug 2023 09:53:51 +0200 Subject: [PATCH 09/22] [All] Fixed accessibility issues (#2109) refs: MBL-16982, MBL-16975, MBL-16977, MBL-16984, MBL-16971, MBL-16978, MBL-16985 affects: All release note: Fixed accessibility issues * MBL-16982 Changed green and red colors to have 4.5:1 contrast with the background. * MBL-16975 Fixed file submission icon contrast. * MBL-16977 Fixed course name and home page contrast. * MBL-16984 Fixed info color contrast * MBL-16971 Fixed syllabus contrast. * MBL-16978 Redesigned rating dialog. * MBL-16985 Fixed contrast and content description for Canvas text on the login screen. * Test fixes --- .../svg/canvas-parent-login-logo-dark.svg | 10 ++++++++ .../assets/svg/canvas-parent-login-logo.svg | 12 +++++----- .../lib/screens/login_landing_screen.dart | 8 ++----- .../AssignmentDetailsViewModel.kt | 6 ++--- .../src/main/res/layout/fragment_syllabus.xml | 4 +++- .../layout/fragment_unsupported_file_type.xml | 2 +- .../AssignmentDetailsViewModelTest.kt | 8 +++---- .../src/main/res/layout/fragment_syllabus.xml | 4 +++- .../layout/fragment_unsupported_file_type.xml | 2 +- .../res/layout/view_edit_course_homepage.xml | 2 +- .../main/res/layout/view_rename_course.xml | 2 +- .../layout/activity_login_landing_page.xml | 4 ++-- .../src/main/res/drawable/ic_rating_star.xml | 5 ++++ .../res/drawable/ic_rating_star_outline.xml | 5 ++++ libs/pandares/src/main/res/values/colors.xml | 24 +++++++++---------- .../pandautils/dialogs/RatingDialog.kt | 7 ++---- .../src/main/res/layout/dialog_rating.xml | 20 ++++++++-------- .../src/main/res/values/font_styles.xml | 4 ++++ 18 files changed, 75 insertions(+), 54 deletions(-) create mode 100644 apps/flutter_parent/assets/svg/canvas-parent-login-logo-dark.svg create mode 100644 libs/pandares/src/main/res/drawable/ic_rating_star.xml create mode 100644 libs/pandares/src/main/res/drawable/ic_rating_star_outline.xml diff --git a/apps/flutter_parent/assets/svg/canvas-parent-login-logo-dark.svg b/apps/flutter_parent/assets/svg/canvas-parent-login-logo-dark.svg new file mode 100644 index 0000000000..cfc8e0bc77 --- /dev/null +++ b/apps/flutter_parent/assets/svg/canvas-parent-login-logo-dark.svg @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/apps/flutter_parent/assets/svg/canvas-parent-login-logo.svg b/apps/flutter_parent/assets/svg/canvas-parent-login-logo.svg index a6413426ae..a7729978ef 100644 --- a/apps/flutter_parent/assets/svg/canvas-parent-login-logo.svg +++ b/apps/flutter_parent/assets/svg/canvas-parent-login-logo.svg @@ -1,10 +1,10 @@ - - - - - - + + + + + + diff --git a/apps/flutter_parent/lib/screens/login_landing_screen.dart b/apps/flutter_parent/lib/screens/login_landing_screen.dart index 7c66ea9cf9..af81ff724f 100644 --- a/apps/flutter_parent/lib/screens/login_landing_screen.dart +++ b/apps/flutter_parent/lib/screens/login_landing_screen.dart @@ -18,19 +18,14 @@ import 'package:flutter/material.dart'; import 'package:flutter_parent/l10n/app_localizations.dart'; import 'package:flutter_parent/models/login.dart'; import 'package:flutter_parent/models/school_domain.dart'; -import 'package:flutter_parent/network/utils/analytics.dart'; import 'package:flutter_parent/network/utils/api_prefs.dart'; import 'package:flutter_parent/router/panda_router.dart'; import 'package:flutter_parent/screens/qr_login/qr_login_util.dart'; import 'package:flutter_parent/screens/web_login/web_login_screen.dart'; import 'package:flutter_parent/utils/common_widgets/avatar.dart'; -import 'package:flutter_parent/utils/common_widgets/error_report/error_report_dialog.dart'; -import 'package:flutter_parent/utils/common_widgets/error_report/error_report_interactor.dart'; -import 'package:flutter_parent/utils/common_widgets/full_screen_scroll_container.dart'; import 'package:flutter_parent/utils/common_widgets/two_finger_double_tap_gesture_detector.dart'; import 'package:flutter_parent/utils/common_widgets/user_name.dart'; import 'package:flutter_parent/utils/debug_flags.dart'; -import 'package:flutter_parent/utils/design/canvas_icons.dart'; import 'package:flutter_parent/utils/design/canvas_icons_solid.dart'; import 'package:flutter_parent/utils/design/parent_colors.dart'; import 'package:flutter_parent/utils/design/parent_theme.dart'; @@ -93,13 +88,14 @@ class LoginLandingScreen extends StatelessWidget { Widget _body(BuildContext context) { final lastLoginAccount = ApiPrefs.getLastAccount(); + final assetString = ParentTheme.of(context).isDarkMode ? 'assets/svg/canvas-parent-login-logo-dark.svg' : 'assets/svg/canvas-parent-login-logo.svg'; return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Spacer(), SvgPicture.asset( - 'assets/svg/canvas-parent-login-logo.svg', + assetString, semanticsLabel: L10n(context).canvasLogoLabel, ), Spacer(), diff --git a/apps/student/src/main/java/com/instructure/student/features/assignmentdetails/AssignmentDetailsViewModel.kt b/apps/student/src/main/java/com/instructure/student/features/assignmentdetails/AssignmentDetailsViewModel.kt index 0a7f57a4ac..1155fdcead 100644 --- a/apps/student/src/main/java/com/instructure/student/features/assignmentdetails/AssignmentDetailsViewModel.kt +++ b/apps/student/src/main/java/com/instructure/student/features/assignmentdetails/AssignmentDetailsViewModel.kt @@ -268,11 +268,11 @@ class AssignmentDetailsViewModel @Inject constructor( ) val submissionStatusTint = if (assignment.isSubmitted) { - R.color.backgroundSuccess + R.color.textSuccess } else if (isMissing) { - R.color.backgroundDanger + R.color.textDanger } else { - R.color.backgroundDark + R.color.textDark } val submittedStatusIcon = if (assignment.isSubmitted) R.drawable.ic_complete_solid else R.drawable.ic_no diff --git a/apps/student/src/main/res/layout/fragment_syllabus.xml b/apps/student/src/main/res/layout/fragment_syllabus.xml index f9baf996b6..cb801b5f90 100644 --- a/apps/student/src/main/res/layout/fragment_syllabus.xml +++ b/apps/student/src/main/res/layout/fragment_syllabus.xml @@ -46,7 +46,9 @@ app:tabPaddingEnd="4dp" app:tabPaddingStart="4dp" app:tabSelectedTextColor="@color/white" - app:tabTextColor="@color/transparentWhite" + app:tabTextColor="@color/white" + app:tabTextAppearance="@style/TextAppearance.Design.Tab" + app:tabSelectedTextAppearance="@style/NavigationTabTextAppeareance" tools:background="#00bcd5" tools:visibility="visible"> diff --git a/apps/student/src/main/res/layout/fragment_unsupported_file_type.xml b/apps/student/src/main/res/layout/fragment_unsupported_file_type.xml index 202c4d34cd..eb03f71252 100644 --- a/apps/student/src/main/res/layout/fragment_unsupported_file_type.xml +++ b/apps/student/src/main/res/layout/fragment_unsupported_file_type.xml @@ -48,7 +48,7 @@ android:layout_height="64dp" android:importantForAccessibility="no" android:scaleType="fitCenter" - android:tint="@color/textLight" + app:tint="@color/textDark" app:srcCompat="@drawable/ic_canvas_logo_red"/> diff --git a/apps/teacher/src/main/res/layout/fragment_unsupported_file_type.xml b/apps/teacher/src/main/res/layout/fragment_unsupported_file_type.xml index 568c075201..fb0542d8bf 100644 --- a/apps/teacher/src/main/res/layout/fragment_unsupported_file_type.xml +++ b/apps/teacher/src/main/res/layout/fragment_unsupported_file_type.xml @@ -47,7 +47,7 @@ android:layout_height="64dp" android:importantForAccessibility="no" android:scaleType="fitCenter" - android:tint="@color/textLight" + app:tint="@color/textDark" app:srcCompat="@drawable/ic_canvas_logo" /> diff --git a/apps/teacher/src/main/res/layout/view_rename_course.xml b/apps/teacher/src/main/res/layout/view_rename_course.xml index e1b2afcd22..4594143d7d 100644 --- a/apps/teacher/src/main/res/layout/view_rename_course.xml +++ b/apps/teacher/src/main/res/layout/view_rename_course.xml @@ -56,7 +56,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/courseNameLabel" - android:alpha="0.55" + android:textColor="@color/textDark" android:freezesText="true" tools:text="Biology 101"/> diff --git a/libs/login-api-2/src/main/res/layout/activity_login_landing_page.xml b/libs/login-api-2/src/main/res/layout/activity_login_landing_page.xml index b41bb274f1..22adb062e5 100644 --- a/libs/login-api-2/src/main/res/layout/activity_login_landing_page.xml +++ b/libs/login-api-2/src/main/res/layout/activity_login_landing_page.xml @@ -55,8 +55,8 @@ android:layout_marginTop="24dp" android:layout_marginBottom="2dp" android:adjustViewBounds="true" - android:importantForAccessibility="no" - android:tint="@color/tiara" + android:contentDescription="@string/canvas" + android:tint="@color/textDarkest" app:srcCompat="@drawable/ic_canvas_wordmark" /> + + diff --git a/libs/pandares/src/main/res/drawable/ic_rating_star_outline.xml b/libs/pandares/src/main/res/drawable/ic_rating_star_outline.xml new file mode 100644 index 0000000000..c32749453d --- /dev/null +++ b/libs/pandares/src/main/res/drawable/ic_rating_star_outline.xml @@ -0,0 +1,5 @@ + + + diff --git a/libs/pandares/src/main/res/values/colors.xml b/libs/pandares/src/main/res/values/colors.xml index 5843539a2c..0adee136e1 100644 --- a/libs/pandares/src/main/res/values/colors.xml +++ b/libs/pandares/src/main/res/values/colors.xml @@ -20,44 +20,44 @@ #556572 #BF32A4 - #EE0612 + #E0061F #556572 #2D3B45 #F5F5F5 #FFFFFF - #008EE2 + #0374B5 #F5F5F5 #FFFFFF #FFFFFF #C7CDD1 - #00AC18 + #0B874B #FC5E13 #BF32A4 #BF32A4 - #EE0612 + #E0061F #556572 #2D3B45 - #008EE2 + #0374B5 #F5F5F5 #FFFFFF #C7CDD1 - #00AC18 + #0B874B #FC5E13 - #EE0612 - #008EE2 + #E0061F + #0374B5 #FC5E13 #2D3B45 #394B58 #F5F5F5 - #00AC18 + #0B874B #BF32A4 - #EE0612 + #E0061F #556572 #2D3B45 - #008EE2 + #0374B5 #F5F5F5 #FFFFFF - #00AC18 + #0B874B #FC5E13 #C7CDD1 #FFFFFF diff --git a/libs/pandautils/src/main/java/com/instructure/pandautils/dialogs/RatingDialog.kt b/libs/pandautils/src/main/java/com/instructure/pandautils/dialogs/RatingDialog.kt index 04cf4f703d..7745073010 100644 --- a/libs/pandautils/src/main/java/com/instructure/pandautils/dialogs/RatingDialog.kt +++ b/libs/pandautils/src/main/java/com/instructure/pandautils/dialogs/RatingDialog.kt @@ -113,13 +113,11 @@ class RatingDialog : DialogFragment() { val starClickListener = View.OnClickListener { v -> stars.forEach { - it.setImageResource(R.drawable.ic_star) - it.setColorFilter(requireContext().getColor(R.color.backgroundMedium)) + it.setImageResource(R.drawable.ic_rating_star_outline) } val selectionIndex = stars.indexOf(v) stars.take(selectionIndex + 1).forEach { - it.setImageResource(R.drawable.ic_star) - it.setColorFilter(requireContext().getColor(R.color.backgroundDark)) + it.setImageResource(R.drawable.ic_rating_star) } val isFiveStars = selectionIndex >= 4 comments.setVisible(!isFiveStars) @@ -132,7 +130,6 @@ class RatingDialog : DialogFragment() { } stars.forEach { - it.setImageResource(R.drawable.ic_star) it.setOnClickListener(starClickListener) } } diff --git a/libs/pandautils/src/main/res/layout/dialog_rating.xml b/libs/pandautils/src/main/res/layout/dialog_rating.xml index 007ed070e7..ab56eb6e20 100644 --- a/libs/pandautils/src/main/res/layout/dialog_rating.xml +++ b/libs/pandautils/src/main/res/layout/dialog_rating.xml @@ -39,8 +39,8 @@ android:layout_marginLeft="4dp" android:layout_marginRight="4dp" android:contentDescription="@string/star1" - android:src="@drawable/ic_star" - app:tint="@color/backgroundMedium" /> + android:src="@drawable/ic_rating_star_outline" + app:tint="@color/backgroundDark" /> + android:src="@drawable/ic_rating_star_outline" + app:tint="@color/backgroundDark"/> + android:src="@drawable/ic_rating_star_outline" + app:tint="@color/backgroundDark"/> + android:src="@drawable/ic_rating_star_outline" + app:tint="@color/backgroundDark"/> + android:src="@drawable/ic_rating_star_outline" + app:tint="@color/backgroundDark"/> diff --git a/libs/pandautils/src/main/res/values/font_styles.xml b/libs/pandautils/src/main/res/values/font_styles.xml index 1e19ec8b65..51fa9e391c 100644 --- a/libs/pandautils/src/main/res/values/font_styles.xml +++ b/libs/pandautils/src/main/res/values/font_styles.xml @@ -42,4 +42,8 @@ italic + + \ No newline at end of file From 454740d1d0ed6f6f7a19c7ef30a8e03bc42bcc5f Mon Sep 17 00:00:00 2001 From: Kristof Deak <92309696+kdeakinstructure@users.noreply.github.com> Date: Tue, 22 Aug 2023 12:32:24 +0200 Subject: [PATCH 10/22] Fix many breaking nightly tests in both apps (#2114) * Rollback lowres devices to API lvl 26 (because API level 29 low resolution device is too flaky). * fix teacher announcement and discussion e2e tests * fix files e2e test in teacher * fix breaking syllabus tablet test. fix breaking discussion test. * fix breaking landscape module tests * Stub NotATeacherPageTest displaysPageObjects test because of the 'too many login attempts' change on the backend. (Will be put back after find found a solution for it) --- .../ui/interaction/ModuleInteractionTest.kt | 338 ++++++++++++------ .../teacher/ui/NotATeacherPageTest.kt | 2 + .../teacher/ui/e2e/DiscussionsE2ETest.kt | 12 +- .../teacher/ui/e2e/FilesE2ETest.kt | 2 +- .../teacher/ui/pages/AnnouncementsListPage.kt | 2 +- .../teacher/ui/pages/CalendarEventPage.kt | 4 +- 6 files changed, 232 insertions(+), 128 deletions(-) diff --git a/apps/student/src/androidTest/java/com/instructure/student/ui/interaction/ModuleInteractionTest.kt b/apps/student/src/androidTest/java/com/instructure/student/ui/interaction/ModuleInteractionTest.kt index c35844fb1b..20c99a602c 100644 --- a/apps/student/src/androidTest/java/com/instructure/student/ui/interaction/ModuleInteractionTest.kt +++ b/apps/student/src/androidTest/java/com/instructure/student/ui/interaction/ModuleInteractionTest.kt @@ -18,12 +18,36 @@ package com.instructure.student.ui.interaction import android.text.Html import androidx.test.espresso.Espresso import androidx.test.espresso.web.webdriver.Locator -import com.instructure.canvas.espresso.mockCanvas.* -import com.instructure.canvasapi2.models.* +import com.instructure.canvas.espresso.mockCanvas.MockCanvas +import com.instructure.canvas.espresso.mockCanvas.addAssignment +import com.instructure.canvas.espresso.mockCanvas.addDiscussionTopicToCourse +import com.instructure.canvas.espresso.mockCanvas.addFileToCourse +import com.instructure.canvas.espresso.mockCanvas.addItemToModule +import com.instructure.canvas.espresso.mockCanvas.addLTITool +import com.instructure.canvas.espresso.mockCanvas.addModuleToCourse +import com.instructure.canvas.espresso.mockCanvas.addPageToCourse +import com.instructure.canvas.espresso.mockCanvas.addQuestionToQuiz +import com.instructure.canvas.espresso.mockCanvas.addQuizToCourse +import com.instructure.canvas.espresso.mockCanvas.init +import com.instructure.canvasapi2.models.Assignment +import com.instructure.canvasapi2.models.CourseSettings +import com.instructure.canvasapi2.models.DiscussionTopicHeader +import com.instructure.canvasapi2.models.LockInfo +import com.instructure.canvasapi2.models.LockedModule +import com.instructure.canvasapi2.models.ModuleContentDetails +import com.instructure.canvasapi2.models.ModuleObject +import com.instructure.canvasapi2.models.Page +import com.instructure.canvasapi2.models.Quiz +import com.instructure.canvasapi2.models.QuizAnswer +import com.instructure.canvasapi2.models.Tab import com.instructure.dataseeding.util.days import com.instructure.dataseeding.util.fromNow import com.instructure.dataseeding.util.iso8601 -import com.instructure.panda_annotations.* +import com.instructure.panda_annotations.FeatureCategory +import com.instructure.panda_annotations.Priority +import com.instructure.panda_annotations.SecondaryFeatureCategory +import com.instructure.panda_annotations.TestCategory +import com.instructure.panda_annotations.TestMetaData import com.instructure.student.R import com.instructure.student.ui.pages.WebViewTextCheck import com.instructure.student.ui.utils.StudentTest @@ -43,7 +67,6 @@ class ModuleInteractionTest : StudentTest() { private var page: Page? = null private val fileName = "ModuleFile.html" private var fileCheck: WebViewTextCheck? = null - private val externalUrl = "https://www.google.com" private var quiz: Quiz? = null // Tapping an Assignment module item should navigate to that item's detail page @@ -55,7 +78,19 @@ class ModuleInteractionTest : StudentTest() { val course1 = data.courses.values.first() val module = data.courseModules[course1.id]!!.first() + // Create an assignment and add it as a module item + assignment = data.addAssignment( + courseId = course1.id, + submissionType = Assignment.SubmissionType.ONLINE_TEXT_ENTRY + ) + data.addItemToModule( + course = course1, + moduleId = module.id, + item = assignment!! + ) + // Verify that we can launch into the assignment from an assignment module item + modulesPage.refresh() modulesPage.assertModuleDisplayed(module) modulesPage.assertModuleItemDisplayed(module, assignment!!.name!!) modulesPage.clickModuleItem(module, assignment!!.name!!) @@ -71,8 +106,23 @@ class ModuleInteractionTest : StudentTest() { val data = getToCourseModules(studentCount = 1, courseCount = 1) val course1 = data.courses.values.first() val module = data.courseModules[course1.id]!!.first() + val user = data.users.values.first() + + // Create a discussion and add it as a module item + topicHeader = data.addDiscussionTopicToCourse( + course = course1, + user = user, + topicTitle = "Discussion in module", + topicDescription = "In. A. Module." + ) + data.addItemToModule( + course = course1, + moduleId = module.id, + item = topicHeader!! + ) // Verify that we can launch into a discussion from a discussion module item + modulesPage.refresh() modulesPage.assertModuleDisplayed(module) modulesPage.assertModuleItemDisplayed(module, topicHeader!!.title!!) modulesPage.clickModuleItem(module, topicHeader!!.title!!) @@ -87,6 +137,14 @@ class ModuleInteractionTest : StudentTest() { val course1 = data.courses.values.first() val module = data.courseModules[course1.id]!!.first() + val ltiTool = data.addLTITool("Google Drive", "http://google.com", course1, 1234L) + data.addItemToModule( + course = course1, + moduleId = module.id, + item = ltiTool!! + ) + + modulesPage.refresh() modulesPage.clickModuleItem(module, "Google Drive") canvasWebViewPage.assertTitle("Google Drive") } @@ -96,11 +154,20 @@ class ModuleInteractionTest : StudentTest() { @TestMetaData(Priority.MANDATORY, FeatureCategory.MODULES, TestCategory.INTERACTION, false) fun testModules_launchesIntoExternalURL() { // Basic mock setup + val externalUrl = "https://www.google.com" val data = getToCourseModules(studentCount = 1, courseCount = 1) val course1 = data.courses.values.first() val module = data.courseModules[course1.id]!!.first() + // Create an external URL and add it as a module item + data.addItemToModule( + course = course1, + moduleId = module.id, + item = externalUrl + ) + // click the external url module item + modulesPage.refresh() modulesPage.clickModuleItem(module, externalUrl) // Not much we can test here, as it is an external URL, but testModules_navigateToNextAndPreviousModuleItems // will test that the module name and module item name are displayed correctly. @@ -116,7 +183,26 @@ class ModuleInteractionTest : StudentTest() { val course1 = data.courses.values.first() val module = data.courseModules[course1.id]!!.first() + // Create a file and add it as a module item + val fileContent = "

A Heading

" + fileCheck = WebViewTextCheck(Locator.ID, "heading1", "A Heading") + + val fileId = data.addFileToCourse( + courseId = course1.id, + displayName = fileName, + fileContent = fileContent, + contentType = "text/html" + ) + val rootFolderId = data.courseRootFolders[course1.id]!!.id + val fileFolder = data.folderFiles[rootFolderId]?.find { it.id == fileId } + data.addItemToModule( + course = course1, + moduleId = module.id, + item = fileFolder!! + ) + // Click the file module and verify that the file appears + modulesPage.refresh() modulesPage.clickModuleItem(module, fileName, R.id.openButton) canvasWebViewPage.waitForWebView() canvasWebViewPage.runTextChecks(fileCheck!!) @@ -131,7 +217,22 @@ class ModuleInteractionTest : StudentTest() { val course1 = data.courses.values.first() val module = data.courseModules[course1.id]!!.first() + // Create a page and add it as a module item + page = data.addPageToCourse( + courseId = course1.id, + pageId = data.newItemId(), + published = true, + title = "Page In Course", + url = URLEncoder.encode("Page In Course", "UTF-8") + ) + data.addItemToModule( + course = course1, + moduleId = module.id, + item = page!! + ) + // Verify that we can launch into a page from a page module item + modulesPage.refresh() modulesPage.assertModuleDisplayed(module) modulesPage.assertModuleItemDisplayed(module, page!!.title!!) modulesPage.clickModuleItem(module, page!!.title!!) @@ -157,7 +258,48 @@ class ModuleInteractionTest : StudentTest() { val course1 = data.courses.values.first() val module = data.courseModules[course1.id]!!.first() + // Create a quiz and add it as a module item + quiz = data.addQuizToCourse( + course = course1 + ) + + data.addQuestionToQuiz( + course = course1, + quizId = quiz!!.id, + questionName = "Math 1", + questionText = "What is 2 + 5?", + questionType = "multiple_choice_question", + answers = arrayOf( + QuizAnswer(answerText = "7"), + QuizAnswer(answerText = "25"), + QuizAnswer(answerText = "-7") + ) + ) + + data.addQuestionToQuiz( + course = course1, + quizId = quiz!!.id, + questionName = "Math 2", + questionText = "Pi is greater than the square root of 2", + questionType = "true_false_question" + ) + + data.addQuestionToQuiz( + course = course1, + quizId = quiz!!.id, + questionName = "Math 3", + questionText = "Write an essay on why math is so awesome", + questionType = "essay_question" + ) + + data.addItemToModule( + course = course1, + moduleId = module.id, + item = quiz!! + ) + // Verify that we can launch into a quiz from a quiz module item + modulesPage.refresh() modulesPage.assertModuleDisplayed(module) modulesPage.assertModuleItemDisplayed(module, quiz!!.title!!) /* TODO: Check that the quiz is displayed if/when we can do so via WebView @@ -177,7 +319,20 @@ class ModuleInteractionTest : StudentTest() { // Basic mock setup val data = getToCourseModules(studentCount = 1, courseCount = 1) val course1 = data.courses.values.first() - val module = data.courseModules[course1.id]!!.first() + var module = data.courseModules[course1.id]!!.first() + + // Create an assignment and add it as a module item + assignment = data.addAssignment( + courseId = course1.id, + submissionType = Assignment.SubmissionType.ONLINE_TEXT_ENTRY + ) + data.addItemToModule( + course = course1, + moduleId = module.id, + item = assignment!! + ) + + module = data.courseModules[course1.id]!!.first() val firstModuleItem = module.items[0] // Verify that expanding a module shows the module items and collapsing a module @@ -185,6 +340,7 @@ class ModuleInteractionTest : StudentTest() { // We're going on the assumption that the lone module is initially expanded. Although // the initial assertModuleItemDisplayed() would expand the module if it was not expanded // already. + modulesPage.refresh() modulesPage.assertModuleDisplayed(module) modulesPage.assertModuleItemDisplayed(module, firstModuleItem.title!!) modulesPage.clickModule(module) @@ -221,11 +377,68 @@ class ModuleInteractionTest : StudentTest() { fun testModules_navigateToNextAndPreviousModuleItems() { // Basic mock setup val data = getToCourseModules(studentCount = 1, courseCount = 1) + val externalUrl = "https://www.google.com" val course1 = data.courses.values.first() - val module = data.courseModules[course1.id]!!.first() + var module = data.courseModules[course1.id]!!.first() + val user = data.users.values.first() + + // Create an assignment and add it as a module item + assignment = data.addAssignment( + courseId = course1.id, + submissionType = Assignment.SubmissionType.ONLINE_TEXT_ENTRY + ) + data.addItemToModule( + course = course1, + moduleId = module.id, + item = assignment!! + ) + + // Create a discussion and add it as a module item + topicHeader = data.addDiscussionTopicToCourse( + course = course1, + user = user, + topicTitle = "Discussion in module", + topicDescription = "In. A. Module." + ) + data.addItemToModule( + course = course1, + moduleId = module.id, + item = topicHeader!! + ) + + val ltiTool = data.addLTITool("Google Drive", "http://google.com", course1, 1234L) + data.addItemToModule( + course = course1, + moduleId = module.id, + item = ltiTool!! + ) + + // Create a page and add it as a module item + page = data.addPageToCourse( + courseId = course1.id, + pageId = data.newItemId(), + published = true, + title = "Page In Course", + url = URLEncoder.encode("Page In Course", "UTF-8") + ) + data.addItemToModule( + course = course1, + moduleId = module.id, + item = page!! + ) + + // Create an external URL and add it as a module item + data.addItemToModule( + course = course1, + moduleId = module.id, + item = externalUrl + ) + + module = data.courseModules[course1.id]!!.first() // Iterate through the module items, starting at the first val moduleItemList = module.items + modulesPage.refresh() modulesPage.clickModuleItem(module, moduleItemList[0].title!!) var moduleIndex = 0; // we start here @@ -413,126 +626,15 @@ class ModuleInteractionTest : StudentTest() { // Add a course tab val course1 = data.courses.values.first() - val user1 = data.users.values.first() val modulesTab = Tab(position = 2, label = "Modules", visibility = "public", tabId = Tab.MODULES_ID) data.courseTabs[course1.id]!! += modulesTab // Create a module - val module = data.addModuleToCourse( + data.addModuleToCourse( course = course1, moduleName = "Big Module" ) - // Create a discussion and add it as a module item - topicHeader = data.addDiscussionTopicToCourse( - course = course1, - user = user1, - topicTitle = "Discussion in module", - topicDescription = "In. A. Module." - ) - data.addItemToModule( - course = course1, - moduleId = module.id, - item = topicHeader!! - ) - - // Create an assignment and add it as a module item - assignment = data.addAssignment( - courseId = course1.id, - submissionType = Assignment.SubmissionType.ONLINE_TEXT_ENTRY - ) - data.addItemToModule( - course = course1, - moduleId = module.id, - item = assignment!! - ) - - // Create a page and add it as a module item - page = data.addPageToCourse( - courseId = course1.id, - pageId = data.newItemId(), - published = true, - title = "Page In Course", - url = URLEncoder.encode("Page In Course", "UTF-8") - ) - data.addItemToModule( - course = course1, - moduleId = module.id, - item = page!! - ) - - // Create a file and add it as a module item - val fileContent = "

A Heading

" - fileCheck = WebViewTextCheck(Locator.ID, "heading1", "A Heading") - - val fileId = data.addFileToCourse( - courseId = course1.id, - displayName = fileName, - fileContent = fileContent, - contentType = "text/html" - ) - val rootFolderId = data.courseRootFolders[course1.id]!!.id - val fileFolder = data.folderFiles[rootFolderId]?.find { it.id == fileId } - data.addItemToModule( - course = course1, - moduleId = module.id, - item = fileFolder!! - ) - - // Create an external URL and add it as a module item - data.addItemToModule( - course = course1, - moduleId = module.id, - item = externalUrl - ) - - // Create a quiz and add it as a module item - quiz = data.addQuizToCourse( - course = course1 - ) - - data.addQuestionToQuiz( - course = course1, - quizId = quiz!!.id, - questionName = "Math 1", - questionText = "What is 2 + 5?", - questionType = "multiple_choice_question", - answers = arrayOf( - QuizAnswer(answerText = "7"), - QuizAnswer(answerText = "25"), - QuizAnswer(answerText = "-7") - ) - ) - - data.addQuestionToQuiz( - course = course1, - quizId = quiz!!.id, - questionName = "Math 2", - questionText = "Pi is greater than the square root of 2", - questionType = "true_false_question" - ) - - data.addQuestionToQuiz( - course = course1, - quizId = quiz!!.id, - questionName = "Math 3", - questionText = "Write an essay on why math is so awesome", - questionType = "essay_question" - ) - - data.addItemToModule( - course = course1, - moduleId = module.id, - item = quiz!! - ) - - val ltiTool = data.addLTITool("Google Drive", "http://google.com", course1, 1234L) - data.addItemToModule( - course = course1, - moduleId = module.id, - item = ltiTool!! - ) - // Sign in val student = data.students[0] val token = data.tokenFor(student)!! diff --git a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/NotATeacherPageTest.kt b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/NotATeacherPageTest.kt index 24a7e27a53..fdabaaf522 100644 --- a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/NotATeacherPageTest.kt +++ b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/NotATeacherPageTest.kt @@ -15,6 +15,7 @@ */ package com.instructure.teacher.ui +import com.instructure.canvas.espresso.Stub import com.instructure.teacher.ui.utils.TeacherTest import com.instructure.teacher.ui.utils.slowLogInAsStudent import dagger.hilt.android.testing.HiltAndroidTest @@ -25,6 +26,7 @@ class NotATeacherPageTest : TeacherTest() { // Runs live; no MockCanvas @Test + @Stub("Stubbed because of the 'too many login attempts' change on backend. Will be de-stubbed when we find a solution for that.") override fun displaysPageObjects() { slowLogInAsStudent() notATeacherPage.assertPageObjects() diff --git a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/e2e/DiscussionsE2ETest.kt b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/e2e/DiscussionsE2ETest.kt index 17132fd6d5..4d80738c64 100644 --- a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/e2e/DiscussionsE2ETest.kt +++ b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/e2e/DiscussionsE2ETest.kt @@ -90,6 +90,10 @@ class DiscussionsE2ETest : TeacherTest() { discussionsListPage.assertGroupDisplayed("Pinned") discussionsListPage.assertDiscussionInGroup("Pinned", discussion2.title) + Log.d(STEP_TAG, "Assert that both of the discussions, '${discussion.title}' and '${discussion2.title}' discusssions are displayed.") + discussionsListPage.assertHasDiscussion(newTitle) + discussionsListPage.assertHasDiscussion(discussion2) + Log.d(STEP_TAG,"Navigate to Discussions Details Page by clicking on 'Edit'. Delete the '$newTitle' discussion.") discussionsListPage.clickDiscussion(newTitle) discussionsDetailsPage.openEdit() @@ -127,7 +131,7 @@ class DiscussionsE2ETest : TeacherTest() { Log.d(STEP_TAG,"Assert that the '$newDiscussionTitle' discussion is displayed and it is the only one.") discussionsListPage.assertDiscussionCount(1) discussionsListPage.assertHasDiscussion(newDiscussionTitle) - Espresso.pressBack() // need to press back to exit from the search input field + discussionsListPage.searchable.clickOnClearSearchButton() Log.d(STEP_TAG,"Collapse the discussion list and assert that the '$newDiscussionTitle' discussion can NOT be seen.") discussionsListPage.toggleCollapseExpandIcon() @@ -138,11 +142,5 @@ class DiscussionsE2ETest : TeacherTest() { discussionsListPage.toggleCollapseExpandIcon() discussionsListPage.assertDiscussionCount(1) discussionsListPage.assertHasDiscussion(newDiscussionTitle) - - Log.d(STEP_TAG, "Click on the clear search input button (X) on the toolbar. Assert that the default state, so both of the discussions will be displayed.") - discussionsListPage.searchable.clickOnClearSearchButton() - discussionsListPage.assertHasDiscussion(discussion) - discussionsListPage.assertHasDiscussion(discussion2) - discussionsListPage.assertDiscussionCount(2) } } \ No newline at end of file diff --git a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/e2e/FilesE2ETest.kt b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/e2e/FilesE2ETest.kt index 71aab3cde4..87cc6c14c1 100644 --- a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/e2e/FilesE2ETest.kt +++ b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/e2e/FilesE2ETest.kt @@ -175,7 +175,7 @@ class FilesE2ETest: TeacherTest() { fileListPage.assertItemNotDisplayed("unfiled") Log.d(STEP_TAG, "Click on 'Reset' search (cross) icon and assert that all the root level directories and files are displayed (1).") - fileListPage.searchable.clickOnClearSearchButton() + fileListPage.searchable.pressSearchBackButton() fileListPage.assertFileListCount(1) Log.d(STEP_TAG,"Select 'unfiled' directory. Assert that ${discussionAttachmentFile.name} file is displayed on the File List Page.") diff --git a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/pages/AnnouncementsListPage.kt b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/pages/AnnouncementsListPage.kt index d8c9ad7b7f..88b00f66ec 100644 --- a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/pages/AnnouncementsListPage.kt +++ b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/pages/AnnouncementsListPage.kt @@ -95,7 +95,7 @@ class AnnouncementsListPage(val searchable: Searchable) : BasePage() { * @param announcementName: The announcement name string parameter. */ fun assertHasAnnouncement(announcementName: String) { - onView(withText(announcementName)).assertDisplayed() + onView(withId(R.id.discussionTitle) + withText(announcementName)).assertDisplayed() } /** diff --git a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/pages/CalendarEventPage.kt b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/pages/CalendarEventPage.kt index 6d078ce3c2..63c194c0f8 100644 --- a/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/pages/CalendarEventPage.kt +++ b/apps/teacher/src/androidTest/java/com/instructure/teacher/ui/pages/CalendarEventPage.kt @@ -25,6 +25,8 @@ import androidx.test.espresso.web.webdriver.Locator import com.instructure.canvas.espresso.containsTextCaseInsensitive import com.instructure.espresso.assertDisplayed import com.instructure.espresso.page.BasePage +import com.instructure.espresso.page.plus +import com.instructure.espresso.page.withParent import com.instructure.teacher.R import org.hamcrest.Matchers @@ -56,7 +58,7 @@ class CalendarEventPage : BasePage(R.id.fragmentCalendarEvent) { * @throws AssertionError if the description does not match the expected description. */ fun verifyDescription(description: String) { - Web.onWebView(ViewMatchers.withId(R.id.contentWebView)) + Web.onWebView(ViewMatchers.withId(R.id.contentWebView) + withParent(R.id.calendarEventWebViewWrapper)) .withElement(DriverAtoms.findElement(Locator.ID, "content")) .check(WebViewAssertions.webMatches(DriverAtoms.getText(), Matchers.comparesEqualTo(description))) } From 1d3a67106702b8c1de08a25e2c9480e27f6384cd Mon Sep 17 00:00:00 2001 From: Tamas Kozmer <72397075+tamaskozmer@users.noreply.github.com> Date: Wed, 23 Aug 2023 11:32:19 +0200 Subject: [PATCH 11/22] [MBL-16976][Student][Teacher] Fixed date picker contrast #2115 refs: MBL-16976 affects: Student, Teacher release note: none --- apps/student/src/main/res/values/styles.xml | 5 +++++ .../main/res/values/themes_canvastheme.xml | 1 + apps/teacher/src/main/res/values/styles.xml | 6 ++++++ .../res/color/calendar_color_selector.xml | 20 +++++++++++++++++++ .../pandautils/src/main/res/values/styles.xml | 4 ++++ 5 files changed, 36 insertions(+) create mode 100644 libs/pandautils/src/main/res/color/calendar_color_selector.xml diff --git a/apps/student/src/main/res/values/styles.xml b/apps/student/src/main/res/values/styles.xml index ab7bd8654a..f7f6d76219 100644 --- a/apps/student/src/main/res/values/styles.xml +++ b/apps/student/src/main/res/values/styles.xml @@ -255,4 +255,9 @@ @color/textDark + + diff --git a/apps/student/src/main/res/values/themes_canvastheme.xml b/apps/student/src/main/res/values/themes_canvastheme.xml index 25ff54c211..286ae42ffc 100755 --- a/apps/student/src/main/res/values/themes_canvastheme.xml +++ b/apps/student/src/main/res/values/themes_canvastheme.xml @@ -43,6 +43,7 @@ @style/ModalDialogStyle @style/AnnotationNoteHinter @color/backgroundLight + @style/DatePickerStyle + + diff --git a/libs/pandautils/src/main/res/color/calendar_color_selector.xml b/libs/pandautils/src/main/res/color/calendar_color_selector.xml new file mode 100644 index 0000000000..1ba3935ed9 --- /dev/null +++ b/libs/pandautils/src/main/res/color/calendar_color_selector.xml @@ -0,0 +1,20 @@ + + + + + \ No newline at end of file diff --git a/libs/pandautils/src/main/res/values/styles.xml b/libs/pandautils/src/main/res/values/styles.xml index 87edd80e33..ea6efca1aa 100644 --- a/libs/pandautils/src/main/res/values/styles.xml +++ b/libs/pandautils/src/main/res/values/styles.xml @@ -219,4 +219,8 @@ @color/white + + From 71e6067faa8235ca1957896430cc1aa3a15e8996 Mon Sep 17 00:00:00 2001 From: Akos Hermann <72087159+hermannakos@users.noreply.github.com> Date: Wed, 23 Aug 2023 13:05:40 +0200 Subject: [PATCH 12/22] [MBL-16981][All] Inbox input labels always visible (#2108) Test plan: Check the inbox compose screen, the labels should always be visible. refs: MBL-16981 affects: Student, Teacher, Parent release note: Accessibility improvement. --- .../create_conversation_screen.dart | 4 +- .../student/ui/pages/NewMessagePage.kt | 3 +- .../fragment/InboxComposeMessageFragment.kt | 2 +- .../layout/fragment_inbox_compose_message.xml | 70 +++++++++------- .../teacher/fragments/AddMessageFragment.kt | 2 +- .../main/res/layout/fragment_add_message.xml | 83 ++++++++++--------- 6 files changed, 92 insertions(+), 72 deletions(-) diff --git a/apps/flutter_parent/lib/screens/inbox/create_conversation/create_conversation_screen.dart b/apps/flutter_parent/lib/screens/inbox/create_conversation/create_conversation_screen.dart index 911f5db614..1cdbf7b6e8 100644 --- a/apps/flutter_parent/lib/screens/inbox/create_conversation/create_conversation_screen.dart +++ b/apps/flutter_parent/lib/screens/inbox/create_conversation/create_conversation_screen.dart @@ -463,7 +463,7 @@ class _CreateConversationScreenState extends State wit style: Theme.of(context).textTheme.bodyText1, textCapitalization: TextCapitalization.sentences, decoration: InputDecoration( - hintText: L10n(context).messageSubjectInputHint, + labelText: L10n(context).messageSubjectInputHint, contentPadding: EdgeInsets.all(16), border: InputBorder.none, ), @@ -484,7 +484,7 @@ class _CreateConversationScreenState extends State wit maxLines: null, style: Theme.of(context).textTheme.bodyText2, decoration: InputDecoration( - hintText: L10n(context).messageBodyInputHint, + labelText: L10n(context).messageBodyInputHint, contentPadding: EdgeInsets.all(16), border: InputBorder.none, ), diff --git a/apps/student/src/androidTest/java/com/instructure/student/ui/pages/NewMessagePage.kt b/apps/student/src/androidTest/java/com/instructure/student/ui/pages/NewMessagePage.kt index 5bd887a0cb..ee1737f2da 100644 --- a/apps/student/src/androidTest/java/com/instructure/student/ui/pages/NewMessagePage.kt +++ b/apps/student/src/androidTest/java/com/instructure/student/ui/pages/NewMessagePage.kt @@ -130,7 +130,8 @@ class NewMessagePage : BasePage() { fun setMessage(messageText: String) { Espresso.closeSoftKeyboard() - onView(allOf(withId(R.id.message), hasSibling(withId(R.id.sendIndividualDivider)))) + onView(withId(R.id.messageContainer)).click() + onView(allOf(withId(R.id.message), withAncestor(R.id.messageContainer))) .scrollTo() .typeText(messageText) } diff --git a/apps/student/src/main/java/com/instructure/student/fragment/InboxComposeMessageFragment.kt b/apps/student/src/main/java/com/instructure/student/fragment/InboxComposeMessageFragment.kt index 6962b7d493..b4c6148bc8 100644 --- a/apps/student/src/main/java/com/instructure/student/fragment/InboxComposeMessageFragment.kt +++ b/apps/student/src/main/java/com/instructure/student/fragment/InboxComposeMessageFragment.kt @@ -319,7 +319,7 @@ class InboxComposeMessageFragment : ParentFragment(), FileUploadDialogParent { private fun handleExit() { // Check to see if the user has made any changes - if (binding.editSubject.text.isNotBlank() || binding.message.text.isNotBlank() || attachments.isNotEmpty()) { + if (binding.editSubject.text?.isNotBlank() == true || binding.message.text?.isNotBlank() == true || attachments.isNotEmpty()) { shouldAllowExit = false // Use childFragmentManager so that exiting the compose fragment also dismisses the dialog UnsavedChangesExitDialog.show(childFragmentManager) { diff --git a/apps/student/src/main/res/layout/fragment_inbox_compose_message.xml b/apps/student/src/main/res/layout/fragment_inbox_compose_message.xml index 16b4e10ed5..6a623ffdbb 100644 --- a/apps/student/src/main/res/layout/fragment_inbox_compose_message.xml +++ b/apps/student/src/main/res/layout/fragment_inbox_compose_message.xml @@ -120,22 +120,26 @@ - - + android:layout_height="wrap_content"> + + + - + android:layout_height="wrap_content"> + + + - تم الحذف + تم تحديث الدرجة جارٍ تحميل محتوى Canvas… UnknownDevice @@ -1170,6 +1171,7 @@ يمكنك فتح تفاصيل الإرسال من هنا + الدرجة: %s %s من الدقائق %s دقيقة diff --git a/libs/pandares/src/main/res/values-b+da+DK+instk12/strings.xml b/libs/pandares/src/main/res/values-b+da+DK+instk12/strings.xml index e1651e56b6..3d89c5ace5 100644 --- a/libs/pandares/src/main/res/values-b+da+DK+instk12/strings.xml +++ b/libs/pandares/src/main/res/values-b+da+DK+instk12/strings.xml @@ -432,6 +432,7 @@ Slettet + Vurdering opdateret Indlæser Canvas-indhold… UnknownDevice @@ -1119,6 +1120,7 @@ Du kan åbne afleveringsdetaljerne herfra + Vurdering: %s %s minut %s minutter diff --git a/libs/pandares/src/main/res/values-b+en+AU+unimelb/strings.xml b/libs/pandares/src/main/res/values-b+en+AU+unimelb/strings.xml index 9d91414183..013c458795 100644 --- a/libs/pandares/src/main/res/values-b+en+AU+unimelb/strings.xml +++ b/libs/pandares/src/main/res/values-b+en+AU+unimelb/strings.xml @@ -432,6 +432,7 @@ Deleted + Grade updated Loading Canvas Content… UnknownDevice @@ -1119,6 +1120,7 @@ You can open Submission details from here + Grade: %s %s Minute %s Minutes diff --git a/libs/pandares/src/main/res/values-b+en+GB+instukhe/strings.xml b/libs/pandares/src/main/res/values-b+en+GB+instukhe/strings.xml index 4072036e2e..e860a4f857 100644 --- a/libs/pandares/src/main/res/values-b+en+GB+instukhe/strings.xml +++ b/libs/pandares/src/main/res/values-b+en+GB+instukhe/strings.xml @@ -432,6 +432,7 @@ Deleted + Grade updated Loading Canvas Content… UnknownDevice @@ -1119,6 +1120,7 @@ You can open Submission details from here + Grade: %s %s minute %s Minutes diff --git a/libs/pandares/src/main/res/values-b+nb+NO+instk12/strings.xml b/libs/pandares/src/main/res/values-b+nb+NO+instk12/strings.xml index bd6ae8ec18..3bbbfdbd80 100644 --- a/libs/pandares/src/main/res/values-b+nb+NO+instk12/strings.xml +++ b/libs/pandares/src/main/res/values-b+nb+NO+instk12/strings.xml @@ -432,6 +432,7 @@ Slettet + Vurdering oppdatert Laster Canvas-innhold… UnknownDevice @@ -1119,6 +1120,7 @@ Du kan åpne Detaljer om innlevering her + Vurdering: %s %s minutt %s minutter diff --git a/libs/pandares/src/main/res/values-b+sv+SE+instk12/strings.xml b/libs/pandares/src/main/res/values-b+sv+SE+instk12/strings.xml index 44ae3284e8..eb7b807e44 100644 --- a/libs/pandares/src/main/res/values-b+sv+SE+instk12/strings.xml +++ b/libs/pandares/src/main/res/values-b+sv+SE+instk12/strings.xml @@ -432,6 +432,7 @@ Borttagen + Bedömning uppdaterat Läser in Canvas-innehåll… UnknownDevice @@ -1119,6 +1120,7 @@ Du kan öppna inlämningsinformationen härifrån + Bedömning: %s %s minut %s minuter diff --git a/libs/pandares/src/main/res/values-b+zh+HK/strings.xml b/libs/pandares/src/main/res/values-b+zh+HK/strings.xml index b6bf168689..ee91fbdcd0 100644 --- a/libs/pandares/src/main/res/values-b+zh+HK/strings.xml +++ b/libs/pandares/src/main/res/values-b+zh+HK/strings.xml @@ -426,6 +426,7 @@ 已刪除 + 評分已更新 載入 Canvas 內容… UnknownDevice @@ -1106,6 +1107,7 @@ 您可以從此處開啟提交項目詳細資料 + 評分:%s %s 分鐘 diff --git a/libs/pandares/src/main/res/values-b+zh+Hans/strings.xml b/libs/pandares/src/main/res/values-b+zh+Hans/strings.xml index 815e304d01..9fd0ff9c21 100644 --- a/libs/pandares/src/main/res/values-b+zh+Hans/strings.xml +++ b/libs/pandares/src/main/res/values-b+zh+Hans/strings.xml @@ -426,6 +426,7 @@ 已删除 + 评分已更新 正在加载Canvas内容… UnknownDevice @@ -1106,6 +1107,7 @@ 您可以从此处打开提交详情 + 评分:%s %s 分钟 diff --git a/libs/pandares/src/main/res/values-b+zh+Hant/strings.xml b/libs/pandares/src/main/res/values-b+zh+Hant/strings.xml index b6bf168689..ee91fbdcd0 100644 --- a/libs/pandares/src/main/res/values-b+zh+Hant/strings.xml +++ b/libs/pandares/src/main/res/values-b+zh+Hant/strings.xml @@ -426,6 +426,7 @@ 已刪除 + 評分已更新 載入 Canvas 內容… UnknownDevice @@ -1106,6 +1107,7 @@ 您可以從此處開啟提交項目詳細資料 + 評分:%s %s 分鐘 diff --git a/libs/pandares/src/main/res/values-ca/strings.xml b/libs/pandares/src/main/res/values-ca/strings.xml index 00d064fb12..013976b360 100644 --- a/libs/pandares/src/main/res/values-ca/strings.xml +++ b/libs/pandares/src/main/res/values-ca/strings.xml @@ -432,6 +432,7 @@ Suprimit + S’ha actualitzat la nota S\'està carregant el contingut de Canvas… UnknownDevice @@ -1119,6 +1120,7 @@ Podeu obrir Informació de l’entrega des d\'aquí + Nota: %s %s minut %s minuts diff --git a/libs/pandares/src/main/res/values-cy/strings.xml b/libs/pandares/src/main/res/values-cy/strings.xml index 6bd48540a4..8498f8bf6d 100644 --- a/libs/pandares/src/main/res/values-cy/strings.xml +++ b/libs/pandares/src/main/res/values-cy/strings.xml @@ -432,6 +432,7 @@ Wedi dileu + Gradd wedi’i diweddaru Llwytho Cynnwys Canvas… UnknownDevice @@ -1119,6 +1120,7 @@ Gallwch chi agor manylion Cyflwyniad fan hyn + Gradd: %s %s Munud %s Munud diff --git a/libs/pandares/src/main/res/values-da/strings.xml b/libs/pandares/src/main/res/values-da/strings.xml index 5235e2943e..ddc3e5462f 100644 --- a/libs/pandares/src/main/res/values-da/strings.xml +++ b/libs/pandares/src/main/res/values-da/strings.xml @@ -432,6 +432,7 @@ Slettet + Karakter opdateret Indlæser Canvas-indhold… UnknownDevice @@ -1119,6 +1120,7 @@ Du kan åbne afleveringsdetaljerne herfra + Karakter: %s %s minut %s minutter diff --git a/libs/pandares/src/main/res/values-de/strings.xml b/libs/pandares/src/main/res/values-de/strings.xml index 97b9b7ade9..58cda0e850 100644 --- a/libs/pandares/src/main/res/values-de/strings.xml +++ b/libs/pandares/src/main/res/values-de/strings.xml @@ -432,6 +432,7 @@ Gelöscht + Note aktualisiert Canvas-Content laden… UnknownDevice @@ -1119,6 +1120,7 @@ Sie können die Abgabedetails von hier aus öffnen + Note: %s %s Minute %s Minuten diff --git a/libs/pandares/src/main/res/values-en-rAU/strings.xml b/libs/pandares/src/main/res/values-en-rAU/strings.xml index 94d73a8b46..8aa32c6d13 100644 --- a/libs/pandares/src/main/res/values-en-rAU/strings.xml +++ b/libs/pandares/src/main/res/values-en-rAU/strings.xml @@ -432,6 +432,7 @@ Deleted + Mark updated Loading Canvas Content… UnknownDevice @@ -1119,6 +1120,7 @@ You can open Submission details from here + Mark: %s %s Minute %s Minutes diff --git a/libs/pandares/src/main/res/values-en-rCY/strings.xml b/libs/pandares/src/main/res/values-en-rCY/strings.xml index 4072036e2e..e860a4f857 100644 --- a/libs/pandares/src/main/res/values-en-rCY/strings.xml +++ b/libs/pandares/src/main/res/values-en-rCY/strings.xml @@ -432,6 +432,7 @@ Deleted + Grade updated Loading Canvas Content… UnknownDevice @@ -1119,6 +1120,7 @@ You can open Submission details from here + Grade: %s %s minute %s Minutes diff --git a/libs/pandares/src/main/res/values-en-rGB/strings.xml b/libs/pandares/src/main/res/values-en-rGB/strings.xml index 2b1b2629c7..70d3e97250 100644 --- a/libs/pandares/src/main/res/values-en-rGB/strings.xml +++ b/libs/pandares/src/main/res/values-en-rGB/strings.xml @@ -432,6 +432,7 @@ Deleted + Grade updated Loading Canvas Content… UnknownDevice @@ -1119,6 +1120,7 @@ You can open Submission details from here + Grade: %s %s minute %s Minutes diff --git a/libs/pandares/src/main/res/values-es-rES/strings.xml b/libs/pandares/src/main/res/values-es-rES/strings.xml index e8465b9bf7..8cef4f43c9 100644 --- a/libs/pandares/src/main/res/values-es-rES/strings.xml +++ b/libs/pandares/src/main/res/values-es-rES/strings.xml @@ -432,6 +432,7 @@ Eliminado + Nota actualizada Cargando el contenido de Canvas… UnknownDevice @@ -1119,6 +1120,7 @@ Desde aquí puedes abrir los detalles de la entrega + Nota: %s %s minuto %s minutos diff --git a/libs/pandares/src/main/res/values-es/strings.xml b/libs/pandares/src/main/res/values-es/strings.xml index 22bfecd1b7..1aaa81bfb7 100644 --- a/libs/pandares/src/main/res/values-es/strings.xml +++ b/libs/pandares/src/main/res/values-es/strings.xml @@ -432,6 +432,7 @@ Eliminado + Calificación actualizada Cargando el contenido de Canvas… UnknownDevice @@ -1119,6 +1120,7 @@ Desde aquí puede abrir los detalles de Entrega + Calificación: %s %s minuto %s minutos diff --git a/libs/pandares/src/main/res/values-fi/strings.xml b/libs/pandares/src/main/res/values-fi/strings.xml index d4f361ce9a..ab65479f50 100644 --- a/libs/pandares/src/main/res/values-fi/strings.xml +++ b/libs/pandares/src/main/res/values-fi/strings.xml @@ -432,6 +432,7 @@ Poistettu + Arvosana päivitetty Ladataan Canvas-sisältöä… UnknownDevice @@ -1119,6 +1120,7 @@ Voit avata tehtävän palautustiedot täältä + Arvosana: %s %s Minuutti %s minuuttia diff --git a/libs/pandares/src/main/res/values-fr-rCA/strings.xml b/libs/pandares/src/main/res/values-fr-rCA/strings.xml index 63e5e000cd..dd583f2abc 100644 --- a/libs/pandares/src/main/res/values-fr-rCA/strings.xml +++ b/libs/pandares/src/main/res/values-fr-rCA/strings.xml @@ -432,6 +432,7 @@ Supprimé + Note mise à jour Chargement du contenu de Canvas… UnknownDevice @@ -1119,6 +1120,7 @@ Vous pouvez ouvrir les détails de l’envoi à partir d’ici + Note : %s %s Minute %s Minutes diff --git a/libs/pandares/src/main/res/values-fr/strings.xml b/libs/pandares/src/main/res/values-fr/strings.xml index a566c9618a..adaf919f50 100644 --- a/libs/pandares/src/main/res/values-fr/strings.xml +++ b/libs/pandares/src/main/res/values-fr/strings.xml @@ -432,6 +432,7 @@ Supprimé + Note mise à jour Chargement du contenu Canvas… UnknownDevice @@ -1119,6 +1120,7 @@ Vous pouvez ouvrir les Détails de soumission à partir d\'ici + Note : %s %s Minute %s Minutes diff --git a/libs/pandares/src/main/res/values-ht/strings.xml b/libs/pandares/src/main/res/values-ht/strings.xml index bad97880f0..4d9e1e3de6 100644 --- a/libs/pandares/src/main/res/values-ht/strings.xml +++ b/libs/pandares/src/main/res/values-ht/strings.xml @@ -432,6 +432,7 @@ Efase + Klas aktyalize Chajman Kontni Canvas… UnknownDevice @@ -1119,6 +1120,7 @@ Ou ka ouvri detay Soumisyon yo la a + Klas: %s %s Minit %s Minit diff --git a/libs/pandares/src/main/res/values-is/strings.xml b/libs/pandares/src/main/res/values-is/strings.xml index 11335d2433..71498f4b73 100644 --- a/libs/pandares/src/main/res/values-is/strings.xml +++ b/libs/pandares/src/main/res/values-is/strings.xml @@ -432,6 +432,7 @@ Eytt + Einkunn uppfærð Sæki Canvas efni… UnknownDevice @@ -1119,6 +1120,7 @@ Þú getur opnað upplýsingar um skil héðan + Einkunn: %s %s Mínúta %s mínútur diff --git a/libs/pandares/src/main/res/values-it/strings.xml b/libs/pandares/src/main/res/values-it/strings.xml index 95e35d513b..1ebe6ca67a 100644 --- a/libs/pandares/src/main/res/values-it/strings.xml +++ b/libs/pandares/src/main/res/values-it/strings.xml @@ -432,6 +432,7 @@ Eliminato + Voto aggiornato Caricamento dei contenuti Contenuto… UnknownDevice @@ -1119,6 +1120,7 @@ Puoi aprire i dettagli consegna da qui + Voto: %s %s minuto %s minuti diff --git a/libs/pandares/src/main/res/values-ja/strings.xml b/libs/pandares/src/main/res/values-ja/strings.xml index 44d2184638..0b26bf4991 100644 --- a/libs/pandares/src/main/res/values-ja/strings.xml +++ b/libs/pandares/src/main/res/values-ja/strings.xml @@ -426,6 +426,7 @@ 削除されました + 評定を更新しました Canvas コンテンツ…を読み込み中 UnknownDevice @@ -1106,6 +1107,7 @@ 「提出」の詳細はここで開くことができます + 評定:%s %s 分 diff --git a/libs/pandares/src/main/res/values-mi/strings.xml b/libs/pandares/src/main/res/values-mi/strings.xml index 31a742b7fb..3ce51d36f9 100644 --- a/libs/pandares/src/main/res/values-mi/strings.xml +++ b/libs/pandares/src/main/res/values-mi/strings.xml @@ -432,6 +432,7 @@ mukua + Koeke kua whakahoutia E uta ana Canvas Ihirangi… UnknownDevice @@ -1119,6 +1120,7 @@ Mai i konei, ka kite koe i nga Taipitopito Tukunga. + Kōeke: %s %s Meneti %s meneti diff --git a/libs/pandares/src/main/res/values-ms/strings.xml b/libs/pandares/src/main/res/values-ms/strings.xml index 22552f920e..bce19c3d3a 100644 --- a/libs/pandares/src/main/res/values-ms/strings.xml +++ b/libs/pandares/src/main/res/values-ms/strings.xml @@ -432,6 +432,7 @@ Telah Dipadamkan + Gred dikemas kini Memuatkan Kandungan Canvas… UnknownDevice @@ -1119,6 +1120,7 @@ Anda boleh membuka butiran Serahan di sini + Gred: %s %s Minit %s Minit diff --git a/libs/pandares/src/main/res/values-nb/strings.xml b/libs/pandares/src/main/res/values-nb/strings.xml index fc43bf719c..74ed00f0d0 100644 --- a/libs/pandares/src/main/res/values-nb/strings.xml +++ b/libs/pandares/src/main/res/values-nb/strings.xml @@ -432,6 +432,7 @@ Slettet + Vurdering oppdatert Laster Canvas-innhold… UnknownDevice @@ -1119,6 +1120,7 @@ Du kan åpne Detaljer om innlevering her + Vurdering: %s %s minutt %s minutter diff --git a/libs/pandares/src/main/res/values-nl/strings.xml b/libs/pandares/src/main/res/values-nl/strings.xml index e5e50a7c83..0b32e79400 100644 --- a/libs/pandares/src/main/res/values-nl/strings.xml +++ b/libs/pandares/src/main/res/values-nl/strings.xml @@ -432,6 +432,7 @@ Verwijderd + Cijfer bijgewerkt Canvas Content aan het uploaden… UnknownDevice @@ -1119,6 +1120,7 @@ U kunt inleverdetails hier openen + Cijfer: %s %s minuut %s minuten diff --git a/libs/pandares/src/main/res/values-pl/strings.xml b/libs/pandares/src/main/res/values-pl/strings.xml index f40e84f984..a9f3d91551 100644 --- a/libs/pandares/src/main/res/values-pl/strings.xml +++ b/libs/pandares/src/main/res/values-pl/strings.xml @@ -444,6 +444,7 @@ Usunięto + Zaktualizowano ocenę Ładowanie zawartości Canvas… UnknownDevice @@ -1145,6 +1146,7 @@ Tutaj można otworzyć szczegóły przesyłki + Ocena: %s %s min %s min diff --git a/libs/pandares/src/main/res/values-pt-rBR/strings.xml b/libs/pandares/src/main/res/values-pt-rBR/strings.xml index ce7e963aba..dc5f3aec5c 100644 --- a/libs/pandares/src/main/res/values-pt-rBR/strings.xml +++ b/libs/pandares/src/main/res/values-pt-rBR/strings.xml @@ -432,6 +432,7 @@ Excluído + Nota atualizada Carregando conteúdo do Canvas… UnknownDevice @@ -1119,6 +1120,7 @@ Você pode abrir os detalhes do Envio aqui + Nota: %s %s Minuto %s Minutos diff --git a/libs/pandares/src/main/res/values-pt-rPT/strings.xml b/libs/pandares/src/main/res/values-pt-rPT/strings.xml index 3c73a4d156..1bf5144981 100644 --- a/libs/pandares/src/main/res/values-pt-rPT/strings.xml +++ b/libs/pandares/src/main/res/values-pt-rPT/strings.xml @@ -432,6 +432,7 @@ Eliminado + Nota atualizada A carregar o conteúdo da tela… UnknownDevice @@ -1119,6 +1120,7 @@ Podes abrir detalhes de Submissão a partir daqui + Nota: %s %s minuto %s minutos diff --git a/libs/pandares/src/main/res/values-ru/strings.xml b/libs/pandares/src/main/res/values-ru/strings.xml index 311d8519e6..9c7d3ded27 100644 --- a/libs/pandares/src/main/res/values-ru/strings.xml +++ b/libs/pandares/src/main/res/values-ru/strings.xml @@ -444,6 +444,7 @@ Удалено + Оценка обновлена Загрузка контента Canvas… UnknownDevice @@ -1145,6 +1146,7 @@ Вы можете открыть информацию об отправке здесь + Оценка: %s %s минута %s минут diff --git a/libs/pandares/src/main/res/values-sl/strings.xml b/libs/pandares/src/main/res/values-sl/strings.xml index 3dd4497706..b77f4e12fc 100644 --- a/libs/pandares/src/main/res/values-sl/strings.xml +++ b/libs/pandares/src/main/res/values-sl/strings.xml @@ -432,6 +432,7 @@ Odstranjeno + Ocena je posodobljena Nalaganje vsebine sistema Canvas… UnknownDevice @@ -1119,6 +1120,7 @@ Tukaj lahko odprete podrobnosti o oddaji + Ocena: %s %s minuta %s minut diff --git a/libs/pandares/src/main/res/values-sv/strings.xml b/libs/pandares/src/main/res/values-sv/strings.xml index b923d00664..fc1aee1a9d 100644 --- a/libs/pandares/src/main/res/values-sv/strings.xml +++ b/libs/pandares/src/main/res/values-sv/strings.xml @@ -432,6 +432,7 @@ Borttagen + Omdöme uppdaterat Läser in Canvas-innehåll… UnknownDevice @@ -1119,6 +1120,7 @@ Du kan öppna inlämningsinformationen härifrån + Omdöme: %s %s minut %s minuter diff --git a/libs/pandares/src/main/res/values-th/strings.xml b/libs/pandares/src/main/res/values-th/strings.xml index a0a534be86..e9871f3baf 100644 --- a/libs/pandares/src/main/res/values-th/strings.xml +++ b/libs/pandares/src/main/res/values-th/strings.xml @@ -432,6 +432,7 @@ ลบแล้ว + อัพเดตเกรดแล้ว กำลังโหลดเนื้อหา Canvas… UnknownDevice @@ -1119,6 +1120,7 @@ คุณสามารถเปิดรายละเอียดผลงานจัดส่ง (Submission details) ได้จากที่นี่ + เกรด: %s %s นาที %s นาที diff --git a/libs/pandares/src/main/res/values-vi/strings.xml b/libs/pandares/src/main/res/values-vi/strings.xml index db8ee483c2..bcf91a4a53 100644 --- a/libs/pandares/src/main/res/values-vi/strings.xml +++ b/libs/pandares/src/main/res/values-vi/strings.xml @@ -432,6 +432,7 @@ Đã xóa + Đã cập nhật lớp Đang Tải Nội Dung Canvas… UnknownDevice @@ -1119,6 +1120,7 @@ Bạn có thể mở chi tiết Bài Nộp từ đây + Lớp: %s %s Phút %s Phút diff --git a/libs/pandares/src/main/res/values-zh/strings.xml b/libs/pandares/src/main/res/values-zh/strings.xml index 815e304d01..9fd0ff9c21 100644 --- a/libs/pandares/src/main/res/values-zh/strings.xml +++ b/libs/pandares/src/main/res/values-zh/strings.xml @@ -426,6 +426,7 @@ 已删除 + 评分已更新 正在加载Canvas内容… UnknownDevice @@ -1106,6 +1107,7 @@ 您可以从此处打开提交详情 + 评分:%s %s 分钟 From 9d18a6c9a6ca517bff6ca338f679bc7f81e3eb53 Mon Sep 17 00:00:00 2001 From: "kristof.nemere" Date: Wed, 30 Aug 2023 13:44:38 +0200 Subject: [PATCH 22/22] Version bump --- apps/flutter_parent/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/flutter_parent/pubspec.yaml b/apps/flutter_parent/pubspec.yaml index c87f6a3c72..d43bf36c23 100644 --- a/apps/flutter_parent/pubspec.yaml +++ b/apps/flutter_parent/pubspec.yaml @@ -25,7 +25,7 @@ description: Canvas Parent # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 3.8.0+46 +version: 3.8.1+47 module: androidX: true