Skip to content

Commit

Permalink
feat(rule): add color-contrast check for unicode characters.
Browse files Browse the repository at this point in the history
Adding two new config flags to color-contrast so it can check unicode character based icons.

ignoreUnicode, defaults to true and retains the behavior of ignoring all unicode characters when doing color contrast. This can be turned off to start checking unicode characters for color contrast.

ignoreLength, defaults to false and retains the behavior that single character nodes do not contain enough information to say whether or not they have color contrast issues. This can be turned on to ignore this length check and always check if a node has color contrast issues.

Fixes issues described in dequelabs#1906.
  • Loading branch information
Kyle McNutt authored and Kyle Bastien committed Jan 7, 2020
1 parent a9506a0 commit 13f7457
Show file tree
Hide file tree
Showing 95 changed files with 2,485 additions and 554 deletions.
27 changes: 14 additions & 13 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@ restore_dependency_cache: &restore_dependency_cache
- v{{ .Environment.CACHE_VERSION }}-npm-cache-{{ checksum "package.json" }}
- v{{ .Environment.CACHE_VERSION }}-npm-cache-

restore_phantomjs_cache: &restore_phantomjs_cache
restore_cache:
keys:
- v{{ .Environment.CACHE_VERSION }}-phantomjs-2.1.1

set_npm_auth: &set_npm_auth
run: npm config set "//registry.npmjs.org/:_authToken" $NPM_AUTH

Expand Down Expand Up @@ -47,14 +42,6 @@ jobs:
steps:
- checkout
- <<: *restore_dependency_cache
- <<: *restore_phantomjs_cache
- run:
name: PhantomJs - Install or Restore from Cache
command: 'sh .circleci/install-phantomjs.sh'
- save_cache:
key: v{{ .Environment.CACHE_VERSION }}-phantomjs-2.1.1
paths:
- phantomjs
- run: npm run test

# Run examples under `doc/examples`
Expand All @@ -74,6 +61,14 @@ jobs:
- run: npm run build
- run: npm run test:locales

# Test api docs can be built
build_api_docs:
<<: *defaults
steps:
- checkout
- <<: *restore_dependency_cache
- run: npm run api-docs

# Test newest axe-core version rule help docs are active (only on
# master prs)
test_rule_help_version:
Expand Down Expand Up @@ -138,6 +133,9 @@ workflows:
- test_locales:
requires:
- test
- build_api_docs:
requires:
- test
- test_rule_help_version:
requires:
- test
Expand All @@ -148,6 +146,7 @@ workflows:
- test
- test_examples
- test_locales
- build_api_docs
- test_rule_help_version
filters:
branches:
Expand All @@ -160,6 +159,7 @@ workflows:
- test
- test_examples
- test_locales
- build_api_docs
filters:
branches:
only: develop
Expand All @@ -170,6 +170,7 @@ workflows:
- test
- test_examples
- test_locales
- build_api_docs
- test_rule_help_version
- hold
filters:
Expand Down
12 changes: 0 additions & 12 deletions .circleci/install-phantomjs.sh

This file was deleted.

24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,30 @@

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

### [3.4.1](https://github.com/dequelabs/axe-core/compare/v3.4.0...v3.4.1) (2019-12-11)

### Bug Fixes

- ignores axe.ping responses that do not contain axe=true ([7d8aa42](https://github.com/dequelabs/axe-core/commit/7d8aa42))
- input[role=button][value='correct'] should pass ([#1897](https://github.com/dequelabs/axe-core/issues/1897)) ([3aba02c](https://github.com/dequelabs/axe-core/commit/3aba02c))
- remove heading from list of widget roles ([#1882](https://github.com/dequelabs/axe-core/issues/1882)) ([beb458f](https://github.com/dequelabs/axe-core/commit/beb458f))
- **listitem:** clarify that li elements must be contained in a list or role=list ([#1894](https://github.com/dequelabs/axe-core/issues/1894)) ([8fa0964](https://github.com/dequelabs/axe-core/commit/8fa0964))
- removes flaky test in axe Pro api check ([f2b3b54](https://github.com/dequelabs/axe-core/commit/f2b3b54))
- **aria-allowed-role:** allow role combobox on input tel, search, url, and email ([#1850](https://github.com/dequelabs/axe-core/issues/1850)) ([75d3c8b](https://github.com/dequelabs/axe-core/commit/75d3c8b))
- **axe.d.ts:** RunOnly.values should not accept a RunOnlyOption ([#1888](https://github.com/dequelabs/axe-core/issues/1888)) ([94b1466](https://github.com/dequelabs/axe-core/commit/94b1466))
- **build:** add lang query parameter to helpUrl when builing with a locale ([#1909](https://github.com/dequelabs/axe-core/issues/1909)) ([a2f0247](https://github.com/dequelabs/axe-core/commit/a2f0247))
- **color-contrast:** take into account parent opacity for foreground color ([#1902](https://github.com/dequelabs/axe-core/issues/1902)) ([639c41b](https://github.com/dequelabs/axe-core/commit/639c41b))
- **is-focusable:** use tabindex attribute instead of property ([#1912](https://github.com/dequelabs/axe-core/issues/1912)) ([aa5314d](https://github.com/dequelabs/axe-core/commit/aa5314d))
- **is-icon-ligature:** ignore whitespace characters ([#1908](https://github.com/dequelabs/axe-core/issues/1908)) ([77fc838](https://github.com/dequelabs/axe-core/commit/77fc838))
- **is-ligature-icon:** rename canvas to canvasContext ([#1880](https://github.com/dequelabs/axe-core/issues/1880)) ([604ba4f](https://github.com/dequelabs/axe-core/commit/604ba4f))
- **link-name:** test role=link when there is no href ([#1921](https://github.com/dequelabs/axe-core/issues/1921)) ([e839c57](https://github.com/dequelabs/axe-core/commit/e839c57))
- **locales:** fix incompeteMessageFallback to be a string rather than an object ([#1853](https://github.com/dequelabs/axe-core/issues/1853)) ([02a1d8a](https://github.com/dequelabs/axe-core/commit/02a1d8a))
- **run:** throw error if axe.run is called after a run has started but not completed ([#1914](https://github.com/dequelabs/axe-core/issues/1914)) ([290d125](https://github.com/dequelabs/axe-core/commit/290d125))
- **server-side-image-map:** return as needs review rather than failure ([#1898](https://github.com/dequelabs/axe-core/issues/1898)) ([ce73af9](https://github.com/dequelabs/axe-core/commit/ce73af9))
- **tabindex:** don't error when tabindex property is overridden ([#1910](https://github.com/dequelabs/axe-core/issues/1910)) ([e6875ee](https://github.com/dequelabs/axe-core/commit/e6875ee))
- **td-has-headers:** greatly improve performance of td-has-headers rule ([#1887](https://github.com/dequelabs/axe-core/issues/1887)) ([a588cad](https://github.com/dequelabs/axe-core/commit/a588cad))
- **typings:** add proper return value to getRule ([#1900](https://github.com/dequelabs/axe-core/issues/1900)) ([0d7c3d2](https://github.com/dequelabs/axe-core/commit/0d7c3d2))

## [3.4.0](https://github.com/dequelabs/axe-core/compare/v3.3.2...v3.4.0) (2019-10-18)

### Bug Fixes
Expand Down
60 changes: 19 additions & 41 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-mocha');
grunt.loadNpmTasks('grunt-parallel');
grunt.loadNpmTasks('grunt-run');
grunt.loadTasks('build/tasks');
Expand Down Expand Up @@ -337,9 +336,6 @@ module.exports = function(grunt) {
}
}
},
mocha: testConfig(grunt, {
reporter: grunt.option('reporter') || 'Spec'
}),
connect: {
test: {
options: {
Expand All @@ -353,14 +349,21 @@ module.exports = function(grunt) {
npm_run_imports: {
cmd: 'node',
args: ['./build/imports-generator']
},
npm_run_testHeadless: {
cmd: 'npm',
args: ['run', 'test:headless']
}
}
});

grunt.registerTask('default', ['build']);

grunt.registerTask('translate', [
'pre-build',
'validate',
'concat:commons',
'add-locale'
]);
grunt.registerTask('pre-build', ['clean', 'run:npm_run_imports']);

grunt.registerTask('build', [
'pre-build',
'validate',
Expand All @@ -371,45 +374,20 @@ module.exports = function(grunt) {
'uglify',
'aria-supported'
]);

grunt.registerTask('test', [
grunt.registerTask('prepare', [
'build',
'file-exists',
'testconfig',
'fixture',
'connect',
'mocha',
'parallel'
'connect'
]);

grunt.registerTask('ci-build', [
'build',
'testconfig',
'fixture',
'connect',
grunt.registerTask('default', ['build']);
grunt.registerTask('dev', ['prepare', 'watch']);
grunt.registerTask('test-fast', ['prepare', 'run:npm_run_testHeadless']);
grunt.registerTask('test', [
'prepare',
'run:npm_run_testHeadless',
'parallel'
]);

grunt.registerTask('test-fast', [
'build',
'testconfig',
'fixture',
'connect',
'mocha'
]);

grunt.registerTask('translate', [
'pre-build',
'validate',
'concat:commons',
'add-locale'
]);

grunt.registerTask('dev', [
'build',
'testconfig',
'fixture',
'connect',
'watch'
]);
grunt.registerTask('ci-build', ['prepare', 'parallel']);
};
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ Axe can be built using your local language. To do so, a localization file must b

This will create a new build for axe, called `axe.<lang>.js` and `axe.<lang>.min.js`. If you want to build localized versions, simply pass in `--all-lang` instead.

To create a new translation for axe, start by running `grunt translate --lang=<langcode>`. This will create a json file fin the `./locales` directory, with the default English text in it for you to translate. We welcome any localization for axe-core. For details on how to contribute, see the Contributing section below.
To create a new translation for axe, start by running `grunt translate --lang=<langcode>`. This will create a json file fin the `./locales` directory, with the default English text in it for you to translate. We welcome any localization for axe-core. For details on how to contribute, see the Contributing section below. For details on the message syntax, see [Check Message Template](/docs/check-message-template.md).

To update existing translation file, re-run `grunt translate --lang=<langcode>`. This will add new messages used in English and remove messages which were not used in English.

Expand All @@ -116,7 +116,7 @@ axe.configure({
'aria-errormessage': {
// Note: doT (https://github.com/olado/dot) templates are supported here.
fail:
'Der Wert der aria-errormessage {{~it.data:value}} `{{=value}}{{~}}` muss eine Technik verwenden, um die Message anzukündigen (z. B., aria-live, aria-describedby, role=alert, etc.).'
'Der Wert der aria-errormessage ${data.values}` muss eine Technik verwenden, um die Message anzukündigen (z. B., aria-live, aria-describedby, role=alert, etc.).'
}
// ...
}
Expand Down
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "axe-core",
"version": "3.4.0",
"version": "3.4.1",
"contributors": [
{
"name": "David Sturley",
Expand Down
15 changes: 11 additions & 4 deletions build/configure.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ var clone = require('clone');
var dot = require('@deque/dot');
var templates = require('./templates');
var buildManual = require('./build-manual');
var entities = new (require('html-entities')).AllHtmlEntities();
var entities = new (require('html-entities').AllHtmlEntities)();
var dotRegex = /\{\{.+?\}\}/g;

var descriptionHeaders =
'| Rule ID | Description | Impact | Tags | Enabled by default | Failures | Needs Review |\n| :------- | :------- | :------- | :------- | :------- | :------- | :------- |\n';
Expand Down Expand Up @@ -59,15 +60,18 @@ function buildRules(grunt, options, commons, callback) {
Object.keys(result.messages).forEach(function(key) {
// only convert to templated function for strings
// objects handled later in publish-metadata.js
if (typeof result.messages[key] !== 'object') {
if (
typeof result.messages[key] !== 'object' &&
dotRegex.test(result.messages[key])
) {
result.messages[key] = dot
.template(result.messages[key])
.toString();
}
});
}
//TODO this is actually failureSummaries, property name should better reflect that
if (result.failureMessage) {
if (result.failureMessage && dotRegex.test(result.failureMessage)) {
result.failureMessage = dot.template(result.failureMessage).toString();
}
return result;
Expand All @@ -86,7 +90,10 @@ function buildRules(grunt, options, commons, callback) {
function getIncompleteMsg(summaries) {
var result = {};
summaries.forEach(function(summary) {
if (summary.incompleteFallbackMessage) {
if (
summary.incompleteFallbackMessage &&
dotRegex.test(summary.incompleteFallbackMessage)
) {
result = dot.template(summary.incompleteFallbackMessage).toString();
}
});
Expand Down
2 changes: 0 additions & 2 deletions build/tasks/validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ function hasMultipleOutcomes(messages) {
switch (key) {
case 'pass':
case 'fail':
return typeof messages[key] === 'string';

case 'incomplete':
return ['string', 'object'].includes(typeof messages[key]);

Expand Down
38 changes: 38 additions & 0 deletions build/test/get-test-urls.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
const globby = require('globby');

const getTestUrls = async (host = `localhost`, port = `9876`) => {
const urls = [
/**
* Unit tests -> Core
*/
`http://${host}:${port}/test/core/`,
/**
* Unit tests -> Checks
*/
`http://${host}:${port}/test/checks/`,
/**
* Unit tests -> Matches
*/
`http://${host}:${port}/test/rule-matches/`,
/**
* Unit tests -> Commons
*/
`http://${host}:${port}/test/commons/`,
/**
* Integration tests -> rules
*/
`http://${host}:${port}/test/integration/rules`,
/**
* Integration tests -> full
*/
...(
await globby([
'test/integration/full/**/*.html',
'!test/integration/full/**/frames/**/*.html'
])
).map(file => `http://${host}:${port}/${file}`)
];
return urls;
};

module.exports = getTestUrls;
26 changes: 26 additions & 0 deletions build/test/headless.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* Note:
* For this to be run via `npm run test:headless` ensure server is running
*/
const getTestUrls = require('./get-test-urls');
const { runner } = require('mocha-headless-chrome');

/**
* Run headless tests
*/
(async function runTests() {
const testUrls = await getTestUrls();
for (const url of testUrls) {
const options = {
file: url
};
const { result } = await runner(options);

/**
* Stop test execution on failure, for early feedback
*/
if (result.stats.failures > 0) {
process.exit(1);
}
}
})();
1 change: 0 additions & 1 deletion doc/aria-supported.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,3 @@ For a detailed description about how accessibility support is decided, see [How
| aria-attribute | axe-core support |
| ---------------- | ---------------- |
| aria-describedat | No |
| aria-details | No |

0 comments on commit 13f7457

Please sign in to comment.