Skip to content

Commit

Permalink
feat(new-rule): Add meta-refresh-no-exceptions (wcag2aaa, disabled by…
Browse files Browse the repository at this point in the history
… default) (#3530)

* feat(new-rule): Add meta-refresh-no-exceptions (wcag2aaa, disabled by default)

* Add virtual rule tests
  • Loading branch information
WilcoFiers authored Jul 6, 2022
1 parent 5beb6c3 commit 27031a8
Show file tree
Hide file tree
Showing 15 changed files with 341 additions and 8 deletions.
11 changes: 6 additions & 5 deletions doc/rule-descriptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
| [list](https://dequeuniversity.com/rules/axe/4.4/list?application=RuleDescription) | Ensures that lists are structured correctly | Serious | cat.structure, wcag2a, wcag131 | failure | |
| [listitem](https://dequeuniversity.com/rules/axe/4.4/listitem?application=RuleDescription) | Ensures <li> elements are used semantically | Serious | cat.structure, wcag2a, wcag131 | failure | |
| [marquee](https://dequeuniversity.com/rules/axe/4.4/marquee?application=RuleDescription) | Ensures <marquee> elements are not used | Serious | cat.parsing, wcag2a, wcag222 | failure | |
| [meta-refresh](https://dequeuniversity.com/rules/axe/4.4/meta-refresh?application=RuleDescription) | Ensures <meta http-equiv="refresh"> is not used | Critical | cat.time-and-media, wcag2a, wcag221, wcag224, wcag325 | failure | [bc659a](https://act-rules.github.io/rules/bc659a) |
| [meta-refresh](https://dequeuniversity.com/rules/axe/4.4/meta-refresh?application=RuleDescription) | Ensures <meta http-equiv="refresh"> is not used for delayed refresh | Critical | cat.time-and-media, wcag2a, wcag221, wcag224, wcag325 | failure | [bc659a](https://act-rules.github.io/rules/bc659a) |
| [nested-interactive](https://dequeuniversity.com/rules/axe/4.4/nested-interactive?application=RuleDescription) | Ensures interactive controls are not nested as they are not always announced by screen readers or can cause focus problems for assistive technologies | Serious | cat.keyboard, wcag2a, wcag412 | failure, needs review | [307n5z](https://act-rules.github.io/rules/307n5z) |
| [object-alt](https://dequeuniversity.com/rules/axe/4.4/object-alt?application=RuleDescription) | Ensures <object> elements have alternate text | Serious | cat.text-alternatives, wcag2a, wcag111, section508, section508.22.a | failure, needs review | [8fc3b6](https://act-rules.github.io/rules/8fc3b6) |
| [role-img-alt](https://dequeuniversity.com/rules/axe/4.4/role-img-alt?application=RuleDescription) | Ensures [role='img'] elements have alternate text | Serious | cat.text-alternatives, wcag2a, wcag111, section508, section508.22.a, ACT | failure, needs review | [23a2a8](https://act-rules.github.io/rules/23a2a8) |
Expand Down Expand Up @@ -116,10 +116,11 @@ Rules that do not necessarily conform to WCAG success criterion but are industry

Rules that check for conformance to WCAG AAA success criteria that can be fully automated.

| Rule ID | Description | Impact | Tags | Issue Type | ACT Rules |
| :--------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------- | :------ | :-------------------------------- | :------------------------- | :------------------------------------------------- |
| [color-contrast-enhanced](https://dequeuniversity.com/rules/axe/4.4/color-contrast-enhanced?application=RuleDescription) | Ensures the contrast between foreground and background colors meets WCAG 2 AAA contrast ratio thresholds | Serious | cat.color, wcag2aaa, wcag146, ACT | failure, needs review | [09o5cg](https://act-rules.github.io/rules/09o5cg) |
| [identical-links-same-purpose](https://dequeuniversity.com/rules/axe/4.4/identical-links-same-purpose?application=RuleDescription) | Ensure that links with the same accessible name serve a similar purpose | Minor | cat.semantics, wcag2aaa, wcag249 | needs review | [b20e66](https://act-rules.github.io/rules/b20e66) |
| Rule ID | Description | Impact | Tags | Issue Type | ACT Rules |
| :--------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------- | :------ | :--------------------------------------------- | :------------------------- | :------------------------------------------------- |
| [color-contrast-enhanced](https://dequeuniversity.com/rules/axe/4.4/color-contrast-enhanced?application=RuleDescription) | Ensures the contrast between foreground and background colors meets WCAG 2 AAA contrast ratio thresholds | Serious | cat.color, wcag2aaa, wcag146, ACT | failure, needs review | [09o5cg](https://act-rules.github.io/rules/09o5cg) |
| [identical-links-same-purpose](https://dequeuniversity.com/rules/axe/4.4/identical-links-same-purpose?application=RuleDescription) | Ensure that links with the same accessible name serve a similar purpose | Minor | cat.semantics, wcag2aaa, wcag249 | needs review | [b20e66](https://act-rules.github.io/rules/b20e66) |
| [meta-refresh-no-exceptions](https://dequeuniversity.com/rules/axe/4.4/meta-refresh-no-exceptions?application=RuleDescription) | Ensures <meta http-equiv="refresh"> is not used for delayed refresh | Minor | cat.time-and-media, wcag2aaa, wcag224, wcag325 | failure | [bisz58](https://act-rules.github.io/rules/bisz58) |

## Experimental Rules

Expand Down
15 changes: 15 additions & 0 deletions lib/checks/navigation/meta-refresh-no-exceptions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"id": "meta-refresh-no-exceptions",
"evaluate": "meta-refresh-evaluate",
"options": {
"minDelay": 0,
"maxDelay": false
},
"metadata": {
"impact": "minor",
"messages": {
"pass": "<meta> tag does not immediately refresh the page",
"fail": "<meta> tag forces timed refresh of page"
}
}
}
2 changes: 1 addition & 1 deletion lib/checks/navigation/meta-refresh.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"impact": "critical",
"messages": {
"pass": "<meta> tag does not immediately refresh the page",
"fail": "<meta> tag forces timed refresh of page"
"fail": "<meta> tag forces timed refresh of page (less than 20 hours)"
}
}
}
20 changes: 20 additions & 0 deletions lib/rules/meta-refresh-no-exceptions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"id": "meta-refresh-no-exceptions",
"selector": "meta[http-equiv=\"refresh\"][content]",
"excludeHidden": false,
"enabled": false,
"tags": [
"cat.time-and-media",
"wcag2aaa",
"wcag224",
"wcag325"
],
"actIds": ["bisz58"],
"metadata": {
"description": "Ensures <meta http-equiv=\"refresh\"> is not used for delayed refresh",
"help": "Delayed refresh must not be used"
},
"all": [],
"any": ["meta-refresh-no-exceptions"],
"none": []
}
4 changes: 2 additions & 2 deletions lib/rules/meta-refresh.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
],
"actIds": ["bc659a"],
"metadata": {
"description": "Ensures <meta http-equiv=\"refresh\"> is not used",
"help": "Timed refresh must not exist"
"description": "Ensures <meta http-equiv=\"refresh\"> is not used for delayed refresh",
"help": "Delayed refresh under 20 hours must not be used"
},
"all": [],
"any": ["meta-refresh"],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
describe('meta-refresh-no-exceptions fail', function() {
'use strict';

it('should be a violation', function(done) {
axe.run({ runOnly: 'meta-refresh-no-exceptions' }, function(err, results) {
try {
assert.isNull(err);
assert.lengthOf(results.violations, 1, 'violations');
assert.lengthOf(results.passes, 0, 'passes');
assert.lengthOf(results.incomplete, 0, 'passes');
assert.lengthOf(results.inapplicable, 0, 'inapplicable');
done();
} catch (e) {
done(e);
}
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf8" />
<title>Meta-refresh-no-exceptions fail 1</title>
<meta http-equiv="refresh" content="10 https://deque.com/">
<link
rel="stylesheet"
type="text/css"
href="/node_modules/mocha/mocha.css"
/>
<script src="/node_modules/mocha/mocha.js"></script>
<script src="/node_modules/chai/chai.js"></script>
<script src="/axe.js"></script>
<script>
mocha.setup({
timeout: 10000,
ui: 'bdd'
});
var assert = chai.assert;
</script>
</head>
<body>
<div id="mocha"></div>
<script src="meta-refresh-fail.js"></script>
<script src="/test/integration/adapter.js"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf8" />
<title>Meta-refresh-no-exceptions fail 2</title>
<!-- Greater than 20 hour is still not allowed at Level AAA -->
<meta http-equiv="refresh" content="90000; https://deque.com/">
<link
rel="stylesheet"
type="text/css"
href="/node_modules/mocha/mocha.css"
/>
<script src="/node_modules/mocha/mocha.js"></script>
<script src="/node_modules/chai/chai.js"></script>
<script src="/axe.js"></script>
<script>
mocha.setup({
timeout: 10000,
ui: 'bdd'
});
var assert = chai.assert;
</script>
</head>
<body>
<div id="mocha"></div>
<script src="meta-refresh-fail.js"></script>
<script src="/test/integration/adapter.js"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
describe('meta-refresh-no-exceptions inapplicable', function() {
'use strict';

it('should be inapplicable', function(done) {
axe.run({ runOnly: 'meta-refresh-no-exceptions' }, function(err, results) {
try {
assert.isNull(err);
assert.lengthOf(results.violations, 0, 'violations');
assert.lengthOf(results.passes, 0, 'passes');
assert.lengthOf(results.incomplete, 0, 'passes');
assert.lengthOf(results.inapplicable, 1, 'inapplicable');
done();
} catch (e) {
done(e);
}
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf8" />
<title>Meta-refresh-no-exceptions inapplicable 1</title>
<!-- no content attribute -->
<meta http-equiv="refresh">
<link
rel="stylesheet"
type="text/css"
href="/node_modules/mocha/mocha.css"
/>
<script src="/node_modules/mocha/mocha.js"></script>
<script src="/node_modules/chai/chai.js"></script>
<script src="/axe.js"></script>
<script>
mocha.setup({
timeout: 10000,
ui: 'bdd'
});
var assert = chai.assert;
</script>
</head>
<body>
<div id="mocha"></div>
<script src="meta-refresh-inapplicable.js"></script>
<script src="/test/integration/adapter.js"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf8" />
<title>Meta-refresh-no-exceptions inapplicable 2</title>
<!-- no http-equiv="refresh" attribute -->
<meta http-equiv="something-else" content="5">
<link
rel="stylesheet"
type="text/css"
href="/node_modules/mocha/mocha.css"
/>
<script src="/node_modules/mocha/mocha.js"></script>
<script src="/node_modules/chai/chai.js"></script>
<script src="/axe.js"></script>
<script>
mocha.setup({
timeout: 10000,
ui: 'bdd'
});
var assert = chai.assert;
</script>
</head>
<body>
<div id="mocha"></div>
<script src="meta-refresh-inapplicable.js"></script>
<script src="/test/integration/adapter.js"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
describe('meta-refresh-no-exceptions pass', function() {
'use strict';

it('should pass', function(done) {
axe.run({ runOnly: 'meta-refresh-no-exceptions' }, function(err, results) {
console.log(results)
try {
assert.isNull(err);
assert.lengthOf(results.violations, 0, 'violations');
assert.lengthOf(results.passes, 1, 'passes');
assert.lengthOf(results.incomplete, 0, 'passes');
done();
} catch (e) {
done(e);
}
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf8" />
<title>Meta-refresh-no-exceptions pass 1</title>
<!-- "-10" is not valid, this will be ignored -->
<meta http-equiv="refresh" content="-10 https://deque.com/">
<link
rel="stylesheet"
type="text/css"
href="/node_modules/mocha/mocha.css"
/>
<script src="/node_modules/mocha/mocha.js"></script>
<script src="/node_modules/chai/chai.js"></script>
<script src="/axe.js"></script>
<script>
mocha.setup({
timeout: 10000,
ui: 'bdd'
});
var assert = chai.assert;
</script>
</head>
<body>
<div id="mocha"></div>
<script src="meta-refresh-pass.js"></script>
<script src="/test/integration/adapter.js"></script>
</body>
</html>
85 changes: 85 additions & 0 deletions test/integration/virtual-rules/meta-refresh-no-exceptions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
describe('meta-refresh-no-exceptions virtual-rule', function() {
it('should be inapplicable for missing content', function() {
var results = axe.runVirtualRule('meta-refresh-no-exceptions', {
nodeName: 'meta',
attributes: {
'http-equiv': 'refresh'
}
});

assert.lengthOf(results.passes, 0);
assert.lengthOf(results.violations, 0);
assert.lengthOf(results.incomplete, 0);
assert.lengthOf(results.inapplicable, 1);
});

it('should pass for content=0', function() {
var results = axe.runVirtualRule('meta-refresh-no-exceptions', {
nodeName: 'meta',
attributes: {
'http-equiv': 'refresh',
content: '0'
}
});

assert.lengthOf(results.passes, 1);
assert.lengthOf(results.violations, 0);
assert.lengthOf(results.incomplete, 0);
});

it('should pass for content=0 and url', function() {
var results = axe.runVirtualRule('meta-refresh-no-exceptions', {
nodeName: 'meta',
attributes: {
'http-equiv': 'refresh',
content: '0;url=http://example.com/'
}
});

assert.lengthOf(results.passes, 1);
assert.lengthOf(results.violations, 0);
assert.lengthOf(results.incomplete, 0);
});

it('should fail for content other than 0', function() {
var results = axe.runVirtualRule('meta-refresh-no-exceptions', {
nodeName: 'meta',
attributes: {
'http-equiv': 'refresh',
content: '300'
}
});

assert.lengthOf(results.passes, 0);
assert.lengthOf(results.violations, 1);
assert.lengthOf(results.incomplete, 0);
});

it('should fail for content other than 0 and url', function() {
var results = axe.runVirtualRule('meta-refresh-no-exceptions', {
nodeName: 'meta',
attributes: {
'http-equiv': 'refresh',
content: '20;url=http://example.com/'
}
});

assert.lengthOf(results.passes, 0);
assert.lengthOf(results.violations, 1);
assert.lengthOf(results.incomplete, 0);
});

it('should fail for content greater than 20 hours', function() {
var results = axe.runVirtualRule('meta-refresh-no-exceptions', {
nodeName: 'meta',
attributes: {
'http-equiv': 'refresh',
content: '72001'
}
});

assert.lengthOf(results.passes, 0);
assert.lengthOf(results.violations, 1);
assert.lengthOf(results.incomplete, 0);
});
});
14 changes: 14 additions & 0 deletions test/integration/virtual-rules/meta-refresh.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,18 @@ describe('meta-refresh virtual-rule', function() {
assert.lengthOf(results.violations, 1);
assert.lengthOf(results.incomplete, 0);
});

it('should pass for content greater than 20 hours', function() {
var results = axe.runVirtualRule('meta-refresh', {
nodeName: 'meta',
attributes: {
'http-equiv': 'refresh',
content: '72001'
}
});

assert.lengthOf(results.passes, 1);
assert.lengthOf(results.violations, 0);
assert.lengthOf(results.incomplete, 0);
});
});

0 comments on commit 27031a8

Please sign in to comment.