make CAPA problems (MultipleChoice and Checkboxes) accessible
This commit is contained in:
@@ -176,7 +176,7 @@ class LoncapaProblem(object):
|
||||
# transformations. This also creates the dict (self.responders) of Response
|
||||
# instances for each question in the problem. The dict has keys = xml subtree of
|
||||
# Response, values = Response instance
|
||||
self._preprocess_problem(self.tree)
|
||||
self.problem_data = self._preprocess_problem(self.tree)
|
||||
|
||||
if not self.student_answers: # True when student_answers is an empty dict
|
||||
self.set_initial_display()
|
||||
@@ -752,7 +752,10 @@ class LoncapaProblem(object):
|
||||
|
||||
if problemtree.tag in inputtypes.registry.registered_tags():
|
||||
# If this is an inputtype subtree, let it render itself.
|
||||
status = "unsubmitted"
|
||||
response_id = self.problem_id + '_' + problemtree.get('response_id')
|
||||
response_data = self.problem_data[response_id]
|
||||
|
||||
status = 'unsubmitted'
|
||||
msg = ''
|
||||
hint = ''
|
||||
hintmode = None
|
||||
@@ -766,7 +769,7 @@ class LoncapaProblem(object):
|
||||
hintmode = self.correct_map.get_hintmode(pid)
|
||||
answervariable = self.correct_map.get_property(pid, 'answervariable')
|
||||
|
||||
value = ""
|
||||
value = ''
|
||||
if self.student_answers and problemid in self.student_answers:
|
||||
value = self.student_answers[problemid]
|
||||
|
||||
@@ -780,6 +783,7 @@ class LoncapaProblem(object):
|
||||
'id': input_id,
|
||||
'input_state': self.input_state[input_id],
|
||||
'answervariable': answervariable,
|
||||
'response_data': response_data,
|
||||
'feedback': {
|
||||
'message': msg,
|
||||
'hint': hint,
|
||||
@@ -836,6 +840,7 @@ class LoncapaProblem(object):
|
||||
Obtain all responder answers and save as self.responder_answers dict (key = response)
|
||||
"""
|
||||
response_id = 1
|
||||
problem_data = {}
|
||||
self.responders = {}
|
||||
for response in tree.xpath('//' + "|//".join(responsetypes.registry.registered_tags())):
|
||||
response_id_str = self.problem_id + "_" + str(response_id)
|
||||
@@ -857,6 +862,12 @@ class LoncapaProblem(object):
|
||||
entry.attrib['id'] = "%s_%i_%i" % (self.problem_id, response_id, answer_id)
|
||||
answer_id = answer_id + 1
|
||||
|
||||
# Find the label and save it for html transformation step
|
||||
responsetype_label = response.find('label')
|
||||
problem_data[self.problem_id + '_' + str(response_id)] = {
|
||||
'label': responsetype_label.text if responsetype_label is not None else ''
|
||||
}
|
||||
|
||||
# instantiate capa Response
|
||||
responsetype_cls = responsetypes.registry.get_class_for_tag(response.tag)
|
||||
responder = responsetype_cls(response, inputfields, self.context, self.capa_system, self.capa_module)
|
||||
@@ -881,3 +892,5 @@ class LoncapaProblem(object):
|
||||
for solution in tree.findall('.//solution'):
|
||||
solution.attrib['id'] = "%s_solution_%i" % (self.problem_id, solution_id)
|
||||
solution_id += 1
|
||||
|
||||
return problem_data
|
||||
|
||||
@@ -224,7 +224,8 @@ class InputTypeBase(object):
|
||||
self.hint = feedback.get('hint', '')
|
||||
self.hintmode = feedback.get('hintmode', None)
|
||||
self.input_state = state.get('input_state', {})
|
||||
self.answervariable = state.get("answervariable", None)
|
||||
self.answervariable = state.get('answervariable', None)
|
||||
self.response_data = state.get('response_data', None)
|
||||
|
||||
# put hint above msg if it should be displayed
|
||||
if self.hintmode == 'always':
|
||||
@@ -316,8 +317,10 @@ class InputTypeBase(object):
|
||||
'value': self.value,
|
||||
'status': Status(self.status, self.capa_system.i18n.ugettext),
|
||||
'msg': self.msg,
|
||||
'response_data': self.response_data,
|
||||
'STATIC_URL': self.capa_system.STATIC_URL,
|
||||
}
|
||||
|
||||
context.update(
|
||||
(a, v) for (a, v) in self.loaded_attributes.iteritems() if a in self.to_render
|
||||
)
|
||||
|
||||
@@ -250,8 +250,18 @@ class LoncapaResponse(object):
|
||||
- renderer : procedure which produces HTML given an ElementTree
|
||||
- response_msg: a message displayed at the end of the Response
|
||||
"""
|
||||
# render ourself as a <span> + our content
|
||||
tree = etree.Element('span')
|
||||
_ = self.capa_system.i18n.ugettext
|
||||
|
||||
# get responsetype index to make responsetype label
|
||||
response_index = self.xml.attrib['id'].split('_')[-1]
|
||||
# Translators: index here could be 1,2,3 and so on
|
||||
response_label = _(u'Question {index}').format(index=response_index)
|
||||
|
||||
# wrap the content inside a section
|
||||
tree = etree.Element('section')
|
||||
tree.set('class', 'wrapper-problem-response')
|
||||
tree.set('tabindex', '-1')
|
||||
tree.set('aria-label', response_label)
|
||||
|
||||
# problem author can make this span display:inline
|
||||
if self.xml.get('inline', ''):
|
||||
|
||||
@@ -1,43 +1,56 @@
|
||||
<%
|
||||
def is_radio_input(choice_id):
|
||||
return input_type == 'radio' and ((isinstance(value, basestring) and (choice_id == value)) or (
|
||||
not isinstance(value, basestring) and choice_id in value
|
||||
))
|
||||
%>
|
||||
<form class="choicegroup capa_inputtype" id="inputtype_${id}">
|
||||
<fieldset role="${input_type}group" aria-label="${label}">
|
||||
% for choice_id, choice_description in choices:
|
||||
<label for="input_${id}_${choice_id}"
|
||||
## If the student has selected this choice...
|
||||
% if input_type == 'radio' and ( (isinstance(value, basestring) and (choice_id == value)) or (not isinstance(value, basestring) and choice_id in value) ):
|
||||
<fieldset>
|
||||
% if response_data and response_data['label']:
|
||||
<legend id="${id}-legend" class="response-fieldset-legend question-text">${response_data['label']}</legend>
|
||||
% else:
|
||||
<legend>Question</legend>
|
||||
% endif
|
||||
% for choice_id, choice_label in choices:
|
||||
<div class="field" aria-live="polite" aria-atomic="true">
|
||||
<%
|
||||
if status == 'correct':
|
||||
correctness = 'correct'
|
||||
elif status == 'partially-correct':
|
||||
correctness = 'partially-correct'
|
||||
elif status == 'incorrect':
|
||||
correctness = 'incorrect'
|
||||
else:
|
||||
correctness = None
|
||||
label_class = 'response-label field-label label-inline'
|
||||
%>
|
||||
% if correctness and not show_correctness=='never':
|
||||
class="choicegroup_${correctness}"
|
||||
% endif
|
||||
% endif
|
||||
>
|
||||
<input type="${input_type}" name="input_${id}${name_array_suffix}" id="input_${id}_${choice_id}" aria-role="radio" aria-describedby="answer_${id}" value="${choice_id}"
|
||||
## If the student selected this choice...
|
||||
% if input_type == 'radio' and ( (isinstance(value, basestring) and (choice_id == value)) or (not isinstance(value, basestring) and choice_id in value) ):
|
||||
checked="true"
|
||||
% elif input_type != 'radio' and choice_id in value:
|
||||
checked="true"
|
||||
% endif
|
||||
% if input_type != 'radio':
|
||||
aria-multiselectable="true"
|
||||
% endif
|
||||
<label id="${id}-${choice_id}-label"
|
||||
## If the student has selected this choice...
|
||||
% if is_radio_input(choice_id):
|
||||
<%
|
||||
if status == 'correct':
|
||||
correctness = 'correct'
|
||||
elif status == 'partially-correct':
|
||||
correctness = 'partially-correct'
|
||||
elif status == 'incorrect':
|
||||
correctness = 'incorrect'
|
||||
else:
|
||||
correctness = None
|
||||
%>
|
||||
% if correctness and not show_correctness == 'never':
|
||||
<% label_class += ' choicegroup_' + correctness %>
|
||||
% endif
|
||||
% endif
|
||||
class="${label_class}" >
|
||||
|
||||
/> ${choice_description}
|
||||
<input type="${input_type}" name="input_${id}${name_array_suffix}" id="input_${id}_${choice_id}" class="field-input input-${input_type}" value="${choice_id}"
|
||||
## If the student selected this choice...
|
||||
% if is_radio_input(choice_id):
|
||||
checked="true"
|
||||
% elif input_type != 'radio' and choice_id in value:
|
||||
checked="true"
|
||||
% endif
|
||||
/> ${choice_label}
|
||||
|
||||
% if input_type == 'radio' and ( (isinstance(value, basestring) and (choice_id == value)) or (not isinstance(value, basestring) and choice_id in value) ):
|
||||
% if status in ('correct', 'partially-correct', 'incorrect') and not show_correctness=='never':
|
||||
<span class="sr status">${choice_description|h} - ${status.display_name}</span>
|
||||
% endif
|
||||
% endif
|
||||
</label>
|
||||
% if is_radio_input(choice_id):
|
||||
% if status in ('correct', 'partially-correct', 'incorrect') and not show_correctness == 'never':
|
||||
<span class="sr status" id="${id}-${choice_id}-labeltext">${status.display_name}</span>
|
||||
% endif
|
||||
% endif
|
||||
</label>
|
||||
</div>
|
||||
% endfor
|
||||
<span id="answer_${id}"></span>
|
||||
</fieldset>
|
||||
@@ -45,9 +58,9 @@
|
||||
% if input_type == 'checkbox' or not value:
|
||||
<span class="status ${status.classname if show_correctness != 'never' else 'unanswered'}" id="status_${id}" aria-describedby="inputtype_${id}" data-tooltip="${status.display_tooltip}">
|
||||
<span class="sr">
|
||||
%for choice_id, choice_description in choices:
|
||||
%for choice_id, choice_label in choices:
|
||||
% if choice_id in value:
|
||||
${choice_description},
|
||||
${choice_label},
|
||||
%endif
|
||||
%endfor
|
||||
-
|
||||
|
||||
@@ -155,11 +155,12 @@ class CapaHtmlRenderTest(unittest.TestCase):
|
||||
question_element = rendered_html.find("p")
|
||||
self.assertEqual(question_element.text, "Test question")
|
||||
|
||||
# Expect that the response has been turned into a <span>
|
||||
response_element = rendered_html.find("span")
|
||||
self.assertEqual(response_element.tag, "span")
|
||||
# Expect that the response has been turned into a <section> with correct attributes
|
||||
response_element = rendered_html.find("section")
|
||||
self.assertEqual(response_element.tag, "section")
|
||||
self.assertEqual(response_element.attrib["aria-label"], "Question 1")
|
||||
|
||||
# Expect that the response <span>
|
||||
# Expect that the response <section>
|
||||
# that contains a <div> for the textline
|
||||
textline_element = response_element.find("div")
|
||||
self.assertEqual(textline_element.text, 'Input Template Render')
|
||||
@@ -201,6 +202,29 @@ class CapaHtmlRenderTest(unittest.TestCase):
|
||||
expected_calls
|
||||
)
|
||||
|
||||
def test_correct_aria_label(self):
|
||||
xml = """
|
||||
<problem>
|
||||
<choiceresponse>
|
||||
<checkboxgroup>
|
||||
<choice correct="true">over-suspicious</choice>
|
||||
<choice correct="false">funny</choice>
|
||||
</checkboxgroup>
|
||||
</choiceresponse>
|
||||
<choiceresponse>
|
||||
<checkboxgroup>
|
||||
<choice correct="true">Urdu</choice>
|
||||
<choice correct="false">Finnish</choice>
|
||||
</checkboxgroup>
|
||||
</choiceresponse>
|
||||
</problem>
|
||||
"""
|
||||
problem = new_loncapa_problem(xml)
|
||||
rendered_html = etree.XML(problem.get_html())
|
||||
sections = rendered_html.findall('section')
|
||||
self.assertEqual(sections[0].attrib['aria-label'], 'Question 1')
|
||||
self.assertEqual(sections[1].attrib['aria-label'], 'Question 2')
|
||||
|
||||
def test_render_response_with_overall_msg(self):
|
||||
# CustomResponse script that sets an overall_message
|
||||
script = textwrap.dedent("""
|
||||
|
||||
@@ -122,13 +122,16 @@ class ChoiceGroupTemplateTest(TemplateTestCase):
|
||||
|
||||
def setUp(self):
|
||||
choices = [('1', 'choice 1'), ('2', 'choice 2'), ('3', 'choice 3')]
|
||||
self.context = {'id': '1',
|
||||
'choices': choices,
|
||||
'status': Status('correct'),
|
||||
'label': 'test',
|
||||
'input_type': 'checkbox',
|
||||
'name_array_suffix': '1',
|
||||
'value': '3'}
|
||||
self.context = {
|
||||
'id': '1',
|
||||
'choices': choices,
|
||||
'status': Status('correct'),
|
||||
'label': 'test',
|
||||
'input_type': 'checkbox',
|
||||
'name_array_suffix': '1',
|
||||
'value': '3',
|
||||
'response_data': {'label': 'test'}
|
||||
}
|
||||
super(ChoiceGroupTemplateTest, self).setUp()
|
||||
|
||||
def test_problem_marked_correct(self):
|
||||
@@ -229,7 +232,7 @@ class ChoiceGroupTemplateTest(TemplateTestCase):
|
||||
for test_conditions in conditions:
|
||||
self.context.update(test_conditions)
|
||||
xml = self.render_to_xml(self.context)
|
||||
xpath = "//label[@class='choicegroup_correct']"
|
||||
xpath = "//label[contains(@class, 'choicegroup_correct')]"
|
||||
self.assert_has_xpath(xml, xpath, self.context)
|
||||
|
||||
# Should NOT mark the whole problem
|
||||
@@ -250,7 +253,7 @@ class ChoiceGroupTemplateTest(TemplateTestCase):
|
||||
for test_conditions in conditions:
|
||||
self.context.update(test_conditions)
|
||||
xml = self.render_to_xml(self.context)
|
||||
xpath = "//label[@class='choicegroup_incorrect']"
|
||||
xpath = "//label[contains(@class, 'choicegroup_incorrect')]"
|
||||
self.assert_has_xpath(xml, xpath, self.context)
|
||||
|
||||
# Should NOT mark the whole problem
|
||||
@@ -340,8 +343,8 @@ class ChoiceGroupTemplateTest(TemplateTestCase):
|
||||
|
||||
def test_label(self):
|
||||
xml = self.render_to_xml(self.context)
|
||||
xpath = "//fieldset[@aria-label='%s']" % self.context['label']
|
||||
self.assert_has_xpath(xml, xpath, self.context)
|
||||
xpath = "//legend"
|
||||
self.assert_has_text(xml, xpath, self.context['label'])
|
||||
|
||||
|
||||
class TextlineTemplateTest(TemplateTestCase):
|
||||
|
||||
@@ -66,7 +66,7 @@ class @Problem
|
||||
detail = @el.data('progress_detail')
|
||||
status = @el.data('progress_status')
|
||||
|
||||
# Render 'x/y point(s)' if student has attempted question
|
||||
# Render 'x/y point(s)' if student has attempted question
|
||||
if status != 'none' and detail? and (jQuery.type(detail) == "string") and detail.indexOf('/') > 0
|
||||
a = detail.split('/')
|
||||
earned = parseFloat(a[0])
|
||||
@@ -628,10 +628,10 @@ class @Problem
|
||||
choicegroup: (element, display, answers) =>
|
||||
element = $(element)
|
||||
|
||||
input_id = element.attr('id').replace(/inputtype_/,'')
|
||||
input_id = element.attr('id').replace(/inputtype_/, '')
|
||||
answer = answers[input_id]
|
||||
for choice in answer
|
||||
element.find("label[for='input_#{input_id}_#{choice}']").addClass 'choicegroup_correct'
|
||||
element.find("#input_#{input_id}_#{choice}").parent("label").addClass 'choicegroup_correct'
|
||||
|
||||
javascriptinput: (element, display, answers) =>
|
||||
answer_id = $(element).attr('id').split("_")[1...].join("_")
|
||||
@@ -641,7 +641,7 @@ class @Problem
|
||||
choicetextgroup: (element, display, answers) =>
|
||||
element = $(element)
|
||||
|
||||
input_id = element.attr('id').replace(/inputtype_/,'')
|
||||
input_id = element.attr('id').replace(/inputtype_/, '')
|
||||
answer = answers[input_id]
|
||||
for choice in answer
|
||||
element.find("section#forinput#{choice}").addClass 'choicetextgroup_show_correct'
|
||||
@@ -821,4 +821,3 @@ class @Problem
|
||||
]
|
||||
hint_container.attr('hint_index', response.hint_index)
|
||||
@$('.hint-button').focus() # a11y focus on click, like the Check button
|
||||
|
||||
|
||||
@@ -129,6 +129,11 @@ class ProblemPage(PageObject):
|
||||
self.q(css='div.problem button.reset').click()
|
||||
self.wait_for_ajax()
|
||||
|
||||
def click_show_hide_button(self):
|
||||
""" Click the Show/Hide button. """
|
||||
self.q(css='div.problem div.action .show').click()
|
||||
self.wait_for_ajax()
|
||||
|
||||
def wait_for_status_icon(self):
|
||||
"""
|
||||
wait for status icon
|
||||
@@ -199,3 +204,20 @@ class ProblemPage(PageObject):
|
||||
"""
|
||||
self.wait_for_element_visibility('body > .tooltip', 'A tooltip is visible.')
|
||||
return self.q(css='body > .tooltip').text[0]
|
||||
|
||||
def is_solution_tag_present(self):
|
||||
"""
|
||||
Check if solution/explanation is shown.
|
||||
"""
|
||||
solution_selector = '.solution-span div.detailed-solution'
|
||||
return self.q(css=solution_selector).is_present()
|
||||
|
||||
def is_correct_choice_highlighted(self, correct_choices):
|
||||
"""
|
||||
Check if correct answer/choice highlighted for choice group.
|
||||
"""
|
||||
xpath = '//fieldset/div[contains(@class, "field")][{0}]/label[contains(@class, "choicegroup_correct")]'
|
||||
for choice in correct_choices:
|
||||
if not self.q(xpath=xpath.format(choice)).is_present():
|
||||
return False
|
||||
return True
|
||||
|
||||
@@ -218,11 +218,11 @@ class CertificateProgressPageTest(UniqueCourseTest):
|
||||
self.course_nav.q(css='select option[value="{}"]'.format('blue')).first.click()
|
||||
|
||||
# Select correct radio button for the answer
|
||||
self.course_nav.q(css='fieldset label:nth-child(3) input').nth(0).click()
|
||||
self.course_nav.q(css='fieldset div.field:nth-child(4) input').nth(0).click()
|
||||
|
||||
# Select correct radio buttons for the answer
|
||||
self.course_nav.q(css='fieldset label:nth-child(1) input').nth(1).click()
|
||||
self.course_nav.q(css='fieldset label:nth-child(3) input').nth(1).click()
|
||||
self.course_nav.q(css='fieldset div.field:nth-child(2) input').nth(1).click()
|
||||
self.course_nav.q(css='fieldset div.field:nth-child(4) input').nth(1).click()
|
||||
|
||||
# Submit the answer
|
||||
self.course_nav.q(css='button.check.Check').click()
|
||||
|
||||
@@ -51,7 +51,7 @@ class ProblemsTest(UniqueCourseTest):
|
||||
email=self.email,
|
||||
password=self.password,
|
||||
course_id=self.course_id,
|
||||
staff=False
|
||||
staff=True
|
||||
).visit()
|
||||
|
||||
def get_problem(self):
|
||||
|
||||
@@ -324,7 +324,8 @@ class CheckboxProblemTypeTest(ProblemTypeTestBase, ProblemTypeTestMixin):
|
||||
'question_text': 'The correct answer is Choice 0 and Choice 2',
|
||||
'choice_type': 'checkbox',
|
||||
'choices': [True, False, True, False],
|
||||
'choice_names': ['Choice 0', 'Choice 1', 'Choice 2', 'Choice 3']
|
||||
'choice_names': ['Choice 0', 'Choice 1', 'Choice 2', 'Choice 3'],
|
||||
'explanation_text': 'This is explanation text'
|
||||
}
|
||||
|
||||
def setUp(self, *args, **kwargs):
|
||||
@@ -332,15 +333,6 @@ class CheckboxProblemTypeTest(ProblemTypeTestBase, ProblemTypeTestMixin):
|
||||
Additional setup for CheckboxProblemTypeTest
|
||||
"""
|
||||
super(CheckboxProblemTypeTest, self).setUp(*args, **kwargs)
|
||||
self.problem_page.a11y_audit.config.set_rules({
|
||||
'ignore': [
|
||||
'section', # TODO: AC-491
|
||||
'aria-allowed-attr', # TODO: AC-251
|
||||
'aria-valid-attr', # TODO: AC-251
|
||||
'aria-roles', # TODO: AC-251
|
||||
'checkboxgroup', # TODO: AC-251
|
||||
]
|
||||
})
|
||||
|
||||
def answer_problem(self, correct):
|
||||
"""
|
||||
@@ -352,6 +344,30 @@ class CheckboxProblemTypeTest(ProblemTypeTestBase, ProblemTypeTestMixin):
|
||||
else:
|
||||
self.problem_page.click_choice("choice_1")
|
||||
|
||||
@attr('shard_7')
|
||||
def test_can_show_hide_answer(self):
|
||||
"""
|
||||
Scenario: Verifies that show/hide answer button is working as expected.
|
||||
|
||||
Given that I am on courseware page
|
||||
And I can see a CAPA problem with show answer button
|
||||
When I click "Show Answer" button
|
||||
Then I should see "Hide Answer" text on button
|
||||
And I should see question's solution
|
||||
And I should see correct choices highlighted
|
||||
When I click "Hide Answer" button
|
||||
Then I should see "Show Answer" text on button
|
||||
And I should not see question's solution
|
||||
And I should not see correct choices highlighted
|
||||
"""
|
||||
self.problem_page.click_show_hide_button()
|
||||
self.assertTrue(self.problem_page.is_solution_tag_present())
|
||||
self.assertTrue(self.problem_page.is_correct_choice_highlighted(correct_choices=[1, 3]))
|
||||
|
||||
self.problem_page.click_show_hide_button()
|
||||
self.assertFalse(self.problem_page.is_solution_tag_present())
|
||||
self.assertFalse(self.problem_page.is_correct_choice_highlighted(correct_choices=[1, 3]))
|
||||
|
||||
|
||||
class MultipleChoiceProblemTypeTest(ProblemTypeTestBase, ProblemTypeTestMixin):
|
||||
"""
|
||||
@@ -378,13 +394,6 @@ class MultipleChoiceProblemTypeTest(ProblemTypeTestBase, ProblemTypeTestMixin):
|
||||
Additional setup for MultipleChoiceProblemTypeTest
|
||||
"""
|
||||
super(MultipleChoiceProblemTypeTest, self).setUp(*args, **kwargs)
|
||||
self.problem_page.a11y_audit.config.set_rules({
|
||||
'ignore': [
|
||||
'section', # TODO: AC-491
|
||||
'aria-valid-attr', # TODO: AC-251
|
||||
'radiogroup', # TODO: AC-251
|
||||
]
|
||||
})
|
||||
|
||||
def answer_problem(self, correct):
|
||||
"""
|
||||
@@ -422,13 +431,6 @@ class RadioProblemTypeTest(ProblemTypeTestBase, ProblemTypeTestMixin):
|
||||
Additional setup for RadioProblemTypeTest
|
||||
"""
|
||||
super(RadioProblemTypeTest, self).setUp(*args, **kwargs)
|
||||
self.problem_page.a11y_audit.config.set_rules({
|
||||
'ignore': [
|
||||
'section', # TODO: AC-491
|
||||
'aria-valid-attr', # TODO: AC-292
|
||||
'radiogroup', # TODO: AC-292
|
||||
]
|
||||
})
|
||||
|
||||
def answer_problem(self, correct):
|
||||
"""
|
||||
@@ -798,13 +800,6 @@ class RadioTextProblemTypeTest(ChoiceTextProbelmTypeTestBase, ProblemTypeTestMix
|
||||
Additional setup for RadioTextProblemTypeTest
|
||||
"""
|
||||
super(RadioTextProblemTypeTest, self).setUp(*args, **kwargs)
|
||||
self.problem_page.a11y_audit.config.set_rules({
|
||||
'ignore': [
|
||||
'section', # TODO: AC-491
|
||||
'label', # TODO: AC-285
|
||||
'radiogroup', # TODO: AC-285
|
||||
]
|
||||
})
|
||||
|
||||
|
||||
class CheckboxTextProblemTypeTest(ChoiceTextProbelmTypeTestBase, ProblemTypeTestMixin):
|
||||
@@ -831,13 +826,6 @@ class CheckboxTextProblemTypeTest(ChoiceTextProbelmTypeTestBase, ProblemTypeTest
|
||||
Additional setup for CheckboxTextProblemTypeTest
|
||||
"""
|
||||
super(CheckboxTextProblemTypeTest, self).setUp(*args, **kwargs)
|
||||
self.problem_page.a11y_audit.config.set_rules({
|
||||
'ignore': [
|
||||
'section', # TODO: AC-491
|
||||
'label', # TODO: AC-284
|
||||
'checkboxgroup', # TODO: AC-284
|
||||
]
|
||||
})
|
||||
|
||||
|
||||
class ImageProblemTypeTest(ProblemTypeTestBase, ProblemTypeTestMixin):
|
||||
@@ -885,9 +873,9 @@ class SymbolicProblemTypeTest(ProblemTypeTestBase, ProblemTypeTestMixin):
|
||||
}
|
||||
|
||||
status_indicators = {
|
||||
'correct': ['span div.correct'],
|
||||
'incorrect': ['span div.incorrect'],
|
||||
'unanswered': ['span div.unanswered'],
|
||||
'correct': ['div.capa_inputtype div.correct'],
|
||||
'incorrect': ['div.capa_inputtype div.incorrect'],
|
||||
'unanswered': ['div.capa_inputtype div.unanswered'],
|
||||
}
|
||||
|
||||
def setUp(self, *args, **kwargs):
|
||||
|
||||
Reference in New Issue
Block a user