Skip to content

Commit 7e4199b

Browse files
authored
Merge branch 'main' into autocomplete-issue-fix
2 parents 7fab9d4 + 41cd52e commit 7e4199b

File tree

5 files changed

+369
-166
lines changed

5 files changed

+369
-166
lines changed
Lines changed: 69 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,77 @@
1-
import { isValidAutocomplete } from "../../commons/text";
1+
import { isValidAutocomplete } from '../../commons/text';
2+
import { ErrorHandler } from '../../../../a11y-engine-core/lib/core/errors/error-handler';
23

34
function checkIsElementValidAutocomplete(node, options, virtualNode) {
4-
const autocomplete = virtualNode.attr('autocomplete')?.toLowerCase().trim();
5-
// if element has autocomplete attribute as off then it is not a violation
6-
if(autocomplete === "off" || autocomplete==="chrome-off") {
7-
return true;
8-
}
9-
10-
// if it is on then we check whether name / id have valid autocomplete value or not
11-
// same for the case if autocomplete is not present or has a non-standard value
12-
if(!autocomplete || autocomplete === "on" || !isValidAutocomplete(autocomplete, options)) {
13-
const name = virtualNode.attr('name');
14-
const id = virtualNode.attr('id');
15-
if((name && isValidAutocomplete(name, options)) || (id && isValidAutocomplete(id, options)))
16-
return true;
17-
return false;
18-
}
19-
20-
// if element autocomplete attribute is neither off nor on then we check if its a standard value
21-
if(isValidAutocomplete(autocomplete, options)) {
5+
const autocomplete = virtualNode
6+
.attr('autocomplete')
7+
?.toLowerCase()
8+
.trim();
9+
// if element has autocomplete attribute as off then it is not a violation
10+
if (autocomplete === 'off' || autocomplete === 'chrome-off') {
11+
return true;
12+
}
13+
14+
// if it is on then we check whether name / id have valid autocomplete value or not
15+
// same for the case if autocomplete is not present or has a non-standard value
16+
if (
17+
!autocomplete ||
18+
autocomplete === 'on' ||
19+
!isValidAutocomplete(autocomplete, options)
20+
) {
21+
const name = virtualNode.attr('name');
22+
const id = virtualNode.attr('id');
23+
if (
24+
(name && isValidAutocomplete(name, options)) ||
25+
(id && isValidAutocomplete(id, options))
26+
) {
2227
return true;
2328
}
24-
2529
return false;
2630
}
27-
28-
function autocompleteA11yEvaluate(node, options, virtualNode) {
29-
try {
30-
const autocomplete = virtualNode.attr('autocomplete');
31-
32-
// check if the autocomplete applicable element is inside form or exist freely
33-
const closestForm = virtualNode.actualNode.closest("form");
34-
35-
//if it exists inside the form and autocomplete for form is off
36-
if(closestForm && (closestForm.getAttribute('autocomplete')?.toLowerCase().trim() === "off"
37-
|| closestForm.getAttribute('autocomplete')?.toLowerCase().trim() === "chrome-off")) {
38-
// if autocomplete attribute is not present for element then its a pass in this scenario
39-
// otherwise check all posibilities with the method
40-
return autocomplete ? checkIsElementValidAutocomplete(node, options, virtualNode) : true;
41-
} else {
42-
// The else case is if form is present and it has autocomplete as on or not set and
43-
// the other case this handles is that element exists independently
44-
45-
// this method would check for all posibilities
46-
return checkIsElementValidAutocomplete(node, options, virtualNode);
47-
}
48-
}
49-
catch(err) {
50-
ErrorHandler.addCheckError("autocomplete-attribute-valid-check", err);
51-
return undefined;
31+
32+
// if element autocomplete attribute is neither off nor on then we check if its a standard value
33+
if (isValidAutocomplete(autocomplete, options)) {
34+
return true;
35+
}
36+
37+
return false;
38+
}
39+
40+
function autocompleteA11yEvaluate(node, options, virtualNode) {
41+
try {
42+
const autocomplete = virtualNode.attr('autocomplete');
43+
44+
// check if the autocomplete applicable element is inside form or exist freely
45+
const closestForm = virtualNode.actualNode.closest('form');
46+
47+
//if it exists inside the form and autocomplete for form is off
48+
if (
49+
closestForm &&
50+
(closestForm
51+
.getAttribute('autocomplete')
52+
?.toLowerCase()
53+
.trim() === 'off' ||
54+
closestForm
55+
.getAttribute('autocomplete')
56+
?.toLowerCase()
57+
.trim() === 'chrome-off')
58+
) {
59+
// if autocomplete attribute is not present for element then its a pass in this scenario
60+
// otherwise check all posibilities with the method
61+
return autocomplete
62+
? checkIsElementValidAutocomplete(node, options, virtualNode)
63+
: true;
64+
} else {
65+
// The else case is if form is present and it has autocomplete as on or not set and
66+
// the other case this handles is that element exists independently
67+
68+
// this method would check for all posibilities
69+
return checkIsElementValidAutocomplete(node, options, virtualNode);
5270
}
71+
} catch (err) {
72+
ErrorHandler.addCheckError('autocomplete-attribute-valid-check', err);
73+
return undefined;
5374
}
54-
55-
export default autocompleteA11yEvaluate;
75+
}
76+
77+
export default autocompleteA11yEvaluate;

test/checks/forms/autocomplete-valid.js

Lines changed: 186 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,200 @@ describe('autocomplete-valid', function() {
1111
checkContext.reset();
1212
});
1313

14-
it('returns true if autocomplete is valid', function() {
15-
var params = checkSetup('<input autocomplete="on" id="target" />');
14+
// original axe-core's check test
15+
16+
// it('returns true if autocomplete is valid', function() {
17+
// var params = checkSetup('<input autocomplete="on" id="target" />');
18+
// assert.isTrue(evaluate.apply(checkContext, params));
19+
// });
20+
21+
// it('returns false if autocomplete is not valid', function() {
22+
// var params = checkSetup('<input autocomplete="foo" id="target" />');
23+
// assert.isFalse(evaluate.apply(checkContext, params));
24+
// });
25+
26+
// it('uses options to change what is valid autocomplete', function() {
27+
// var options = { stateTerms: ['foo'] };
28+
// var params = checkSetup(
29+
// '<input autocomplete="foo" id="target" />',
30+
// options
31+
// );
32+
// assert.isTrue(evaluate.apply(checkContext, params));
33+
// });
34+
35+
it("evaluate() passes a document if form element has autocomplete set off and child elements don't have autocomplete", function() {
36+
console.log('Our functions are running fine');
37+
var params = checkSetup(
38+
'<html> <form autocomplete="off" onsubmit="javascript(0)"> <input type="text" id="target"/> <button>Save</button> </form> </html>'
39+
);
40+
assert.isTrue(evaluate.apply(checkContext, params));
41+
});
42+
43+
it('evaluate() passes a document if form element has autocomplete set off and child elements have autocomplete as off', function() {
44+
var params = checkSetup(
45+
'<html> <form autocomplete="off" onsubmit="javascript(0)"> <input autocomplete="off" type="text" id="target"/> <button>Save</button> </form> </html>'
46+
);
47+
assert.isTrue(evaluate.apply(checkContext, params));
48+
});
49+
50+
it('evaluate() passes a document if form element has autocomplete set off and child elements have standard autcomplete value', function() {
51+
var params = checkSetup(
52+
'<html> <form autocomplete="off" onsubmit="javascript(0)"> <input autocomplete="username" type="text" id="target"/> <button>Save</button> </form> </html>'
53+
);
54+
assert.isTrue(evaluate.apply(checkContext, params));
55+
});
56+
57+
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() {
58+
var params = checkSetup(
59+
'<html> <form autocomplete="off" onsubmit="javascript(0)"> <input autocomplete="on" name="name" type="text" id="target"/> <button>Save</button> </form> </html>'
60+
);
61+
assert.isTrue(evaluate.apply(checkContext, params));
62+
});
63+
64+
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() {
65+
var params = checkSetup(
66+
'<html> <form autocomplete="off" onsubmit="javascript(0)"> <input autocomplete="on" name="xname" type="text" id="target"/> <button>Save</button> </form> </html>'
67+
);
68+
assert.isFalse(evaluate.apply(checkContext, params));
69+
});
70+
71+
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() {
72+
var params = checkSetup(
73+
'<html> <form autocomplete="off" onsubmit="javascript(0)"> <input autocomplete="xname" name="name" type="text" id="target"/> <button>Save</button> </form> </html>'
74+
);
75+
assert.isTrue(evaluate.apply(checkContext, params));
76+
});
77+
78+
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() {
79+
var params = checkSetup(
80+
'<html> <form autocomplete="off" onsubmit="javascript(0)"> <input autocomplete="xname" name="xname" type="text" id="target"/> <button>Save</button> </form> </html>'
81+
);
82+
assert.isFalse(evaluate.apply(checkContext, params));
83+
});
84+
85+
it('evaluate() passes a document if form element has autocomplete set on and child elements have autocomplete set to off', function() {
86+
var params = checkSetup(
87+
'<html> <form autocomplete="on" onsubmit="javascript(0)"> <input autocomplete="off" type="text" id="target"/> <button>Save</button> </form> </html>'
88+
);
89+
assert.isTrue(evaluate.apply(checkContext, params));
90+
});
91+
92+
it("evaluate() passes a document if form element doesn't have autocomplete set and child elements have autocomplete set to off", function() {
93+
var params = checkSetup(
94+
'<html> <form onsubmit="javascript(0)"> <input autocomplete="off" type="text" id="target"/> <button>Save</button> </form> </html>'
95+
);
96+
assert.isTrue(evaluate.apply(checkContext, params));
97+
});
98+
99+
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() {
100+
var params = checkSetup(
101+
'<html> <form autocomplete="on" onsubmit="javascript(0)"> <input autocomplete="name" type="text" name="xname" id="target"/> <button>Save</button> </form> </html>'
102+
);
103+
assert.isTrue(evaluate.apply(checkContext, params));
104+
});
105+
106+
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() {
107+
var params = checkSetup(
108+
'<html> <form onsubmit="javascript(0)"> <input autocomplete="name" type="text" name="xname" id="target"/> <button>Save</button> </form> </html>'
109+
);
110+
assert.isTrue(evaluate.apply(checkContext, params));
111+
});
112+
113+
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() {
114+
var params = checkSetup(
115+
'<html> <form autocomplete="on" onsubmit="javascript(0)"> <input autocomplete="on" type="text" name="name" id="target"/> <button>Save</button> </form> </html>'
116+
);
117+
assert.isTrue(evaluate.apply(checkContext, params));
118+
});
119+
120+
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() {
121+
var params = checkSetup(
122+
'<html> <form autocomplete="on" onsubmit="javascript(0)"> <input autocomplete="on" type="text" name="name" id="target"/> <button>Save</button> </form> </html>'
123+
);
16124
assert.isTrue(evaluate.apply(checkContext, params));
17125
});
18126

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

24-
it('uses options to change what is valid autocomplete', function() {
25-
var options = { stateTerms: ['foo'] };
134+
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() {
135+
var params = checkSetup(
136+
'<html> <form onsubmit="javascript(0)"> <input autocomplete="on" type="text" name="xname" id="target"/> <button>Save</button> </form> </html>'
137+
);
138+
assert.isFalse(evaluate.apply(checkContext, params));
139+
});
140+
141+
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() {
142+
var params = checkSetup(
143+
'<html> <form autocomplete="on" onsubmit="javascript(0)"> <input type="text" name="name" id="target"/> <button>Save</button> </form> </html>'
144+
);
145+
assert.isTrue(evaluate.apply(checkContext, params));
146+
});
147+
148+
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() {
26149
var params = checkSetup(
27-
'<input autocomplete="foo" id="target" />',
28-
options
150+
'<html> <form onsubmit="javascript(0)"> <input type="text" name="name" id="target"/> <button>Save</button> </form> </html>'
29151
);
30152
assert.isTrue(evaluate.apply(checkContext, params));
31153
});
154+
155+
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() {
156+
var params = checkSetup(
157+
'<html> <form autocomplete="on" onsubmit="javascript(0)"> <input type="text" name="xname" id="target"/> <button>Save</button> </form> </html>'
158+
);
159+
assert.isFalse(evaluate.apply(checkContext, params));
160+
});
161+
162+
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() {
163+
var params = checkSetup(
164+
'<html> <form onsubmit="javascript(0)"> <input type="text" name="xname" id="target"/> <button>Save</button> </form> </html>'
165+
);
166+
assert.isFalse(evaluate.apply(checkContext, params));
167+
});
168+
169+
it('evaluate() passes a document if element is independent and have autocomplete set to off', function() {
170+
var params = checkSetup(
171+
'<html> <input autocomplete="off" type="text" id="target"/> <button>Save</button> </html>'
172+
);
173+
assert.isTrue(evaluate.apply(checkContext, params));
174+
});
175+
176+
it('evaluate() passes a document if element is independent and have autocomplete set to standard irrespective of name and id', function() {
177+
var params = checkSetup(
178+
'<html> <input autocomplete="name" type="text" name="xname" id="target"/> <button>Save</button> </html>'
179+
);
180+
assert.isTrue(evaluate.apply(checkContext, params));
181+
});
182+
183+
it('evaluate() passes a document if element is independent and have autocomplete set on and name/id have a standard autocomplete value', function() {
184+
var params = checkSetup(
185+
'<html> <input autocomplete="on" type="text" name="name" id="target"/> <button>Save</button> </html>'
186+
);
187+
assert.isTrue(evaluate.apply(checkContext, params));
188+
});
189+
190+
it('evaluate() fails a document if element is independent and have autocomplete set on and name/id have a non-standard autocomplete value', function() {
191+
var params = checkSetup(
192+
'<html> <input autocomplete="on" type="text" name="xname" id="target"/> <button>Save</button> </html>'
193+
);
194+
assert.isFalse(evaluate.apply(checkContext, params));
195+
});
196+
197+
it("evaluate()passes a document if element is independent and don't have autocomplete set and name/id have a standard autocomplete value", function() {
198+
var params = checkSetup(
199+
'<html> <input type="text" name="name" id="target"/> <button>Save</button> </html>'
200+
);
201+
assert.isTrue(evaluate.apply(checkContext, params));
202+
});
203+
204+
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() {
205+
var params = checkSetup(
206+
'<html> <input type="text" name="xname" id="target"/> <button>Save</button> </html>'
207+
);
208+
assert.isFalse(evaluate.apply(checkContext, params));
209+
});
32210
});

0 commit comments

Comments
 (0)