Skip to content

Commit

Permalink
fix(autocomplete-valid): allow webauthn token (#3866)
Browse files Browse the repository at this point in the history
  • Loading branch information
WilcoFiers authored and straker committed Jan 23, 2023
1 parent 6761f36 commit a3d1b9d
Show file tree
Hide file tree
Showing 4 changed files with 185 additions and 43 deletions.
8 changes: 8 additions & 0 deletions lib/commons/text/is-valid-autocomplete.js
Expand Up @@ -85,6 +85,14 @@ function isValidAutocomplete(
qualifiedTerms = qualifiedTerms.concat(autocomplete.qualifiedTerms);

const autocompleteTerms = autocompleteValue.split(/\s+/g);

if (autocompleteTerms[autocompleteTerms.length - 1] === 'webauthn') {
autocompleteTerms.pop();
if (autocompleteTerms.length === 0) {
return false;
}
}

if (!looseTyped) {
if (
autocompleteTerms[0].length > 8 &&
Expand Down
203 changes: 162 additions & 41 deletions test/commons/text/is-valid-autocomplete.js
@@ -1,73 +1,185 @@
describe('text.isValidAutocomplete', function () {
'use strict';

var isValidAutocomplete = axe.commons.text.isValidAutocomplete;
var options = {
describe('text.isValidAutocomplete', () => {
const isValidAutocomplete = axe.commons.text.isValidAutocomplete;
const options = {
standaloneTerms: ['standalone-term'],
qualifiedTerms: ['qualified-term']
};

it('returns true if autocomplete is `on` or `off', function () {
['on', 'off'].forEach(function (state) {
assert.isTrue(isValidAutocomplete(state, options));
});
it('is true when empty', () => {
assert.isTrue(isValidAutocomplete('', options));
});

it('returns false if `on` or `off` is used with another term', function () {
['on', 'off'].forEach(function (state) {
assert.isFalse(isValidAutocomplete('section-foo ' + state, options));
});
it('is true when there is a stateTerm', () => {
assert.isTrue(isValidAutocomplete('on', options));
});

it('returns true the only term is a valid autocomplete term', function () {
it('is true when there is a standaloneTerms', () => {
assert.isTrue(isValidAutocomplete('standalone-term', options));
});

it('returns false the only term is an invalid autocomplete term', function () {
assert.isFalse(isValidAutocomplete('bad-term', options));
it('is true when there is a qualifiedTerms', () => {
assert.isTrue(isValidAutocomplete('qualified-term', options));
});

it('returns true if section-* is used as the first term', function () {
assert.isTrue(isValidAutocomplete('section-foo standalone-term', options));
it('is false when there is no stateTerm, standaloneTerms, or qualifiedTerms', () => {
assert.isFalse(isValidAutocomplete('bad-term', options));
});

it('returns true if `shipping` or `billing` is used as the first term', function () {
assert.isTrue(isValidAutocomplete('shipping standalone-term', options));
assert.isTrue(isValidAutocomplete('billing standalone-term', options));
});
describe('section-* grouping', () => {
it('is false when used by itself', () => {
assert.isFalse(isValidAutocomplete('section-foo', options));
});

it('is true when used before a standaloneTerm', () => {
assert.isTrue(
isValidAutocomplete('section-foo standalone-term', options)
);
});

it('is true when used before a qualifiedTerm', () => {
assert.isTrue(isValidAutocomplete('section-foo qualified-term', options));
});

it('is false when used with a stateTerm', () => {
assert.isFalse(isValidAutocomplete('section-foo off', options));
assert.isFalse(isValidAutocomplete('section-foo on', options));
});

it('returns true if section-* is used before `shipping` or `billing`', function () {
assert.isTrue(
isValidAutocomplete('section-foo shipping standalone-term', options)
);
it('is false when used out of order', () => {
assert.isFalse(
isValidAutocomplete('qualified-term section-foo', options)
);
assert.isFalse(
isValidAutocomplete('standalone-term section-foo', options)
);
});
});

it('returns false if `shipping` or `billing` is used before section-*', function () {
assert.isFalse(
isValidAutocomplete('shipping section-foo standalone-term', options)
);
describe('locations', () => {
it('is false when used by itself', () => {
assert.isFalse(isValidAutocomplete('shipping', options));
});

it('is true when in order', () => {
assert.isTrue(isValidAutocomplete('shipping standalone-term', options));
assert.isTrue(isValidAutocomplete('shipping qualified-term', options));
assert.isTrue(
isValidAutocomplete('section-foo shipping standalone-term', options)
);
assert.isTrue(
isValidAutocomplete('section-foo shipping qualified-term', options)
);
});

it('is false when used out of order', () => {
assert.isFalse(isValidAutocomplete('standalone-term shipping', options));
assert.isFalse(isValidAutocomplete('qualified-term shipping', options));
assert.isFalse(
isValidAutocomplete('shipping section-foo standalone-term', options)
);
assert.isFalse(
isValidAutocomplete('shipping section-foo qualified-term', options)
);
});

it('is false when used with a stateTerm', () => {
assert.isFalse(isValidAutocomplete('shipping off', options));
assert.isFalse(isValidAutocomplete('shipping on', options));
});
});

it('returns true if "home", "work", "mobile", "fax" or "pager" is used before a qualifier', function () {
['home', 'work', 'mobile', 'fax', 'pager'].forEach(function (qualifier) {
describe('qualifiers', () => {
it('is true when used before a qualifiedTerm', () => {
assert.isTrue(isValidAutocomplete('home qualified-term', options));
assert.isTrue(
isValidAutocomplete(qualifier + ' qualified-term', options),
'failed for ' + qualifier
isValidAutocomplete('shipping home qualified-term', options)
);
});

it('is false when used before a standaloneTerm', () => {
assert.isFalse(isValidAutocomplete('home standalone-term', options));
});

it('is false when used with a stateTerm', () => {
assert.isFalse(isValidAutocomplete('home off', options));
assert.isFalse(isValidAutocomplete('home on', options));
});

it('is false when used out of order', () => {
assert.isFalse(isValidAutocomplete('qualified-term home', options));
assert.isFalse(
isValidAutocomplete('home section-foo qualified-term', options)
);
assert.isFalse(
isValidAutocomplete('home shipping qualified-term', options)
);
assert.isFalse(
isValidAutocomplete('section-foo home shipping qualified-term', options)
);
assert.isFalse(
isValidAutocomplete('home section-foo shipping qualified-term', options)
);
});
});

it('returns false if "home", "work", "mobile", "fax" or "pager" is used before an inappropriate term', function () {
['home', 'work', 'mobile', 'fax', 'pager'].forEach(function (qualifier) {
describe('webauthn', () => {
it('returns false if used as the only term', () => {
assert.isFalse(isValidAutocomplete('webauthn', options));
});

it('returns false if used with a state term', () => {
assert.isFalse(isValidAutocomplete('on webauthn', options));
assert.isFalse(isValidAutocomplete('off webauthn', options));
});

it('returns true if used after a standalone term', () => {
assert.isTrue(isValidAutocomplete('standalone-term webauthn', options));
assert.isTrue(
isValidAutocomplete('billing standalone-term webauthn', options)
);
assert.isTrue(
isValidAutocomplete('section-foo standalone-term webauthn', options)
);
assert.isTrue(
isValidAutocomplete(
'section-foo billing standalone-term webauthn',
options
)
);
});

it('returns false if used before a standalone term', () => {
assert.isFalse(isValidAutocomplete('webauthn standalone-term', options));
assert.isFalse(
isValidAutocomplete('webauthn section-foo standalone-term', options)
);
assert.isFalse(
isValidAutocomplete(qualifier + ' standalone-term', options),
'failed for ' + qualifier
isValidAutocomplete('section-foo webauthn standalone-term', options)
);
});

it('returns true if used after a qualified term', () => {
assert.isTrue(isValidAutocomplete('qualified-term webauthn', options));
assert.isTrue(
isValidAutocomplete('section-foo qualified-term webauthn', options)
);
assert.isTrue(
isValidAutocomplete('home qualified-term webauthn', options)
);
assert.isTrue(
isValidAutocomplete('section-foo home qualified-term webauthn', options)
);
});

it('returns false when used with only optional tokens', () => {
assert.isFalse(isValidAutocomplete('home webauthn', options));
assert.isFalse(isValidAutocomplete('section-foo webauthn', options));
assert.isFalse(isValidAutocomplete('section-foo home webauthn', options));
});
});

describe('options.strictMode:false', function () {
it('returns true if the last term is a valid autocomplete term', function () {
describe('options.strictMode:false', () => {
it('returns true if the last term is a valid autocomplete term', () => {
assert.isTrue(
isValidAutocomplete('do not care! valid-term', {
looseTyped: true,
Expand All @@ -76,7 +188,16 @@ describe('text.isValidAutocomplete', function () {
);
});

it('returns false if the last term is an invalid autocomplete term', function () {
it('returns true if the last term is webauthn, and the term before is valid', () => {
assert.isTrue(
isValidAutocomplete('do not care! valid-term webauthn', {
looseTyped: true,
standaloneTerms: ['valid-term']
})
);
});

it('returns false if the last term is an invalid autocomplete term', () => {
assert.isFalse(
isValidAutocomplete('shipping invalid', {
looseTyped: true,
Expand Down
Expand Up @@ -25,6 +25,9 @@
<!-- comma seperated rather than space separated list -->
<input autocomplete="work,email" id="fail4" />

<!-- webauthn goes at the end -->
<input autocomplete="webauthn email" id="fail5" />

<!-- Incorrect element -->
<button autocomplete="username" id="inapplicable1"></button>

Expand Down Expand Up @@ -161,3 +164,9 @@
<input autocomplete="enabled" id="pass88" />
<input autocomplete="undefined" id="pass89" />
<input autocomplete="null" id="pass90" />

<!-- Webauthn tokens -->
<input autocomplete="email webauthn" id="pass91" />
<input autocomplete="section-foo email webauthn" id="pass92" />
<input autocomplete="section-foo work email webauthn" id="pass93" />
<input autocomplete="section-foo billing work email webauthn" id="pass94" />
@@ -1,7 +1,7 @@
{
"description": "autocomplete-valid tests",
"rule": "autocomplete-valid",
"violations": [["#fail1"], ["#fail2"], ["#fail3"], ["#fail4"]],
"violations": [["#fail1"], ["#fail2"], ["#fail3"], ["#fail4"], ["#fail5"]],
"passes": [
["#pass1"],
["#pass2"],
Expand Down Expand Up @@ -92,6 +92,10 @@
["#pass87"],
["#pass88"],
["#pass89"],
["#pass90"]
["#pass90"],
["#pass91"],
["#pass92"],
["#pass93"],
["#pass94"]
]
}

0 comments on commit a3d1b9d

Please sign in to comment.