Merge pull request #3670 from NoelDeMartin/MOBILE-4338

MOBILE-4338 quiz: Fix multianswer inline feedback
main
Dani Palou 2023-05-11 12:37:37 +02:00 committed by GitHub
commit 243e8fc0f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 51 additions and 10 deletions

View File

@ -47,7 +47,6 @@ Feature: Attempt a quiz in app
| Test questions | match | TF9 | Text of the seventh question | | Test questions | match | TF9 | Text of the seventh question |
| Test questions | description | TF10 | Text of the eighth question | | Test questions | description | TF10 | Text of the eighth question |
# TODO test calculated question type. # TODO test calculated question type.
# TODO test multianswer question type.
# The calculatedsimple type is implemented using the calculated type. # The calculatedsimple type is implemented using the calculated type.
# The calculatedmulti type is implemented using the multichoice type. # The calculatedmulti type is implemented using the multichoice type.
# The randomsamatch type is implemented using the match type. # The randomsamatch type is implemented using the match type.
@ -70,6 +69,20 @@ Feature: Attempt a quiz in app
| TF12 | 10 | | TF12 | 10 |
| TF13 | 11 | | TF13 | 11 |
# TODO rewrite using generators.
And I am on the "Course 1" "core_question > course question bank" page logged in as teacher1
And I add a "Embedded answers (Cloze)" question filling the form with:
| Question name | multianswer |
| Question text | {1:SHORTANSWER:=Berlin} is the capital of Germany. |
| General feedback | The capital of Germany is Berlin. |
And I am on the "quiz2" "Activity" page
And I click on "Questions" "link"
And I click on "Add" "link"
And I click on "from question bank" "link"
And I set the field with xpath "//tr[contains(normalize-space(.), 'multianswer')]//input[@type='checkbox']" to "1"
And I click on "Add selected questions to the quiz" "button"
And I log out
Scenario: View a quiz entry page (attempts, status, etc.) Scenario: View a quiz entry page (attempts, status, etc.)
Given I entered the quiz activity "Quiz 1" on course "Course 1" as "student1" in the app Given I entered the quiz activity "Quiz 1" on course "Course 1" as "student1" in the app
When I press "Attempt quiz now" in the app When I press "Attempt quiz now" in the app
@ -125,6 +138,7 @@ Feature: Attempt a quiz in app
When I press "Attempt quiz now" in the app When I press "Attempt quiz now" in the app
And I press "Four" in the app And I press "Four" in the app
And I press "Three" in the app And I press "Three" in the app
And I set the field "Answer" to "Berlin" in the app
And I press "Next" in the app And I press "Next" in the app
And I set the field "Answer" to "testing" in the app And I set the field "Answer" to "testing" in the app
And I press "Next" in the app And I press "Next" in the app
@ -163,7 +177,7 @@ Feature: Attempt a quiz in app
And I click on "img.dropbackground" "css" And I click on "img.dropbackground" "css"
And I press "Submit" in the app And I press "Submit" in the app
Then I should find "Answer saved" in the app Then I should find "Answer saved" in the app
And I should find "Incomplete answer" within "9" "ion-item" in the app And I should find "Incomplete answer" within "10" "ion-item" in the app
But I should not find "Not yet answered" in the app But I should not find "Not yet answered" in the app
When I press "Submit all and finish" in the app When I press "Submit all and finish" in the app
@ -172,6 +186,10 @@ Feature: Attempt a quiz in app
And I should find "Finished" in the app And I should find "Finished" in the app
And I should find "Not yet graded" in the app And I should find "Not yet graded" in the app
When I press "Correct" within "Question 2" "ion-card" in the app
Then I should find "The correct answer is: Berlin" in the app
And I should find "Mark 1.00 out of 1.00" in the app
Scenario: Submit a quiz & Review a quiz attempt Scenario: Submit a quiz & Review a quiz attempt
Given I entered the quiz activity "Quiz 1" on course "Course 1" as "student1" in the app Given I entered the quiz activity "Quiz 1" on course "Course 1" as "student1" in the app
When I press "Attempt quiz now" in the app When I press "Attempt quiz now" in the app

View File

@ -792,7 +792,7 @@ export class CoreQuestionHelperProvider {
const classList = icon.classList.toString(); const classList = icon.classList.toString();
if (classList.indexOf('fa-check') >= 0) { if (classList.indexOf('fa-check') >= 0) {
correct = true; correct = true;
} else if (classList.indexOf('fa-xmark') < 0 || classList.indexOf('fa-remove') < 0) { } else if (classList.indexOf('fa-xmark') < 0 && classList.indexOf('fa-remove') < 0) {
return; return;
} }
} }
@ -815,6 +815,7 @@ export class CoreQuestionHelperProvider {
icon.parentNode?.replaceChild(newIcon, icon); icon.parentNode?.replaceChild(newIcon, icon);
}); });
// Treat legacy markup used before MDL-77856 (4.2).
const spans = Array.from(element.querySelectorAll('.feedbackspan.accesshide')); const spans = Array.from(element.querySelectorAll('.feedbackspan.accesshide'));
spans.forEach((span) => { spans.forEach((span) => {
// Search if there's a hidden feedback for this element. // Search if there's a hidden feedback for this element.
@ -851,20 +852,37 @@ export class CoreQuestionHelperProvider {
contextInstanceId?: number, contextInstanceId?: number,
courseId?: number, courseId?: number,
): void { ): void {
const icons = <HTMLElement[]> Array.from(element.querySelectorAll('ion-icon.questioncorrectnessicon[tappable]')); const icons = <HTMLElement[]> Array.from(element.querySelectorAll('ion-icon.questioncorrectnessicon'));
const title = Translate.instant('core.question.feedback'); const title = Translate.instant('core.question.feedback');
const getClickableFeedback = (icon: HTMLElement) => {
if (icon.parentElement instanceof HTMLButtonElement && icon.parentElement.dataset.toggle === 'popover') {
return {
element: icon.parentElement,
html: icon.parentElement?.dataset.content,
};
}
icons.forEach((icon) => { // Support legacy icons used before MDL-77856 (4.2).
// Search the feedback for the icon. if (icon.hasAttribute('tappable')) {
const span = <HTMLElement | undefined> icon.parentElement?.querySelector('.feedbackspan.accesshide'); return {
element: icon,
html: icon.parentElement?.querySelector('.feedbackspan.accesshide')?.innerHTML,
};
}
if (!span) { return null;
};
icons.forEach(icon => {
const target = getClickableFeedback(icon);
if (!target || !target.html) {
return; return;
} }
// There's a hidden feedback, show it when the icon is clicked. // There's a hidden feedback, show it when the icon is clicked.
icon.addEventListener('click', () => { target.element.addEventListener('click', () => {
CoreTextUtils.viewText(title, span.innerHTML, { CoreTextUtils.viewText(title, target.html ?? '', {
component: component, component: component,
componentId: componentId, componentId: componentId,
filter: true, filter: true,

View File

@ -112,6 +112,11 @@ core-format-text {
margin: 0; margin: 0;
padding: 10px 0; padding: 10px 0;
} }
.btn-link {
background: none;
}
} }
@keyframes loading { @keyframes loading {