From 09a3d4168c49e94309ba730bb08cc5026f46428d Mon Sep 17 00:00:00 2001 From: Jesus Balderrama Date: Fri, 11 Sep 2026 14:12:51 -0600 Subject: [PATCH 1/5] fix: announce instructional paragraphs when navigating choice options --- xblocks_contrib/problem/capa/capa_problem.py | 16 ++++++++++++++++ xblocks_contrib/problem/capa/inputtypes.py | 1 + .../problem/capa/templates/choicegroup.html | 1 + 3 files changed, 18 insertions(+) diff --git a/xblocks_contrib/problem/capa/capa_problem.py b/xblocks_contrib/problem/capa/capa_problem.py index 00a9e6f3..03f32d3e 100644 --- a/xblocks_contrib/problem/capa/capa_problem.py +++ b/xblocks_contrib/problem/capa/capa_problem.py @@ -1150,6 +1150,18 @@ def _preprocess_problem(self, tree, minimal_init): # private return problem_data + @staticmethod + def _preceding_prompt_ids(response, responsetype_id): + """Assign ids to contiguous preceding ``

`` siblings and return them in document order.""" + ids = [] + sibling = response.getprevious() + while sibling is not None and isinstance(sibling.tag, str) and sibling.tag.lower() == "p": + pid = sibling.get("id") or f"prompt_{responsetype_id}_{len(ids) + 1}" + sibling.set("id", pid) + ids.append(pid) + sibling = sibling.getprevious() + return list(reversed(ids)) + def response_a11y_data( # pylint: disable=too-many-locals,too-many-branches self, response, inputfields, responsetype_id, problem_data ): @@ -1193,11 +1205,14 @@ def response_a11y_data( # pylint: disable=too-many-locals,too-many-branches if group_description_ids: response.set("multiinput-group_description_ids", " ".join(group_description_ids)) + preceding_prompt_ids = self._preceding_prompt_ids(response, responsetype_id) + for inputfield in inputfields: problem_data[inputfield.get("id")] = { "group_label": group_label_tag_text, "label": HTML(inputfield.attrib.get("label", "")), "descriptions": {}, + "additional_describedby_ids": list(preceding_prompt_ids), } else: # Extract label value from

Date: Fri, 11 Sep 2026 14:56:19 -0600 Subject: [PATCH 2/5] refactor: validations added y and tests adjusted --- xblocks_contrib/problem/capa/capa_problem.py | 20 ++++++++++++---- .../problem/capa/tests/test_capa_problem.py | 23 ++++++++++++++++--- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/xblocks_contrib/problem/capa/capa_problem.py b/xblocks_contrib/problem/capa/capa_problem.py index 03f32d3e..ff5f57e4 100644 --- a/xblocks_contrib/problem/capa/capa_problem.py +++ b/xblocks_contrib/problem/capa/capa_problem.py @@ -1205,15 +1205,21 @@ def response_a11y_data( # pylint: disable=too-many-locals,too-many-branches if group_description_ids: response.set("multiinput-group_description_ids", " ".join(group_description_ids)) - preceding_prompt_ids = self._preceding_prompt_ids(response, responsetype_id) + preceding_prompt_ids = ( + self._preceding_prompt_ids(response, responsetype_id) + if inputfields[0].tag in ACCESSIBLE_CAPA_INPUT_TYPES + else [] + ) for inputfield in inputfields: - problem_data[inputfield.get("id")] = { + entry = { "group_label": group_label_tag_text, "label": HTML(inputfield.attrib.get("label", "")), "descriptions": {}, - "additional_describedby_ids": list(preceding_prompt_ids), } + if preceding_prompt_ids: + entry["additional_describedby_ids"] = list(preceding_prompt_ids) + problem_data[inputfield.get("id")] = entry else: # Extract label value from