Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(rule): Label and Name from Content mismatch WCAG21 (Issue #1149) #1335

Merged
merged 44 commits into from
Feb 21, 2019

Conversation

jeeyyy
Copy link
Contributor

@jeeyyy jeeyyy commented Jan 28, 2019

This PR does the below:

  • Implements a new rule -> label and name from content mismatch.
  • This PR has been branched from PR fix: Solve several accessible-name issues #1163 , to utilise the a11y-name computation, so reviews required only on commit - ef1c638, also ideally this should be merged after the earlier said PR is merged.

Closes issue:

Reviewer checks

Required fields, to be filled out by PR reviewer(s)

  • Follows the commit message policy, appropriate for next version
  • Has documentation updated, a DU ticket, or requires no documentation change
  • Includes new tests, or was unnecessary
  • Code is reviewed for security by: @WilcoFiers

@jeeyyy jeeyyy requested a review from a team as a code owner January 28, 2019 11:16
@jeeyyy jeeyyy changed the title feat(rule): label and name from content mismatch - wcag21a feat(rule): Label and Name from Content mismatch WCAG21 (Issue #1149) Jan 29, 2019
lib/checks/label/label-content-name-mismatch.js Outdated Show resolved Hide resolved
lib/rules/label-content-name-mismatch.json Outdated Show resolved Hide resolved
lib/rules/label-content-name-mismatch-matches.js Outdated Show resolved Hide resolved
lib/rules/label-content-name-mismatch-matches.js Outdated Show resolved Hide resolved
lib/rules/label-content-name-mismatch-matches.js Outdated Show resolved Hide resolved
lib/checks/label/label-content-name-mismatch.js Outdated Show resolved Hide resolved
lib/checks/label/label-content-name-mismatch.json Outdated Show resolved Hide resolved
lib/rules/label-content-name-mismatch-matches.js Outdated Show resolved Hide resolved
lib/checks/label/label-content-name-mismatch.js Outdated Show resolved Hide resolved
lib/checks/label/label-content-name-mismatch.js Outdated Show resolved Hide resolved
lib/checks/label/label-content-name-mismatch.js Outdated Show resolved Hide resolved
lib/checks/label/label-content-name-mismatch.js Outdated Show resolved Hide resolved
lib/commons/text/is-human-interpretable.js Outdated Show resolved Hide resolved
lib/commons/text/is-human-interpretable.js Outdated Show resolved Hide resolved
test/commons/text/is-human-interpretable.js Outdated Show resolved Hide resolved
test/commons/text/is-human-interpretable.js Outdated Show resolved Hide resolved
test/commons/text/is-human-interpretable.js Outdated Show resolved Hide resolved
test/commons/text/is-human-interpretable.js Show resolved Hide resolved
test/commons/text/is-human-interpretable.js Show resolved Hide resolved
package.json Outdated
@@ -86,6 +86,7 @@
"clone": "~2.1.1",
"css-selector-parser": "^1.3.0",
"dot": "~1.1.2",
"emoji-regex": "^7.0.3",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not comfortable pulling in package that is maintained by a single person, and that has very few weekly download. Either we lock down the version of this and do a security audit on it, or we ship our own.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Locked version to 7.0.3 and performed an audit.

image

@@ -0,0 +1,16 @@
describe('text.replacePunctuation', function() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add tests for the two other sequences you've got in punctuation.js

* @param {String} replaceWith (Optional) replacement string
* @returns {String}
*/
text.replacePunctuation = function replacePunctuation(str, replaceWith = '') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename this file and its tests to replace-punctuation.js so that its consistent with the function.

* @param {String} str string to operate on
* @returns {String}
*/
text.replaceEmojiUnicode = function replaceEmojiUnicode(str, replaceWith = '') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason you put the punctuation stuff in a different file, but the emoji stuff in a shared file with nonBmp? Probably best to split those out too.

* @param {String} str string to verify
* @returns {Boolean}
*/
text.isNonBmpUnicode = function isNonBmpUnicode(str) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say this needs to be called hasNonBmpUnicode, seeing as you're checking if the string includes any such characters, rather than that it only contains those chars. Same for the other functions.

{
"description": "label-content-name-mismatch tests",
"rule": "label-content-name-mismatch",
"violations": [["#fail1"], ["#fail2"], ["#fail3"], ["#fail4"], ["#fail5"]],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add "incomplete" integration tests as well.

});

it('returns false if element role is not supported with name from contents', function() {
var vNode = queryFixture('<textarea id="target"></textarea>');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This elm could just as easily be false because it doesn't have an accessible name and/or text content. This test doesn't prove what you say it does.

assert.isFalse(actual);
});

it('returns true for non-widget role that does support name from content', function() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you resolved my comment here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tooltip is a widget role - https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques

This is a typo in the test description. Fixed.


it('returns false for hidden (non visible) text content', function() {
var vNode = queryFixture(
'<button id="target" aria-label="close"><span style="display:none"></span></button>'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no hidden content in this test.

var actual = rule.matches(vNode.actualNode, vNode);
assert.isTrue(actual);
});
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should add a test for an elm with an implicit name-from-content role that is replaced with an explicit role that does not have name from content. For example <button role="tooltip">

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tooltip does support name from content, for example status does not, added a testcase.

text.replacePunctuation(
text.replaceNonBmpUnicode(text.replaceEmojiUnicode(str))
)
const noEmojiUnicodeStr = text.replaceUnicode(str, (type = 'emoji'));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not:

text.replaceUnicode(str, {
  emoji: true,
  nonBmp: true,
  punctuations: true
})

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Firstly, unicode only comprises emoji and nonBmp at the moment. Punctuations are handled separately. I wouldn't want to mix and match everything into the same options object as it can get verbose.

Hence went with the simpler type=* argument.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After discussion, updated as agreed.

Copy link
Contributor

@WilcoFiers WilcoFiers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple small problems with your tests still.

<button id="incomplete1" aria-label="comet">☄️</button>
<button id="incomplete2" aria-label="☄️">shooting star</button>
<button id="incomplete3" aria-label="help">?</button>
<button id="incomplete4" aria-label="&#x1F354">&#x1F354</button>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You didn't close this entity code with a ;.

<button id='incomplete7' aria-label="close">X</button>
<button id="incomplete8" aria-label="comet">☄️</button>
<button id="incomplete9" aria-label="help">?</button>
<button id="incomplete10" aria-label="&#x1F354">&#x1F354</button>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

});

it('returns false if given element has no role', function() {
var vNode = queryFixture('<div id="target"></div>');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test doesn't have content or aria-label either. Your test doesn't prove what it presupposes.


it('returns false if element role is not supported with name from contents', function() {
var vNode = queryFixture(
'<div id="target" role="progressbar" aria-valuenow="20" aria-valuemin="0" aria-valuemax="100">20 %</div>'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, aria-label(ledby) is missing.

assert.isFalse(actual);
});

it('returns false if implicit element role is overridden to a role that dos not support name from contents', function() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"dos" -> "does"


it('returns false if implicit element role is overridden to a role that dos not support name from contents', function() {
var vNode = queryFixture(
'<button id="target" role="status">Your changes were automatically saved.</button>'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, aria-label(ledby) is missing.

@WilcoFiers WilcoFiers merged commit a4255da into develop Feb 21, 2019
@WilcoFiers WilcoFiers deleted the new-rule-lcnm branch February 21, 2019 18:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants