diff --git a/lib/checks/forms/autocomplete-a11y-evaluate.js b/lib/checks/forms/autocomplete-a11y-evaluate.js index 0e9683f09..f39b9212b 100644 --- a/lib/checks/forms/autocomplete-a11y-evaluate.js +++ b/lib/checks/forms/autocomplete-a11y-evaluate.js @@ -1,55 +1,77 @@ -import { isValidAutocomplete } from "../../commons/text"; +import { isValidAutocomplete } from '../../commons/text'; +import { ErrorHandler } from '../../../../a11y-engine-core/lib/core/errors/error-handler'; function checkIsElementValidAutocomplete(node, options, virtualNode) { - const autocomplete = virtualNode.attr('autocomplete')?.toLowerCase().trim(); - // if element has autocomplete attribute as off then it is not a violation - if(autocomplete === "off" || autocomplete==="chrome-off") { - return true; - } - - // if it is on then we check whether name / id have valid autocomplete value or not - // same for the case if autocomplete is not present or has a non-standard value - if(!autocomplete || autocomplete === "on" || !isValidAutocomplete(autocomplete, options)) { - const name = virtualNode.attr('name'); - const id = virtualNode.attr('id'); - if((name && isValidAutocomplete(name, options)) || (id && isValidAutocomplete(id, options))) - return true; - return false; - } - - // if element autocomplete attribute is neither off nor on then we check if its a standard value - if(isValidAutocomplete(autocomplete, options)) { + const autocomplete = virtualNode + .attr('autocomplete') + ?.toLowerCase() + .trim(); + // if element has autocomplete attribute as off then it is not a violation + if (autocomplete === 'off' || autocomplete === 'chrome-off') { + return true; + } + + // if it is on then we check whether name / id have valid autocomplete value or not + // same for the case if autocomplete is not present or has a non-standard value + if ( + !autocomplete || + autocomplete === 'on' || + !isValidAutocomplete(autocomplete, options) + ) { + const name = virtualNode.attr('name'); + const id = virtualNode.attr('id'); + if ( + (name && isValidAutocomplete(name, options)) || + (id && isValidAutocomplete(id, options)) + ) { return true; } - return false; } - - function autocompleteA11yEvaluate(node, options, virtualNode) { - try { - const autocomplete = virtualNode.attr('autocomplete'); - - // check if the autocomplete applicable element is inside form or exist freely - const closestForm = virtualNode.actualNode.closest("form"); - - //if it exists inside the form and autocomplete for form is off - if(closestForm && (closestForm.getAttribute('autocomplete')?.toLowerCase().trim() === "off" - || closestForm.getAttribute('autocomplete')?.toLowerCase().trim() === "chrome-off")) { - // if autocomplete attribute is not present for element then its a pass in this scenario - // otherwise check all posibilities with the method - return autocomplete ? checkIsElementValidAutocomplete(node, options, virtualNode) : true; - } else { - // The else case is if form is present and it has autocomplete as on or not set and - // the other case this handles is that element exists independently - - // this method would check for all posibilities - return checkIsElementValidAutocomplete(node, options, virtualNode); - } - } - catch(err) { - ErrorHandler.addCheckError("autocomplete-attribute-valid-check", err); - return undefined; + + // if element autocomplete attribute is neither off nor on then we check if its a standard value + if (isValidAutocomplete(autocomplete, options)) { + return true; + } + + return false; +} + +function autocompleteA11yEvaluate(node, options, virtualNode) { + try { + const autocomplete = virtualNode.attr('autocomplete'); + + // check if the autocomplete applicable element is inside form or exist freely + const closestForm = virtualNode.actualNode.closest('form'); + + //if it exists inside the form and autocomplete for form is off + if ( + closestForm && + (closestForm + .getAttribute('autocomplete') + ?.toLowerCase() + .trim() === 'off' || + closestForm + .getAttribute('autocomplete') + ?.toLowerCase() + .trim() === 'chrome-off') + ) { + // if autocomplete attribute is not present for element then its a pass in this scenario + // otherwise check all posibilities with the method + return autocomplete + ? checkIsElementValidAutocomplete(node, options, virtualNode) + : true; + } else { + // The else case is if form is present and it has autocomplete as on or not set and + // the other case this handles is that element exists independently + + // this method would check for all posibilities + return checkIsElementValidAutocomplete(node, options, virtualNode); } + } catch (err) { + ErrorHandler.addCheckError('autocomplete-attribute-valid-check', err); + return undefined; } - - export default autocompleteA11yEvaluate; \ No newline at end of file +} + +export default autocompleteA11yEvaluate; diff --git a/test/checks/forms/autocomplete-valid.js b/test/checks/forms/autocomplete-valid.js index 804a523f4..795393e80 100644 --- a/test/checks/forms/autocomplete-valid.js +++ b/test/checks/forms/autocomplete-valid.js @@ -11,22 +11,200 @@ describe('autocomplete-valid', function() { checkContext.reset(); }); - it('returns true if autocomplete is valid', function() { - var params = checkSetup(''); + // original axe-core's check test + + // it('returns true if autocomplete is valid', function() { + // var params = checkSetup(''); + // assert.isTrue(evaluate.apply(checkContext, params)); + // }); + + // it('returns false if autocomplete is not valid', function() { + // var params = checkSetup(''); + // assert.isFalse(evaluate.apply(checkContext, params)); + // }); + + // it('uses options to change what is valid autocomplete', function() { + // var options = { stateTerms: ['foo'] }; + // var params = checkSetup( + // '', + // options + // ); + // assert.isTrue(evaluate.apply(checkContext, params)); + // }); + + it("evaluate() passes a document if form element has autocomplete set off and child elements don't have autocomplete", function() { + console.log('Our functions are running fine'); + var params = checkSetup( + '
' + ); + assert.isTrue(evaluate.apply(checkContext, params)); + }); + + it('evaluate() passes a document if form element has autocomplete set off and child elements have autocomplete as off', function() { + var params = checkSetup( + ' ' + ); + assert.isTrue(evaluate.apply(checkContext, params)); + }); + + it('evaluate() passes a document if form element has autocomplete set off and child elements have standard autcomplete value', function() { + var params = checkSetup( + ' ' + ); + assert.isTrue(evaluate.apply(checkContext, params)); + }); + + it('evaluate() passes a document if form element has autocomplete set off, child elements have on autocomplete value and name or id has standard autocomplete value', function() { + var params = checkSetup( + ' ' + ); + assert.isTrue(evaluate.apply(checkContext, params)); + }); + + it('evaluate() fails a document if form element has autocomplete set off and child elements have on autocomplete value and name or id has non-standard autocomplete value', function() { + var params = checkSetup( + ' ' + ); + assert.isFalse(evaluate.apply(checkContext, params)); + }); + + it('evaluate() passes a document if form element has autocomplete set off, child elements have non-standard autocomplete value and name or id has standard autocomplete value', function() { + var params = checkSetup( + ' ' + ); + assert.isTrue(evaluate.apply(checkContext, params)); + }); + + it('evaluate() fails a document if form element has autocomplete set off, child elements have non-standard autocomplete value and name or id has non-standard autocomplete value', function() { + var params = checkSetup( + ' ' + ); + assert.isFalse(evaluate.apply(checkContext, params)); + }); + + it('evaluate() passes a document if form element has autocomplete set on and child elements have autocomplete set to off', function() { + var params = checkSetup( + ' ' + ); + assert.isTrue(evaluate.apply(checkContext, params)); + }); + + it("evaluate() passes a document if form element doesn't have autocomplete set and child elements have autocomplete set to off", function() { + var params = checkSetup( + ' ' + ); + assert.isTrue(evaluate.apply(checkContext, params)); + }); + + it('evaluate() passes a document if form element has autocomplete set on and child elements have autocomplete set to standard irrespective of name and id', function() { + var params = checkSetup( + ' ' + ); + assert.isTrue(evaluate.apply(checkContext, params)); + }); + + it("evaluate() passes a document if form element doesn't have autocomplete set and child elements have autocomplete set to standard irrespective of name and id", function() { + var params = checkSetup( + ' ' + ); + assert.isTrue(evaluate.apply(checkContext, params)); + }); + + it('evaluate() passes a document if form element has autocomplete set on and child elements have autocomplete set on and name/id have a standard autocomplete value', function() { + var params = checkSetup( + ' ' + ); + assert.isTrue(evaluate.apply(checkContext, params)); + }); + + it("evaluate() passes a document if form element doesn't have autocomplete set and child elements have autocomplete set on and name/id have a standard autocomplete value", function() { + var params = checkSetup( + ' ' + ); assert.isTrue(evaluate.apply(checkContext, params)); }); - it('returns false if autocomplete is not valid', function() { - var params = checkSetup(''); + it('evaluate() fails a document if form element has autocomplete set on and child elements have autocomplete set on and name/id have a non-standard autocomplete value', function() { + var params = checkSetup( + ' ' + ); assert.isFalse(evaluate.apply(checkContext, params)); }); - it('uses options to change what is valid autocomplete', function() { - var options = { stateTerms: ['foo'] }; + it("evaluate() fails a document if form element doesn't have autcomplete set and child elements have autocomplete set on and name/id have a non-standard autocomplete value", function() { + var params = checkSetup( + ' ' + ); + assert.isFalse(evaluate.apply(checkContext, params)); + }); + + it("evaluate() passes a document if form element has autocomplete set on and child elements don't have autocomplete set and name/id have a standard autocomplete value", function() { + var params = checkSetup( + ' ' + ); + assert.isTrue(evaluate.apply(checkContext, params)); + }); + + it("evaluate() passes a document if form element doesn't have autocomplete set and child elements don't have autocomplete set and name/id have a standard autocomplete value", function() { var params = checkSetup( - '', - options + ' ' ); assert.isTrue(evaluate.apply(checkContext, params)); }); + + it("evaluate() fails a document if form element has autocomplete set on and child elements don't have autocomplete set and name/id have a non-standard autocomplete value", function() { + var params = checkSetup( + ' ' + ); + assert.isFalse(evaluate.apply(checkContext, params)); + }); + + it("evaluate() fails a document if form element doesn't have autocomplete set and child elements don't have autocomplete set and name/id have a non-standard autocomplete value", function() { + var params = checkSetup( + ' ' + ); + assert.isFalse(evaluate.apply(checkContext, params)); + }); + + it('evaluate() passes a document if element is independent and have autocomplete set to off', function() { + var params = checkSetup( + ' ' + ); + assert.isTrue(evaluate.apply(checkContext, params)); + }); + + it('evaluate() passes a document if element is independent and have autocomplete set to standard irrespective of name and id', function() { + var params = checkSetup( + ' ' + ); + assert.isTrue(evaluate.apply(checkContext, params)); + }); + + it('evaluate() passes a document if element is independent and have autocomplete set on and name/id have a standard autocomplete value', function() { + var params = checkSetup( + ' ' + ); + assert.isTrue(evaluate.apply(checkContext, params)); + }); + + it('evaluate() fails a document if element is independent and have autocomplete set on and name/id have a non-standard autocomplete value', function() { + var params = checkSetup( + ' ' + ); + assert.isFalse(evaluate.apply(checkContext, params)); + }); + + it("evaluate()passes a document if element is independent and don't have autocomplete set and name/id have a standard autocomplete value", function() { + var params = checkSetup( + ' ' + ); + assert.isTrue(evaluate.apply(checkContext, params)); + }); + + it("evaluate() fails a document if element is independent and don't have autocomplete set and name/id have a non-standard autocomplete value", function() { + var params = checkSetup( + ' ' + ); + assert.isFalse(evaluate.apply(checkContext, params)); + }); }); diff --git a/test/integration/rules/autocomplete-valid/autocomplete-valid.html b/test/integration/rules/autocomplete-valid/autocomplete-valid.html index e38a7798a..eec22911e 100644 --- a/test/integration/rules/autocomplete-valid/autocomplete-valid.html +++ b/test/integration/rules/autocomplete-valid/autocomplete-valid.html @@ -7,11 +7,9 @@ - + - - - + @@ -29,10 +27,10 @@ - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + diff --git a/test/integration/rules/autocomplete-valid/autocomplete-valid.json b/test/integration/rules/autocomplete-valid/autocomplete-valid.json index b4eceb260..7f2fbc52c 100644 --- a/test/integration/rules/autocomplete-valid/autocomplete-valid.json +++ b/test/integration/rules/autocomplete-valid/autocomplete-valid.json @@ -1,7 +1,18 @@ { "description": "autocomplete-valid tests", "rule": "autocomplete-valid", - "violations": [["#fail1"], ["#fail2"], ["#fail3"], ["#fail4"]], + "violations": [ + ["#fail1"], + ["#fail2"], + ["#fail3"], + ["#fail4"], + ["#fail5"], + ["#fail6"], + ["#fail7"], + ["#fail8"], + ["#fail9"], + ["#fail10"] + ], "passes": [ ["#pass1"], ["#pass2"], @@ -86,12 +97,6 @@ ["#pass81"], ["#pass82"], ["#pass83"], - ["#pass84"], - ["#pass85"], - ["#pass86"], - ["#pass87"], - ["#pass88"], - ["#pass89"], - ["#pass90"] + ["#pass84"] ] } diff --git a/test/rule-matches/autocomplete-matches.js b/test/rule-matches/autocomplete-matches.js index fd5579d62..298598d0f 100644 --- a/test/rule-matches/autocomplete-matches.js +++ b/test/rule-matches/autocomplete-matches.js @@ -46,9 +46,9 @@ describe('autocomplete-matches', function() { }); }); - it('returns false for elements with an empty autocomplete', function() { + it('returns true for elements with an empty autocomplete', function() { var vNode = queryFixture(''); - assert.isFalse(rule.matches(null, vNode)); + assert.isTrue(rule.matches(null, vNode)); }); it('returns false for intput[type=hidden]', function() {