Skip to content

Commit 1c36f5d

Browse files
authored
Expose answer content to VoiceOver in Tutorials' Quiz (swiftlang#731)
* [rdar://115116964] fix: expose answer content to voiceover * [rdar://115116964] test: fix tests * [rdar://115116964] fix: keep aria-live element always rendered
1 parent b12dd2d commit 1c36f5d

File tree

3 files changed

+33
-19
lines changed

3 files changed

+33
-19
lines changed

src/components/Tutorial/Assessments/Quiz.vue

+13-13
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,19 @@
2929
</label>
3030
</fieldset>
3131
<div aria-live="assertive" class="visuallyhidden">
32-
{{ ariaLiveText }}
32+
<i18n
33+
v-if="checkedIndex != null"
34+
path="tutorials.assessment.answer-result"
35+
tag="span"
36+
>
37+
<template #answer>
38+
<ContentNode class="question" :content="choices[checkedIndex].content" />
39+
</template>
40+
<template #result>{{ choices[checkedIndex].isCorrect
41+
? $t('tutorials.assessment.correct')
42+
: $t('tutorials.assessment.incorrect')
43+
}}</template>
44+
</i18n>
3345
</div>
3446
<div class="controls">
3547
<ButtonLink
@@ -115,18 +127,6 @@ export default {
115127
this.userChoices[correctChoice].checked
116128
));
117129
},
118-
ariaLiveText() {
119-
if (this.checkedIndex === null) return '';
120-
const { isCorrect } = this.choices[this.checkedIndex];
121-
return `${
122-
this.$t('tutorials.assessment.answer-number-is', { index: this.checkedIndex + 1 })
123-
} ${
124-
isCorrect
125-
? this.$t('tutorials.assessment.correct')
126-
: this.$t('tutorials.assessment.incorrect')
127-
}
128-
`;
129-
},
130130
},
131131
methods: {
132132
getIconComponent(index) {

src/lang/locales/en-US.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"assessment": {
2525
"check-your-understanding": "Check Your Understanding",
2626
"success-message": "Great job, you've answered all the questions for this tutorial.",
27-
"answer-number-is": "Answer number {index} is",
27+
"answer-result": "Answer {answer} is {result}",
2828
"correct": "correct",
2929
"incorrect": "incorrect",
3030
"next-question": "Next question",

tests/unit/components/Tutorial/Assessments/Quiz.spec.js

+19-5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ import { shallowMount } from '@vue/test-utils';
1212
import ContentNode from 'docc-render/components/ContentNode.vue';
1313
import Quiz from 'docc-render/components/Tutorial/Assessments/Quiz.vue';
1414

15+
const i18nStub = {
16+
name: 'i18n',
17+
template: '<span>Answer is <slot name="result"/></span>',
18+
};
19+
1520
const textContent = str => ([{
1621
type: 'text',
1722
text: str,
@@ -105,7 +110,10 @@ describe('Quiz', () => {
105110

106111
describe('default', () => {
107112
beforeEach(() => {
108-
wrapper = shallowMount(Quiz, { propsData });
113+
wrapper = shallowMount(Quiz, {
114+
propsData,
115+
stubs: { i18n: i18nStub },
116+
});
109117
});
110118

111119
it('renders a div.quiz root', () => {
@@ -164,7 +172,11 @@ describe('Quiz', () => {
164172
let submit;
165173

166174
beforeEach(() => {
167-
wrapper = shallowMount(Quiz, { propsData, attachToDocument: true });
175+
wrapper = shallowMount(Quiz, {
176+
propsData,
177+
stubs: { i18n: i18nStub },
178+
attachToDocument: true,
179+
});
168180
choices = wrapper.findAll('.choice');
169181
submit = wrapper.find('.check');
170182
});
@@ -199,21 +211,23 @@ describe('Quiz', () => {
199211
});
200212

201213
it('updates the aria live text telling the user if the answer chosen is correct or incorrect', () => {
202-
const ariaLive = wrapper.find('[aria-live="assertive"].visuallyhidden');
214+
let ariaLive = wrapper.find('[aria-live="assertive"].visuallyhidden');
203215
expect(ariaLive.exists()).toBe(true);
204216
expect(ariaLive.text()).toBe('');
205217

206218
let choice = choices.at(1);
207219
choice.trigger('click');
208220
submit.trigger('click');
209221

210-
expect(ariaLive.text()).toBe('tutorials.assessment.answer-number-is 2 tutorials.assessment.incorrect');
222+
ariaLive = wrapper.find('[aria-live="assertive"].visuallyhidden > span');
223+
expect(ariaLive.text()).toBe('Answer is tutorials.assessment.incorrect');
211224

212225
choice = choices.at(0);
213226
choice.trigger('click');
214227
submit.trigger('click');
215228

216-
expect(ariaLive.text()).toBe('tutorials.assessment.answer-number-is 1 tutorials.assessment.correct');
229+
ariaLive = wrapper.find('[aria-live="assertive"].visuallyhidden > span');
230+
expect(ariaLive.text()).toBe('Answer is tutorials.assessment.correct');
217231
});
218232
});
219233
});

0 commit comments

Comments
 (0)