Skip to content

Commit

Permalink
Merge pull request #47 from browserstack/autocomplete-test-cases
Browse files Browse the repository at this point in the history
Added unit test cases for autocomplete
  • Loading branch information
ansh21 authored May 20, 2024
2 parents 7999ff2 + 7674591 commit 41cd52e
Show file tree
Hide file tree
Showing 5 changed files with 369 additions and 166 deletions.
116 changes: 69 additions & 47 deletions lib/checks/forms/autocomplete-a11y-evaluate.js
Original file line number Diff line number Diff line change
@@ -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;
}

export default autocompleteA11yEvaluate;
194 changes: 186 additions & 8 deletions test/checks/forms/autocomplete-valid.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,200 @@ describe('autocomplete-valid', function() {
checkContext.reset();
});

it('returns true if autocomplete is valid', function() {
var params = checkSetup('<input autocomplete="on" id="target" />');
// original axe-core's check test

// it('returns true if autocomplete is valid', function() {
// var params = checkSetup('<input autocomplete="on" id="target" />');
// assert.isTrue(evaluate.apply(checkContext, params));
// });

// it('returns false if autocomplete is not valid', function() {
// var params = checkSetup('<input autocomplete="foo" id="target" />');
// assert.isFalse(evaluate.apply(checkContext, params));
// });

// it('uses options to change what is valid autocomplete', function() {
// var options = { stateTerms: ['foo'] };
// var params = checkSetup(
// '<input autocomplete="foo" id="target" />',
// 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(
'<html> <form autocomplete="off" onsubmit="javascript(0)"> <input type="text" id="target"/> <button>Save</button> </form> </html>'
);
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(
'<html> <form autocomplete="off" onsubmit="javascript(0)"> <input autocomplete="off" type="text" id="target"/> <button>Save</button> </form> </html>'
);
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(
'<html> <form autocomplete="off" onsubmit="javascript(0)"> <input autocomplete="username" type="text" id="target"/> <button>Save</button> </form> </html>'
);
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(
'<html> <form autocomplete="off" onsubmit="javascript(0)"> <input autocomplete="on" name="name" type="text" id="target"/> <button>Save</button> </form> </html>'
);
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(
'<html> <form autocomplete="off" onsubmit="javascript(0)"> <input autocomplete="on" name="xname" type="text" id="target"/> <button>Save</button> </form> </html>'
);
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(
'<html> <form autocomplete="off" onsubmit="javascript(0)"> <input autocomplete="xname" name="name" type="text" id="target"/> <button>Save</button> </form> </html>'
);
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(
'<html> <form autocomplete="off" onsubmit="javascript(0)"> <input autocomplete="xname" name="xname" type="text" id="target"/> <button>Save</button> </form> </html>'
);
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(
'<html> <form autocomplete="on" onsubmit="javascript(0)"> <input autocomplete="off" type="text" id="target"/> <button>Save</button> </form> </html>'
);
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(
'<html> <form onsubmit="javascript(0)"> <input autocomplete="off" type="text" id="target"/> <button>Save</button> </form> </html>'
);
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(
'<html> <form autocomplete="on" onsubmit="javascript(0)"> <input autocomplete="name" type="text" name="xname" id="target"/> <button>Save</button> </form> </html>'
);
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(
'<html> <form onsubmit="javascript(0)"> <input autocomplete="name" type="text" name="xname" id="target"/> <button>Save</button> </form> </html>'
);
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(
'<html> <form autocomplete="on" onsubmit="javascript(0)"> <input autocomplete="on" type="text" name="name" id="target"/> <button>Save</button> </form> </html>'
);
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(
'<html> <form autocomplete="on" onsubmit="javascript(0)"> <input autocomplete="on" type="text" name="name" id="target"/> <button>Save</button> </form> </html>'
);
assert.isTrue(evaluate.apply(checkContext, params));
});

it('returns false if autocomplete is not valid', function() {
var params = checkSetup('<input autocomplete="foo" id="target" />');
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(
'<html> <form autocomplete="on" onsubmit="javascript(0)"> <input autocomplete="on" type="text" name="xname" id="target"/> <button>Save</button> </form> </html>'
);
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(
'<html> <form onsubmit="javascript(0)"> <input autocomplete="on" type="text" name="xname" id="target"/> <button>Save</button> </form> </html>'
);
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(
'<html> <form autocomplete="on" onsubmit="javascript(0)"> <input type="text" name="name" id="target"/> <button>Save</button> </form> </html>'
);
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(
'<input autocomplete="foo" id="target" />',
options
'<html> <form onsubmit="javascript(0)"> <input type="text" name="name" id="target"/> <button>Save</button> </form> </html>'
);
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(
'<html> <form autocomplete="on" onsubmit="javascript(0)"> <input type="text" name="xname" id="target"/> <button>Save</button> </form> </html>'
);
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(
'<html> <form onsubmit="javascript(0)"> <input type="text" name="xname" id="target"/> <button>Save</button> </form> </html>'
);
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(
'<html> <input autocomplete="off" type="text" id="target"/> <button>Save</button> </html>'
);
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(
'<html> <input autocomplete="name" type="text" name="xname" id="target"/> <button>Save</button> </html>'
);
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(
'<html> <input autocomplete="on" type="text" name="name" id="target"/> <button>Save</button> </html>'
);
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(
'<html> <input autocomplete="on" type="text" name="xname" id="target"/> <button>Save</button> </html>'
);
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(
'<html> <input type="text" name="name" id="target"/> <button>Save</button> </html>'
);
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(
'<html> <input type="text" name="xname" id="target"/> <button>Save</button> </html>'
);
assert.isFalse(evaluate.apply(checkContext, params));
});
});
Loading

0 comments on commit 41cd52e

Please sign in to comment.