Repository navigation
Conversation
|
Thanks for the pull request, @javoconsultant! This repository is currently maintained by Once you've gone through the following steps feel free to tag them in a comment and let them know that your changes are ready for engineering review. 🔘 Get product approvalIf you haven't already, check this list to see if your contribution needs to go through the product review process.
🔘 Provide contextTo help your reviewers and other members of the community understand the purpose and larger context of your changes, feel free to add as much of the following information to the PR description as you can:
🔘 Get a green buildIf one or more checks are failing, continue working on your changes until this is no longer the case and your build turns green. DetailsWhere can I find more information?If you'd like to get more details on all aspects of the review process for open source pull requests (OSPRs), check out the following resources: When can I expect my changes to be merged?Our goal is to get community contributions seen and reviewed as efficiently as possible. However, the amount of time that it takes to review and merge a PR can vary significantly based on factors such as:
💡 As a result it may take up to several weeks or months to complete a review and merge your PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #3291 +/- ##
========================================
Coverage 96.12% 96.12%
========================================
Files 1428 1428
Lines 34717 34724 +7
Branches 8295 8022 -273
========================================
+ Hits 33372 33379 +7
Misses 1304 1304
Partials 41 41 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
…sibility attributes
5c0bd66 to
9384a1c
Compare
mgwozdz-unicon
left a comment
There was a problem hiding this comment.
Claude and I reviewed this together, and we have a few requested changes:
1. Group treeitems now take their accessible name from their whole subtree (CompetencyTreeItem.tsx, the <li role="treeitem">)
A treeitem with no aria-label or aria-labelledby computes its accessible name from all of its text content. Now that a group's nested <ul role="group"> lives inside the group's own <li>, every descendant's text becomes part of the group's name. Running computeAccessibleName from dom-accessibility-api (the library Testing Library uses for getByRole(..., { name })) against the nestedTagsResponse fixture after Expand All gives:
- Root A:
"Root A Competency ID: EXT-001 Group A1 Leaf A1a Competency ID: EXT-003" - Group A1:
"Group A1 Leaf A1a Competency ID: EXT-003"
Before this PR the treeitem was the row <div>, so its name was only that row's own text. On a real taxonomy, a screen reader focusing a top-level group could read out the entire subtree. I have only checked this in jsdom, not in a real browser and screen reader, and axe does not flag it because a long name is not a rule violation. Could you point the treeitem's name at its own row instead, e.g. aria-labelledby referencing ids on the .competency-row__label span and the sr-only Competency ID span (via useId), so the ID is still announced?
2. The new "selects only the innermost node clicked" test is redundant (CompetencyTree.test.tsx, last test)
The test does catch ancestor selection, through toHaveBeenCalledTimes(1): without stopPropagation the click bubbles to Group A1's and Root A's <li> handlers and the mock is called three times. But three existing tests already fail the same way. I removed the event.stopPropagation() line in handleSelect and re-ran the file: the leaf-click test, the group-click test, and the leaf Enter/Space test all fail alongside the new one, because each already asserts a call count of 1. Could you drop the new test? If you'd like the intent stated explicitly, adding expect(onSelectCompetency).not.toHaveBeenCalledWith(expect.objectContaining({ id: 2 })) to the existing leaf-click test would cover it in one line.
3. Truncated comment (CompetencyTree.scss, above .competency-node--selected::before)
The comment now ends mid-sentence at "where it meets the shared". The edit removed the line that finished it ("border-radius arc").
…ubtree Addresses review feedback on openedx#3291: - A group's `<li role="treeitem">` now wraps its nested `<ul>`, so with no explicit label it computed its accessible name from every descendant's text. Point `aria-labelledby` at ids on the node's own label span and its sr-only Competency ID span (via `useId`) so the name is the row alone. - Drop the redundant "selects only the innermost node clicked" test; the three existing selection tests already fail without `stopPropagation`. State the intent in the leaf-click test with a `not.toHaveBeenCalledWith` assertion instead. - Restore the comment line truncated above `.competency-node--selected::before`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…t aria-labelledby attributes
01b7c86 to
f0ed696
Compare
@mgwozdz-unicon i've addressed your comments |
mgwozdz-unicon
left a comment
There was a problem hiding this comment.
Thank you, approving. Just one nit. Also, Claude says: The PR description still says "two new regression tests" and describes the "click or Enter on a nested leaf selects only that leaf" test, which has since been removed. It would be worth updating it to mention the accessible-name test instead.
Co-authored-by: Mary Gwozdz <mgwozdz@unicon.net>
dbdc26c to
fc7e539
Compare
Description
Follow-up to #3260, which fixed points 1-4 of openedx/openedx-core#821. QA then reported that the hover effect added there "appears only when the pointer at the top part of the row. When the pointer is at the left, right, or bottom part of the row, hover doesn't appear. And the row is clickable only at the top part of the row."
A group node in the tree paints its hover and selection tints across its whole grey envelope - header strip, the padding around it, and the nested children it wraps. But
role="treeitem", the click/keyboard handlers and the--selectable/--selectedstyling all lived on the.competency-rowheader<div>inside it, which is only as tall as its own text. The tinted box and the hit area were two different boxes.Hit-testing every pixel of each node in a browser quantified it:
QA706 Framework Root(outer group)QA706 Group Analysis(group)QA706 Leaf Data Interpretation(leaf)Leaf nodes, whose
<li>and row are the same box, were already fine.Changes
CompetencyTreeItem.tsx- the<li>itself is now thetreeitemand the click target, so the hit area is the tinted envelope.handleSelectstops propagation, since a child's<li>sits inside its ancestors' and would otherwise select every group above it on the way up.CompetencyTree.scss- fill, border, hover tint and the teal selected accent move onto the<li>. Hover uses:not(:has(li:hover))so only the innermost hovered node lights up.This also drops the old
role="none"workaround: atreeitemas a direct child of itstree/group<ul>is just the plain ARIA tree structure. And it lets the separate group-envelope tint, the group-level::beforeand the row-level::before'sdisplay: noneoverride collapse into a single.competency-node--selectedrule - the stylesheet is a net 36 lines shorter.Testing instructions
Other information
Verified in headless Chrome against the pre-change build:
axe-corereports 0 violations on the new markup, same as before.314 taxonomy tests pass, including two new regression tests: one asserting the group's
treeitemwraps its nested children, one asserting a click or Enter on a nested leaf selects only that leaf and never its ancestor groups.dprint,oxlint --type-aware --deny-warnings,stylelintandtsc --noEmitare all clean.No new dependencies, migrations, or i18n changes.
Supporting information
openedx/openedx-core#821
#3260
Best Practices Checklist
We're trying to move away from some deprecated patterns in this codebase. Please
check if your PR meets these recommendations before asking for a review:
.ts,.tsx).propTypesanddefaultPropsin any new or modified code.src/testUtils.tsx(specificallyinitializeMocks)apiHooks.tsin this repo for examples.messages.tsfiles have adescriptionfor translators to use.../in import paths. To import from parent folders, use@src, e.g.import { initializeMocks } from '@src/testUtils';instead offrom '../../../../testUtils'🤖 Generated with Claude Code