From 6fa6331d505ebbd98e9d7f84e57ec7e5a13aded3 Mon Sep 17 00:00:00 2001 From: Steven Lambert <2433219+straker@users.noreply.github.com> Date: Thu, 5 Jan 2023 08:13:01 -0700 Subject: [PATCH 01/12] ci: verify sri-history in release pr (#3845) * ci: verify sri-history in release pr * typo * run in master --- .circleci/config.yml | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index cc5eb1f3f1..5ba6881d61 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -231,7 +231,7 @@ jobs: - run: npm publish --tag=next # Release a "production" version - release: + verify_sri: <<: *defaults <<: *unix_box steps: @@ -240,6 +240,15 @@ jobs: - <<: *restore_dependency_cache_unix - run: npm run build - run: npm run sri-validate + + # Release a "production" version + release: + <<: *defaults + <<: *unix_box + steps: + - checkout + - <<: *set_npm_auth + - <<: *restore_dependency_cache_unix - run: .circleci/verify-release.sh - run: npm publish @@ -317,6 +326,15 @@ workflows: - test_node: requires: - test_chrome + # Verify the sri history is correct + - verify_sri: + requires: + - dependencies_unix + filters: + branches: + only: + - /release-*/ + - master # Hold for approval - hold: type: approval @@ -328,6 +346,7 @@ workflows: - build_api_docs - test_rule_help_version - test_node + - verify_sri filters: branches: only: @@ -357,6 +376,7 @@ workflows: - build_api_docs - test_rule_help_version - test_node + - verify_sri - hold filters: branches: From 32f67844c927a209fcb34dcf8e85cc04a7553292 Mon Sep 17 00:00:00 2001 From: Steven Lambert <2433219+straker@users.noreply.github.com> Date: Fri, 6 Jan 2023 08:04:46 -0700 Subject: [PATCH 02/12] ci: streamline ci (#3846) * ci: cache axe.js build * use correct brackets * skip install if cache exists * test skip * finalize * add axe.min.js --- .circleci/config.yml | 90 ++++++++++++++++++++++++++++---------------- 1 file changed, 58 insertions(+), 32 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5ba6881d61..7bd090cc0f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -20,9 +20,15 @@ set_npm_auth: &set_npm_auth restore_dependency_cache_unix: &restore_dependency_cache_unix restore_cache: + name: Restore NPM Cache keys: - v9-cache-unix-{{ checksum "package-lock.json" }} - - v9-cache-unix- + +restore_build: &restore_build + restore_cache: + name: Restore Axe.js Cache + keys: + - v9-cache-build-<< pipeline.git.revision >> jobs: # Fetch and cache dependencies. @@ -30,10 +36,19 @@ jobs: <<: *defaults <<: *unix_box steps: - - browser-tools/install-browser-tools - checkout - - <<: *set_npm_auth - <<: *restore_dependency_cache_unix + - run: + name: Skip Install If Cache Exists + command: | + if [ -d "node_modules" ]; then + echo "node_modules exist" + circleci step halt + else + echo "node_modules does not exist" + fi + - browser-tools/install-browser-tools + - <<: *set_npm_auth - run: npm ci - run: npx browser-driver-manager install chromedriver --verbose - save_cache: @@ -41,6 +56,20 @@ jobs: paths: - node_modules + # Build and cache axe.js + build_unix: + <<: *defaults + <<: *unix_box + steps: + - checkout + - <<: *restore_dependency_cache_unix + - run: npm run build + - save_cache: + key: v9-cache-build-<< pipeline.git.revision >> + paths: + - axe.js + - axe.min.js + # Run ESLINT lint: <<: *defaults @@ -59,7 +88,7 @@ jobs: - checkout - <<: *restore_dependency_cache_unix - run: npx browser-driver-manager install chromedriver --verbose - - run: npm run build + - <<: *restore_build - run: npm run test -- --browsers Chrome - run: npm run test:integration:chrome @@ -70,7 +99,7 @@ jobs: - browser-tools/install-browser-tools - checkout - <<: *restore_dependency_cache_unix - - run: npm run build + - <<: *restore_build - run: npm run test -- --browsers Firefox - run: npm run test:integration:firefox @@ -83,7 +112,7 @@ jobs: - checkout - <<: *restore_dependency_cache_unix - run: npx browser-driver-manager install chromedriver --verbose - - run: npm run build + - <<: *restore_build - run: npm run test:examples # Run ACT test cases @@ -95,7 +124,7 @@ jobs: - checkout - <<: *restore_dependency_cache_unix - run: npx browser-driver-manager install chromedriver --verbose - - run: npm run build + - <<: *restore_build - run: npm run test:act # Run ARIA practices test cases @@ -107,7 +136,7 @@ jobs: - checkout - <<: *restore_dependency_cache_unix - run: npx browser-driver-manager install chromedriver --verbose - - run: npm run build + - <<: *restore_build - run: npm run test:apg # Test locale files @@ -119,7 +148,7 @@ jobs: - checkout - <<: *restore_dependency_cache_unix - run: npx browser-driver-manager install chromedriver --verbose - - run: npm run build + - <<: *restore_build - run: npm run test:locales # Test virtual rules @@ -131,7 +160,7 @@ jobs: - checkout - <<: *restore_dependency_cache_unix - run: npx browser-driver-manager install chromedriver --verbose - - run: npm run build + - <<: *restore_build - run: npm run test:virtual-rules # Run the test suite for nightly builds. @@ -142,7 +171,7 @@ jobs: - checkout - <<: *restore_dependency_cache_unix - run: sudo apt-get update -y - - run: npm run build + - <<: *restore_build - run: name: Install Chrome and ChromeDriver Beta command: npx browser-driver-manager install chrome=beta chromedriver=beta --verbose @@ -169,7 +198,7 @@ jobs: # also re-installs all repo dependencies as well - run: npm install w3c/wcag-act-rules#main - run: npx browser-driver-manager install chromedriver --verbose - - run: npm run build + - <<: *restore_build - run: npm run test:act # Run the test suite for nightly builds. @@ -185,7 +214,7 @@ jobs: # also re-installs all repo dependencies as well - run: npm install w3c/aria-practices#main - run: npx browser-driver-manager install chromedriver --verbose - - run: npm run build + - <<: *restore_build - run: npm run test:apg # Test api docs can be built @@ -214,7 +243,7 @@ jobs: steps: - checkout - <<: *restore_dependency_cache_unix - - run: npm run build + - <<: *restore_build - run: npm run test:node # Release a "next" version @@ -225,7 +254,7 @@ jobs: - checkout - <<: *set_npm_auth - <<: *restore_dependency_cache_unix - - run: npm run build + - <<: *restore_build - run: npm run next-release - run: .circleci/verify-release.sh - run: npm publish --tag=next @@ -238,7 +267,7 @@ jobs: - checkout - <<: *set_npm_auth - <<: *restore_dependency_cache_unix - - run: npm run build + - <<: *restore_build - run: npm run sri-validate # Release a "production" version @@ -291,10 +320,13 @@ workflows: jobs: # install deps - dependencies_unix + - build_unix: + requires: + - dependencies_unix # Run linting - lint: requires: - - dependencies_unix + - build_unix # Run tests on all commits, but after installing dependencies - test_chrome: requires: @@ -336,11 +368,13 @@ workflows: - /release-*/ - master # Hold for approval - - hold: + - hold_release: type: approval requires: - - test_chrome + - test_firefox - test_examples + - test_act + - test_aria_practices - test_locales - test_virtual_rules - build_api_docs @@ -354,30 +388,22 @@ workflows: # Run a next release on "develop" commits, but only after the tests pass and dependencies are installed - next_release: requires: - - dependencies_unix - - test_chrome - test_firefox - test_examples + - test_act + - test_aria_practices - test_locales - test_virtual_rules - build_api_docs + - test_rule_help_version + - test_node filters: branches: only: develop # Run a production release on "master" commits, but only after the tests pass and dependencies are installed - release: requires: - - dependencies_unix - - test_chrome - - test_firefox - - test_examples - - test_locales - - test_virtual_rules - - build_api_docs - - test_rule_help_version - - test_node - - verify_sri - - hold + - hold_release filters: branches: only: master From 4c3a00c7bd6de68b2795be37113a59d804d0a313 Mon Sep 17 00:00:00 2001 From: Steven Lambert <2433219+straker@users.noreply.github.com> Date: Fri, 6 Jan 2023 08:56:50 -0700 Subject: [PATCH 03/12] fix(color-contrast): correctly compute color contrast of elements (#3847) * fix(color-contrast): correctly compute color contrast of elements * Update lib/commons/dom/create-grid.js Co-authored-by: Wilco Fiers Co-authored-by: Wilco Fiers --- lib/commons/dom/create-grid.js | 9 ++++++++- test/checks/color/color-contrast.js | 23 +++++++++++++++++++++++ test/commons/dom/get-element-stack.js | 20 ++++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/lib/commons/dom/create-grid.js b/lib/commons/dom/create-grid.js index f4c0278502..509fbba5f9 100644 --- a/lib/commons/dom/create-grid.js +++ b/lib/commons/dom/create-grid.js @@ -54,10 +54,17 @@ export default function createGrid( while (node) { let vNode = getNodeFromTree(node); + if (vNode && vNode.parent) { + parentVNode = vNode.parent; + } + // elements with an assigned slot need to be a child of the slot element + else if (node.assignedSlot) { + parentVNode = getNodeFromTree(node.assignedSlot); + } // an svg in IE11 does not have a parentElement but instead has a // parentNode. but parentNode could be a shadow root so we need to // verify it's in the tree first - if (node.parentElement) { + else if (node.parentElement) { parentVNode = getNodeFromTree(node.parentElement); } else if (node.parentNode && getNodeFromTree(node.parentNode)) { parentVNode = getNodeFromTree(node.parentNode); diff --git a/test/checks/color/color-contrast.js b/test/checks/color/color-contrast.js index d5ae1deea3..d6f5fcb627 100644 --- a/test/checks/color/color-contrast.js +++ b/test/checks/color/color-contrast.js @@ -906,6 +906,29 @@ describe('color-contrast', function () { } ); + (shadowSupported ? it : xit)('handles elements', () => { + fixture.innerHTML = + '

Slotted text

'; + const container = fixture.querySelector('#container'); + const shadow = container.attachShadow({ mode: 'open' }); + + shadow.innerHTML = + '
'; + const shadowContainer = shadow.querySelector('#shadowContainer'); + axe.testUtils.flatTreeSetup(fixture); + + const target = fixture.querySelector('#target'); + const vNode = axe.utils.getNodeFromTree(target); + const result = contrastEvaluate.call( + checkContext, + vNode.actualNode, + null, + vNode + ); + assert.isFalse(result); + assert.deepEqual(checkContext._relatedNodes, [shadowContainer]); + }); + describe('with text-shadow', function () { it('passes if thin text shadows have sufficient contrast with the text', function () { var params = checkSetup( diff --git a/test/commons/dom/get-element-stack.js b/test/commons/dom/get-element-stack.js index 4a2d3f1baa..fb33e7f2da 100644 --- a/test/commons/dom/get-element-stack.js +++ b/test/commons/dom/get-element-stack.js @@ -570,6 +570,26 @@ describe('dom.getElementStack', function () { ]); } ); + + (shadowSupported ? it : xit)('should sort elements', () => { + fixture.innerHTML = + '

Slotted text

'; + const container = fixture.querySelector('#container'); + const shadow = container.attachShadow({ mode: 'open' }); + + shadow.innerHTML = + '
'; + axe.testUtils.flatTreeSetup(fixture); + + const target = fixture.querySelector('#target'); + const stack = mapToIDs(getElementStack(target)); + assert.deepEqual(stack, [ + 'target', + 'shadowContainer', + 'container', + 'fixture' + ]); + }); }); describe('scroll regions', function () { From f5c5258f281cbda164a143c4032f32dcaf7f9681 Mon Sep 17 00:00:00 2001 From: Steven Lambert <2433219+straker@users.noreply.github.com> Date: Tue, 10 Jan 2023 08:33:54 -0700 Subject: [PATCH 04/12] chore: update dependencies (#3851) * chore: update dependencies * update examples * :robot: Automated formatting fixes * fix jsdoc Co-authored-by: straker --- doc/examples/chrome-debugging-protocol/.npmrc | 1 - .../chrome-debugging-protocol/package.json | 6 +- doc/examples/jasmine/package.json | 9 +- doc/examples/jest_react/.babelrc | 12 +- doc/examples/jest_react/jest.setup.js | 4 + doc/examples/jest_react/link.test.js | 13 +- doc/examples/jest_react/package.json | 27 +- doc/examples/jest_react/test-helpers.js | 21 - doc/examples/jsdom/package.json | 7 +- doc/examples/mocha/package.json | 9 +- doc/examples/puppeteer/.npmrc | 1 - doc/examples/puppeteer/package.json | 6 +- doc/examples/qunit/Gruntfile.js | 13 +- doc/examples/qunit/package.json | 10 +- package-lock.json | 947 ++++++++++-------- package.json | 52 +- 16 files changed, 618 insertions(+), 520 deletions(-) delete mode 100644 doc/examples/chrome-debugging-protocol/.npmrc create mode 100644 doc/examples/jest_react/jest.setup.js delete mode 100644 doc/examples/jest_react/test-helpers.js delete mode 100644 doc/examples/puppeteer/.npmrc diff --git a/doc/examples/chrome-debugging-protocol/.npmrc b/doc/examples/chrome-debugging-protocol/.npmrc deleted file mode 100644 index 43c97e719a..0000000000 --- a/doc/examples/chrome-debugging-protocol/.npmrc +++ /dev/null @@ -1 +0,0 @@ -package-lock=false diff --git a/doc/examples/chrome-debugging-protocol/package.json b/doc/examples/chrome-debugging-protocol/package.json index 145bf92449..c3ea3536f2 100644 --- a/doc/examples/chrome-debugging-protocol/package.json +++ b/doc/examples/chrome-debugging-protocol/package.json @@ -4,8 +4,8 @@ "scripts": { "test": "echo 'No test specified.'" }, - "dependencies": { - "axe-core": "^3.3.1", - "chrome-remote-interface": "^0.27.1" + "devDependencies": { + "axe-core": "^4.6.2", + "chrome-remote-interface": "^0.31.3" } } diff --git a/doc/examples/jasmine/package.json b/doc/examples/jasmine/package.json index 36246bc714..d086c088b8 100644 --- a/doc/examples/jasmine/package.json +++ b/doc/examples/jasmine/package.json @@ -8,14 +8,13 @@ "organization": "Deque Systems, Inc.", "url": "http://deque.com/" }, - "dependencies": {}, "scripts": { "test": "karma start karma.conf.js" }, "devDependencies": { - "axe-core": "^3.3.1", - "karma": "^4.2.0", - "karma-chrome-launcher": "^3.0.0", - "karma-jasmine": "^2.0.1" + "axe-core": "^4.6.2", + "karma": "^6.4.1", + "karma-chrome-launcher": "^3.1.1", + "karma-jasmine": "^5.1.0" } } diff --git a/doc/examples/jest_react/.babelrc b/doc/examples/jest_react/.babelrc index 2b7bafa5fa..2250a39858 100644 --- a/doc/examples/jest_react/.babelrc +++ b/doc/examples/jest_react/.babelrc @@ -1,3 +1,13 @@ { - "presets": ["@babel/preset-env", "@babel/preset-react"] + "presets": [ + [ + "@babel/preset-env", + { + "targets": { + "node": "current" + } + } + ], + "@babel/preset-react" + ] } diff --git a/doc/examples/jest_react/jest.setup.js b/doc/examples/jest_react/jest.setup.js new file mode 100644 index 0000000000..c07c082506 --- /dev/null +++ b/doc/examples/jest_react/jest.setup.js @@ -0,0 +1,4 @@ +const Enzyme = require('enzyme'); +const Adapter = require('@wojtekmaj/enzyme-adapter-react-17'); + +Enzyme.configure({ adapter: new Adapter() }); diff --git a/doc/examples/jest_react/link.test.js b/doc/examples/jest_react/link.test.js index 9156d1a151..d9bd25271f 100644 --- a/doc/examples/jest_react/link.test.js +++ b/doc/examples/jest_react/link.test.js @@ -1,14 +1,17 @@ import React from 'react'; +import { mount, render } from 'enzyme'; import axe from 'axe-core'; -import { mountToDoc } from './test-helpers'; import Link from './link'; test('Link has no axe violations', done => { - const linkComponent = mountToDoc( - axe website + const fixture = document.createElement('div'); + document.body.appendChild(fixture); + + const linkComponent = mount( + axe website, + { attachTo: fixture } ); - const linkNode = linkComponent.getDOMNode(); const config = { rules: { @@ -16,7 +19,7 @@ test('Link has no axe violations', done => { 'link-in-text-block': { enabled: false } } }; - axe.run(linkNode, config, (err, { violations }) => { + axe.run(fixture, config, (err, { violations }) => { expect(err).toBe(null); expect(violations).toHaveLength(0); done(); diff --git a/doc/examples/jest_react/package.json b/doc/examples/jest_react/package.json index 78186e1c78..0a67634b91 100644 --- a/doc/examples/jest_react/package.json +++ b/doc/examples/jest_react/package.json @@ -8,21 +8,24 @@ "organization": "Deque Systems, Inc.", "url": "http://deque.com/" }, - "dependencies": {}, "scripts": { "test": "jest" }, "devDependencies": { - "@babel/preset-env": "^7.5.5", - "@babel/preset-react": "^7.0.0", - "axe-core": "^3.3.1", - "babel-jest": "^24.8.0", - "enzyme": "^3.10.0", - "enzyme-adapter-react-16": "^1.14.0", - "jest": "^24.8.0", - "jest-cli": "^24.8.0", - "react": "^16.4.0", - "react-dom": "^16.4.0", - "react-test-renderer": "^16.2.0" + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@wojtekmaj/enzyme-adapter-react-17": "^0.8.0", + "axe-core": "^4.6.2", + "enzyme": "^3.11.0", + "jest": "^29.3.1", + "jest-environment-jsdom": "^29.3.1", + "react": "^17.0.2", + "react-dom": "^17.0.2" + }, + "jest": { + "testEnvironment": "jsdom", + "setupFilesAfterEnv": [ + "/jest.setup.js" + ] } } diff --git a/doc/examples/jest_react/test-helpers.js b/doc/examples/jest_react/test-helpers.js deleted file mode 100644 index d99de0f3bb..0000000000 --- a/doc/examples/jest_react/test-helpers.js +++ /dev/null @@ -1,21 +0,0 @@ -import { configure, mount } from 'enzyme'; -import Adapter from 'enzyme-adapter-react-16'; - -configure({ adapter: new Adapter() }); - -let wrapper; -export function mountToDoc(reactElm) { - if (!document) { - // Set up a basic DOM - global.document = jsdom(''); - } - if (!wrapper) { - wrapper = document.createElement('main'); - document.body.appendChild(wrapper); - } - - const container = mount(reactElm); - wrapper.innerHTML = ''; - wrapper.appendChild(container.getDOMNode()); - return container; -} diff --git a/doc/examples/jsdom/package.json b/doc/examples/jsdom/package.json index 12c13bd161..d74cfeafa8 100644 --- a/doc/examples/jsdom/package.json +++ b/doc/examples/jsdom/package.json @@ -3,13 +3,12 @@ "description": "Axe JSDOM Example", "version": "0.0.1", "private": true, - "dependencies": {}, "scripts": { "test": "mocha" }, "devDependencies": { - "axe-core": "^3.3.1", - "jsdom": "^15.1.1", - "mocha": "^6.2.0" + "axe-core": "^4.6.2", + "jsdom": "^21.0.0", + "mocha": "^10.2.0" } } diff --git a/doc/examples/mocha/package.json b/doc/examples/mocha/package.json index a85fb18657..002eb36f09 100644 --- a/doc/examples/mocha/package.json +++ b/doc/examples/mocha/package.json @@ -8,15 +8,14 @@ "organization": "Deque Systems, Inc.", "url": "http://deque.com/" }, - "dependencies": {}, "scripts": { "test": "karma start karma.conf.js" }, "devDependencies": { - "axe-core": "^3.3.1", - "karma": "^4.2.0", + "axe-core": "^4.6.2", + "karma": "^6.4.1", "karma-chai": "^0.1.0", - "karma-chrome-launcher": "^3.0.0", - "karma-mocha": "^1.3.0" + "karma-chrome-launcher": "^3.1.1", + "karma-mocha": "^2.0.1" } } diff --git a/doc/examples/puppeteer/.npmrc b/doc/examples/puppeteer/.npmrc deleted file mode 100644 index 43c97e719a..0000000000 --- a/doc/examples/puppeteer/.npmrc +++ /dev/null @@ -1 +0,0 @@ -package-lock=false diff --git a/doc/examples/puppeteer/package.json b/doc/examples/puppeteer/package.json index 28f43a6e90..c3f7767446 100644 --- a/doc/examples/puppeteer/package.json +++ b/doc/examples/puppeteer/package.json @@ -6,8 +6,8 @@ "scripts": { "test": "node axe-puppeteer.js https://deque.com" }, - "dependencies": { - "axe-core": "^3.3.1", - "puppeteer": "^1.19.0" + "devDependencies": { + "axe-core": "^4.6.2", + "puppeteer": "^19.5.0" } } diff --git a/doc/examples/qunit/Gruntfile.js b/doc/examples/qunit/Gruntfile.js index c70bbe6ef8..bc50188c67 100644 --- a/doc/examples/qunit/Gruntfile.js +++ b/doc/examples/qunit/Gruntfile.js @@ -5,7 +5,18 @@ module.exports = function (grunt) { grunt.initConfig({ qunit: { - all: ['test/**/*.html'] + all: ['test/**/*.html'], + options: { + puppeteer: { + ignoreDefaultArgs: true, + args: [ + '--headless', + '--disable-web-security', + '--allow-file-access-from-files' + ] + }, + timeout: 10000 + } } }); }; diff --git a/doc/examples/qunit/package.json b/doc/examples/qunit/package.json index 8c46c48ccf..68c36555dc 100644 --- a/doc/examples/qunit/package.json +++ b/doc/examples/qunit/package.json @@ -8,14 +8,14 @@ "organization": "Deque Systems, Inc.", "url": "http://deque.com/" }, - "dependencies": {}, "scripts": { "test": "grunt qunit" }, "devDependencies": { - "axe-core": "^3.3.1", - "grunt": "~1.0.2", - "grunt-contrib-qunit": "~3.1.0", - "qunitjs": "~2.4.1" + "axe-core": "^4.6.2", + "grunt": "^1.5.3", + "grunt-contrib-qunit": "^5.1.1", + "puppeteer": "^19.5.0", + "qunitjs": "^2.0.1" } } diff --git a/package-lock.json b/package-lock.json index 8a7601ab27..b7449d9ef4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,27 +9,27 @@ "version": "4.6.2", "license": "MPL-2.0", "devDependencies": { - "@axe-core/webdriverjs": "^4.4.3", - "@babel/core": "^7.18.6", - "@babel/plugin-proposal-object-rest-spread": "^7.18.6", - "@babel/preset-env": "^7.18.6", - "@babel/runtime-corejs3": "^7.18.6", + "@axe-core/webdriverjs": "^4.5.2", + "@babel/core": "^7.20.12", + "@babel/plugin-proposal-object-rest-spread": "^7.20.7", + "@babel/preset-env": "^7.20.2", + "@babel/runtime-corejs3": "^7.20.7", "@deque/dot": "^1.1.5", "aria-practices": "github:w3c/aria-practices#edbf534", - "aria-query": "^5.0.0", + "aria-query": "^5.1.3", "browser-driver-manager": "1.0.4", - "chai": "~4.3.6", + "chai": "^4.3.7", "chalk": "^4.x", "chromedriver": "latest", "clone": "^2.1.2", "conventional-commits-parser": "^3.2.4", - "core-js": "^3.23.5", + "core-js": "^3.27.1", "css-selector-parser": "^1.4.1", "emoji-regex": "^10.2.1", "es6-promise": "^4.2.8", "esbuild": "^0.10.x", - "eslint": "^8.19.0", - "eslint-config-prettier": "^8.5.0", + "eslint": "^8.31.0", + "eslint-config-prettier": "^8.6.0", "eslint-plugin-mocha-no-only": "^1.1.1", "execa": "5.x", "globby": "11.x", @@ -42,38 +42,38 @@ "grunt-contrib-watch": "^1.1.0", "html-entities": "1.x", "http-server": "^14.1.1", - "husky": "^8.0.1", - "jquery": "^3.6.0", + "husky": "^8.0.3", + "jquery": "^3.6.3", "jsdoc": "^3.6.11", - "jsdom": "^20.0.0", - "karma": "^6.4.0", + "jsdom": "^21.0.0", + "karma": "^6.4.1", "karma-chai": "^0.1.0", "karma-chrome-launcher": "^3.1.1", "karma-firefox-launcher": "^2.1.2", "karma-ie-launcher": "^1.0.0", "karma-mocha": "^2.0.1", "karma-sinon": "^1.0.5", - "karma-spec-reporter": "0.0.34", - "lint-staged": "^13.0.3", + "karma-spec-reporter": "^0.0.36", + "lint-staged": "^13.1.0", "make-dir": "^3.1.0", "markdown-table": "2.x", "memoizee": "^0.4.15", "minami": "^1.2.3", - "mocha": "^10.0.0", + "mocha": "^10.2.0", "node-notifier": "^10.0.1", "npm-run-all": "^4.1.5", - "prettier": "^2.7.1", + "prettier": "^2.8.2", "proxyquire": "^2.1.3", - "revalidator": "~0.3.1", - "selenium-webdriver": "^4.5.0", - "serve-handler": "^6.1.3", - "sinon": "^11.1.2", + "revalidator": "^0.3.1", + "selenium-webdriver": "^4.7.1", + "serve-handler": "^6.1.5", + "sinon": "^15.0.1", "sri-toolbox": "^0.2.0", "standard-version": "^9.5.0", - "start-server-and-test": "^1.14.0", - "typedarray": "^0.0.6", - "typescript": "^4.7.4", - "uglify-js": "^3.16.2", + "start-server-and-test": "^1.15.2", + "typedarray": "^0.0.7", + "typescript": "^4.9.4", + "uglify-js": "^3.17.4", "wcag-act-rules": "github:w3c/wcag-act-rules#9416ea6", "weakmap-polyfill": "^2.0.4" }, @@ -95,12 +95,12 @@ } }, "node_modules/@axe-core/webdriverjs": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@axe-core/webdriverjs/-/webdriverjs-4.5.1.tgz", - "integrity": "sha512-YLMtBd6SmlKOaPQ45wG6rVn4mABKJm8mum93MpxVNdt24/7NJhQ5RCM6qOvDCNxSZ3mC3divplmQaI43YFTqMA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@axe-core/webdriverjs/-/webdriverjs-4.5.2.tgz", + "integrity": "sha512-7OvK9y6vn4VEGiwosyQd0O14YWaDCIvrVDlDG8bbUauFS6jncZin0rVmuwrPWt40SpHY/uxJypfZgPJcENHuPw==", "dev": true, "dependencies": { - "axe-core": "^4.5.1" + "axe-core": "^4.5.2" }, "peerDependencies": { "selenium-webdriver": ">3.0.0-beta || >=2.53.1 || >4.0.0-alpha" @@ -119,34 +119,34 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.1.tgz", - "integrity": "sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ==", + "version": "7.20.10", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.10.tgz", + "integrity": "sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.2.tgz", - "integrity": "sha512-w7DbG8DtMrJcFOi4VrLm+8QM4az8Mo+PuLBKLp2zrYRCow8W/f9xiXm5sN53C8HksCyDQwCKha9JiDoIyPjT2g==", + "version": "7.20.12", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz", + "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.2", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-module-transforms": "^7.20.2", - "@babel/helpers": "^7.20.1", - "@babel/parser": "^7.20.2", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.2", + "@babel/generator": "^7.20.7", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helpers": "^7.20.7", + "@babel/parser": "^7.20.7", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.12", + "@babel/types": "^7.20.7", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", + "json5": "^2.2.2", "semver": "^6.3.0" }, "engines": { @@ -158,12 +158,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.20.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.4.tgz", - "integrity": "sha512-luCf7yk/cm7yab6CAW1aiFnmEfBJplb/JojV56MYEK7ziWfGmFlTfmL9Ehwfy4gFhbjBfWO1wj7/TuSbVNEEtA==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.7.tgz", + "integrity": "sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==", "dev": true, "dependencies": { - "@babel/types": "^7.20.2", + "@babel/types": "^7.20.7", "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" }, @@ -211,14 +211,15 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", - "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", + "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.20.0", + "@babel/compat-data": "^7.20.5", "@babel/helper-validator-option": "^7.18.6", "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", "semver": "^6.3.0" }, "engines": { @@ -228,6 +229,21 @@ "@babel/core": "^7.0.0" } }, + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, "node_modules/@babel/helper-create-class-features-plugin": { "version": "7.20.2", "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.2.tgz", @@ -353,9 +369,9 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", - "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", + "version": "7.20.11", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz", + "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==", "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.18.9", @@ -363,9 +379,9 @@ "@babel/helper-simple-access": "^7.20.2", "@babel/helper-split-export-declaration": "^7.18.6", "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.2" + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.10", + "@babel/types": "^7.20.7" }, "engines": { "node": ">=6.9.0" @@ -505,14 +521,14 @@ } }, "node_modules/@babel/helpers": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.1.tgz", - "integrity": "sha512-J77mUVaDTUJFZ5BpP6mMn6OIl3rEWymk2ZxDBQJUG3P+PbmyMcF3bYWvz0ma69Af1oobDqT/iAsvzhB58xhQUg==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.7.tgz", + "integrity": "sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA==", "dev": true, "dependencies": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.0" + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.7", + "@babel/types": "^7.20.7" }, "engines": { "node": ">=6.9.0" @@ -604,9 +620,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.20.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.3.tgz", - "integrity": "sha512-OP/s5a94frIPXwjzEcv5S/tpQfc6XhxYUnmWpgdqMWGgYCuErA3SzozaRAMQgSZWKeTJxht9aWAkUY+0UzvOFg==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.7.tgz", + "integrity": "sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -795,16 +811,16 @@ } }, "node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.2.tgz", - "integrity": "sha512-Ks6uej9WFK+fvIMesSqbAto5dD8Dz4VuuFvGJFKgIGSkJuRGcrwGECPA1fDgQK3/DbExBJpEkTeYeB8geIFCSQ==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz", + "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.20.1", - "@babel/helper-compilation-targets": "^7.20.0", + "@babel/compat-data": "^7.20.5", + "@babel/helper-compilation-targets": "^7.20.7", "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.20.1" + "@babel/plugin-transform-parameters": "^7.20.7" }, "engines": { "node": ">=6.9.0" @@ -1427,9 +1443,9 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.20.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.3.tgz", - "integrity": "sha512-oZg/Fpx0YDrj13KsLyO8I/CX3Zdw7z0O9qOd95SqcoIzuqy/WTGWvePeHAnZCN54SfdyjHcb1S30gc8zlzlHcA==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.7.tgz", + "integrity": "sha512-WiWBIkeHKVOSYPO0pWkxGPfKeWrCJyD3NJ53+Lrp/QMSZbsVPovrVl2aWZ19D/LTVnaDv5Ap7GJ/B2CTOZdrfA==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.20.2" @@ -1712,46 +1728,46 @@ } }, "node_modules/@babel/runtime-corejs3": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.20.1.tgz", - "integrity": "sha512-CGulbEDcg/ND1Im7fUNRZdGXmX2MTWVVZacQi/6DiKE5HNwZ3aVTm5PV4lO8HHz0B2h8WQyvKKjbX5XgTtydsg==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.20.7.tgz", + "integrity": "sha512-jr9lCZ4RbRQmCR28Q8U8Fu49zvFqLxTY9AMOUz+iyMohMoAgpEcVxY+wJNay99oXOpOcCTODkk70NDN2aaJEeg==", "dev": true, "dependencies": { "core-js-pure": "^3.25.1", - "regenerator-runtime": "^0.13.10" + "regenerator-runtime": "^0.13.11" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", "dev": true, "dependencies": { "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.1.tgz", - "integrity": "sha512-d3tN8fkVJwFLkHkBN479SOsw4DMZnz8cdbL/gvuDuzy3TS6Nfw80HuQqhw1pITbIruHyh7d1fMA47kWzmcUEGA==", + "version": "7.20.12", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.12.tgz", + "integrity": "sha512-MsIbFN0u+raeja38qboyF8TIT7K0BFzz/Yd/77ta4MsUsmP2RAnidIlwq7d5HFQrH/OZJecGV6B71C4zAgpoSQ==", "dev": true, "dependencies": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.1", + "@babel/generator": "^7.20.7", "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-function-name": "^7.19.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.20.1", - "@babel/types": "^7.20.0", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -1760,9 +1776,9 @@ } }, "node_modules/@babel/types": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.2.tgz", - "integrity": "sha512-FnnvsNWgZCr232sqtXggapvlkk/tuwR/qhGzcmxI0GXLCjmPYQPzio2FbdlWuY6y1sHFfQKk+rRbUZ9VStQMog==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", + "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.19.4", @@ -1795,15 +1811,15 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", - "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", + "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^9.4.0", - "globals": "^13.15.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -1818,9 +1834,9 @@ } }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -1860,9 +1876,9 @@ } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.7", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", - "integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==", + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", @@ -2125,9 +2141,9 @@ } }, "node_modules/@sideway/formula": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz", - "integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==", "dev": true }, "node_modules/@sideway/pinpoint": { @@ -2155,16 +2171,25 @@ } }, "node_modules/@sinonjs/samsam": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.1.3.tgz", - "integrity": "sha512-nhOb2dWPeb1sd3IQXL/dVPnKHDOAFfvichtBf4xV00/rU1QbPCQqKMbvIheIjqwVjh7qIgf2AHTHi391yMOMpQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-7.0.1.tgz", + "integrity": "sha512-zsAk2Jkiq89mhZovB2LLOdTCxJF4hqqTToGP0ASWlhp4I1hqOjcfmZGafXntCN7MDC6yySH0mFHrYtHceOeLmw==", "dev": true, "dependencies": { - "@sinonjs/commons": "^1.6.0", + "@sinonjs/commons": "^2.0.0", "lodash.get": "^4.4.2", "type-detect": "^4.0.8" } }, + "node_modules/@sinonjs/samsam/node_modules/@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, "node_modules/@sinonjs/text-encoding": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", @@ -2427,6 +2452,12 @@ "node": ">= 8" } }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -2538,9 +2569,9 @@ } }, "node_modules/axe-core": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.5.1.tgz", - "integrity": "sha512-1exVbW0X1O/HSr/WMwnaweyqcWOgZgLiVxdLG34pvSQk4NlYQr9OUy0JLwuhFfuVNQzzqgH57eYzkFBCb3bIsQ==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.6.2.tgz", + "integrity": "sha512-b1WlTV8+XKLj9gZy2DZXgQiyDp9xkkoe2a6U6UbYccScq2wgH/YwCeI2/Jq2mgo0HzQxqJOjWZBLeA/mqsk5Mg==", "dev": true, "engines": { "node": ">=4" @@ -3238,6 +3269,12 @@ "node": ">= 6" } }, + "node_modules/concat-stream/node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "dev": true + }, "node_modules/connect": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", @@ -3631,9 +3668,9 @@ } }, "node_modules/core-js": { - "version": "3.26.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.26.1.tgz", - "integrity": "sha512-21491RRQVzUn0GGM9Z1Jrpr6PNPxPi+Za8OM9q4tksTSnlbXXGKK1nXNg/QvwFYettXvSX6zWKCtHHfjN4puyA==", + "version": "3.27.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.27.1.tgz", + "integrity": "sha512-GutwJLBChfGCpwwhbYoqfv03LAfmiz7e7D/BNxzeMxwQf10GRSzqiOjx7AmtEk+heiD/JWmBuyBPgFtx0Sg1ww==", "dev": true, "hasInstallScript": true, "funding": { @@ -4280,9 +4317,9 @@ } }, "node_modules/engine.io": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.0.tgz", - "integrity": "sha512-4KzwW3F3bk+KlzSOY57fj/Jx6LyRQ1nbcyIadehl+AnXjKT7gDO0ORdRi/84ixvMKTym6ZKuxvbzN62HDDU1Lg==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.1.tgz", + "integrity": "sha512-ECceEFcAaNRybd3lsGQKas3ZlMVjN3cyWwMP25D2i0zWfyiytVbTpRPa34qrr+FHddtpBVOmq4H/DCv1O0lZRA==", "dev": true, "dependencies": { "@types/cookie": "^0.4.1", @@ -4612,13 +4649,13 @@ } }, "node_modules/eslint": { - "version": "8.27.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.27.0.tgz", - "integrity": "sha512-0y1bfG2ho7mty+SiILVf9PfuRA49ek4Nc60Wmmu62QlobNR+CeXa4xXIJgcuwSQgZiWaPH+5BDsctpIW0PR/wQ==", + "version": "8.31.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.31.0.tgz", + "integrity": "sha512-0tQQEVdmPZ1UtUKXjX7EMm9BlgJ08G90IhWh0PKDCb3ZLsgAOHI8fYSIzYVZej92zsgq+ft0FGsxhJ3xo2tbuA==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.3.3", - "@humanwhocodes/config-array": "^0.11.6", + "@eslint/eslintrc": "^1.4.1", + "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.10.0", @@ -4637,7 +4674,7 @@ "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.15.0", + "globals": "^13.19.0", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", @@ -4668,9 +4705,9 @@ } }, "node_modules/eslint-config-prettier": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", - "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.6.0.tgz", + "integrity": "sha512-bAF0eLpLVqP5oEVUFKpMA+NnRFICwn9X8B5jrR9FcqnYBuPbqWEjTEspPWMj5ye6czoSLDweCzSo3Ko7gGrZaA==", "dev": true, "bin": { "eslint-config-prettier": "bin/cli.js" @@ -4741,9 +4778,9 @@ } }, "node_modules/eslint/node_modules/globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -6369,9 +6406,9 @@ } }, "node_modules/husky": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.2.tgz", - "integrity": "sha512-Tkv80jtvbnkK3mYWxPZePGFpQ/tT3HNSs/sasF9P2YfkMezDl3ON37YN6jUUI4eTg5LcyVynlb6r4eyvOmspvg==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", + "integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==", "dev": true, "bin": { "husky": "lib/bin.js" @@ -7027,9 +7064,9 @@ } }, "node_modules/jquery": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.1.tgz", - "integrity": "sha512-opJeO4nCucVnsjiXOE+/PcCgYw9Gwpvs/a6B1LL/lQhwWwpbVEVYDZ1FokFr8PRc7ghYlrFPuyHuiiDNTQxmcw==", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.3.tgz", + "integrity": "sha512-bZ5Sy3YzKo9Fyc8wH2iIQK4JImJ6R0GWI9kL1/k7Z91ZBNgkRXE6U0JfHIizZbort8ZunhSI3jw9I6253ahKfg==", "dev": true }, "node_modules/js-sdsl": { @@ -7104,18 +7141,18 @@ } }, "node_modules/jsdom": { - "version": "20.0.2", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.2.tgz", - "integrity": "sha512-AHWa+QO/cgRg4N+DsmHg1Y7xnz+8KU3EflM0LVDTdmrYOc1WWTSkOjtpUveQH+1Bqd5rtcVnb/DuxV/UjDO4rA==", + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-21.0.0.tgz", + "integrity": "sha512-AIw+3ZakSUtDYvhwPwWHiZsUi3zHugpMEKlNPaurviseYoBqo0zBd3zqoUi3LPCNtPFlEP8FiW9MqCZdjb2IYA==", "dev": true, "dependencies": { "abab": "^2.0.6", - "acorn": "^8.8.0", + "acorn": "^8.8.1", "acorn-globals": "^7.0.0", "cssom": "^0.5.0", "cssstyle": "^2.3.0", "data-urls": "^3.0.2", - "decimal.js": "^10.4.1", + "decimal.js": "^10.4.2", "domexception": "^4.0.0", "escodegen": "^2.0.0", "form-data": "^4.0.0", @@ -7128,12 +7165,12 @@ "saxes": "^6.0.0", "symbol-tree": "^3.2.4", "tough-cookie": "^4.1.2", - "w3c-xmlserializer": "^3.0.0", + "w3c-xmlserializer": "^4.0.0", "webidl-conversions": "^7.0.0", "whatwg-encoding": "^2.0.0", "whatwg-mimetype": "^3.0.0", "whatwg-url": "^11.0.0", - "ws": "^8.9.0", + "ws": "^8.11.0", "xml-name-validator": "^4.0.0" }, "engines": { @@ -7191,9 +7228,9 @@ "dev": true }, "node_modules/json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, "bin": { "json5": "lib/cli.js" @@ -7368,9 +7405,9 @@ } }, "node_modules/karma-spec-reporter": { - "version": "0.0.34", - "resolved": "https://registry.npmjs.org/karma-spec-reporter/-/karma-spec-reporter-0.0.34.tgz", - "integrity": "sha512-l5H/Nh9q4g2Ysx2CDU2m+NIPyLQpCVbk9c4V02BTZHw3NM6RO1dq3eRpKXCSSdPt4RGfhHk8jDt3XYkGp+5PWg==", + "version": "0.0.36", + "resolved": "https://registry.npmjs.org/karma-spec-reporter/-/karma-spec-reporter-0.0.36.tgz", + "integrity": "sha512-11bvOl1x6ryKZph7kmbmMpbi8vsngEGxGOoeTlIcDaH3ab3j8aPJnZ+r+K/SS0sBSGy5VGkGYO2+hLct7hw/6w==", "dev": true, "dependencies": { "colors": "1.4.0" @@ -7517,9 +7554,9 @@ } }, "node_modules/lilconfig": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.5.tgz", - "integrity": "sha512-xaYmXZtTHPAw5m+xLN8ab9C+3a8YmV3asNSPOATITbtwrfbwaLJj8h66H1WMIpALCkqsIzK3h7oQ+PdX+LQ9Eg==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz", + "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==", "dev": true, "engines": { "node": ">=10" @@ -7541,24 +7578,24 @@ } }, "node_modules/lint-staged": { - "version": "13.0.3", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-13.0.3.tgz", - "integrity": "sha512-9hmrwSCFroTSYLjflGI8Uk+GWAwMB4OlpU4bMJEAT5d/llQwtYKoim4bLOyLCuWFAhWEupE0vkIFqtw/WIsPug==", + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-13.1.0.tgz", + "integrity": "sha512-pn/sR8IrcF/T0vpWLilih8jmVouMlxqXxKuAojmbiGX5n/gDnz+abdPptlj0vYnbfE0SQNl3CY/HwtM0+yfOVQ==", "dev": true, "dependencies": { "cli-truncate": "^3.1.0", - "colorette": "^2.0.17", - "commander": "^9.3.0", + "colorette": "^2.0.19", + "commander": "^9.4.1", "debug": "^4.3.4", "execa": "^6.1.0", - "lilconfig": "2.0.5", - "listr2": "^4.0.5", + "lilconfig": "2.0.6", + "listr2": "^5.0.5", "micromatch": "^4.0.5", "normalize-path": "^3.0.0", "object-inspect": "^1.12.2", "pidtree": "^0.6.0", "string-argv": "^0.3.1", - "yaml": "^2.1.1" + "yaml": "^2.1.3" }, "bin": { "lint-staged": "bin/lint-staged.js" @@ -7681,22 +7718,22 @@ } }, "node_modules/listr2": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-4.0.5.tgz", - "integrity": "sha512-juGHV1doQdpNT3GSTs9IUN43QJb7KHdF9uqg7Vufs/tG9VTzpFphqF4pm/ICdAABGQxsyNn9CiYA3StkI6jpwA==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-5.0.6.tgz", + "integrity": "sha512-u60KxKBy1BR2uLJNTWNptzWQ1ob/gjMzIJPZffAENzpZqbMZ/5PrXXOomDcevIS/+IB7s1mmCEtSlT2qHWMqag==", "dev": true, "dependencies": { "cli-truncate": "^2.1.0", - "colorette": "^2.0.16", + "colorette": "^2.0.19", "log-update": "^4.0.0", "p-map": "^4.0.0", "rfdc": "^1.3.0", - "rxjs": "^7.5.5", + "rxjs": "^7.5.7", "through": "^2.3.8", "wrap-ansi": "^7.0.0" }, "engines": { - "node": ">=12" + "node": "^14.13.1 || >=16.0.0" }, "peerDependencies": { "enquirer": ">= 2.3.0 < 3" @@ -8320,9 +8357,9 @@ } }, "node_modules/mocha": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.1.0.tgz", - "integrity": "sha512-vUF7IYxEoN7XhQpFLxQAEMtE4W91acW4B6En9l97MwE9stL1A9gusXfoHZCLVHDUJ/7V5+lbCM6yMqzo5vNymg==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", + "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", "dev": true, "dependencies": { "ansi-colors": "4.1.1", @@ -9431,9 +9468,9 @@ } }, "node_modules/prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.2.tgz", + "integrity": "sha512-BtRV9BcncDyI2tsuS19zzhzoxD8Dh8LiCx7j7tHzrkz8GFXAexeWFdi22mjE1d16dftH2qNaytVxqiRTGlMfpw==", "dev": true, "bin": { "prettier": "bin-prettier.js" @@ -9914,9 +9951,9 @@ } }, "node_modules/regenerator-runtime": { - "version": "0.13.10", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz", - "integrity": "sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw==", + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", "dev": true }, "node_modules/regenerator-transform": { @@ -10218,9 +10255,9 @@ "dev": true }, "node_modules/selenium-webdriver": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.6.0.tgz", - "integrity": "sha512-HIH/+J+V7l/lbSRSOwyLcpjezg9CV4DLo1pBhP9aphuMlf/PJXEDwC/A/Ht2bFc1AqQppFBGvClYcuMzyO6tRw==", + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.7.1.tgz", + "integrity": "sha512-IfTM9OE8HtCKjOJwyudbAVtAHQKOJK8mu2qrXXbKyj4lqgXF+2lYW4rSZXCV6SLQRWZ+DVGkomCmFzq5orD/ZA==", "dev": true, "dependencies": { "jszip": "^3.10.0", @@ -10373,16 +10410,16 @@ "dev": true }, "node_modules/sinon": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-11.1.2.tgz", - "integrity": "sha512-59237HChms4kg7/sXhiRcUzdSkKuydDeTiamT/jesUVHshBgL8XAmhgFo0GfK6RruMDM/iRSij1EybmMog9cJw==", + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.0.1.tgz", + "integrity": "sha512-PZXKc08f/wcA/BMRGBze2Wmw50CWPiAH3E21EOi4B49vJ616vW4DQh4fQrqsYox2aNR/N3kCqLuB0PwwOucQrg==", "dev": true, "dependencies": { - "@sinonjs/commons": "^1.8.3", - "@sinonjs/fake-timers": "^7.1.2", - "@sinonjs/samsam": "^6.0.2", + "@sinonjs/commons": "^2.0.0", + "@sinonjs/fake-timers": "10.0.2", + "@sinonjs/samsam": "^7.0.1", "diff": "^5.0.0", - "nise": "^5.1.0", + "nise": "^5.1.2", "supports-color": "^7.2.0" }, "funding": { @@ -10390,6 +10427,24 @@ "url": "https://opencollective.com/sinon" } }, + "node_modules/sinon/node_modules/@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/sinon/node_modules/@sinonjs/fake-timers": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", + "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^2.0.0" + } + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -10669,18 +10724,19 @@ } }, "node_modules/start-server-and-test": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-1.14.0.tgz", - "integrity": "sha512-on5ELuxO2K0t8EmNj9MtVlFqwBMxfWOhu4U7uZD1xccVpFlOQKR93CSe0u98iQzfNxRyaNTb/CdadbNllplTsw==", + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-1.15.2.tgz", + "integrity": "sha512-t5xJX04Hg7hqxiKHMJBz/n4zIMsE6G7hpAcerFAH+4Vh9le/LeyFcJERJM7WLiPygWF9TOg33oroJF1XOzJtYQ==", "dev": true, "dependencies": { + "arg": "^5.0.2", "bluebird": "3.7.2", "check-more-types": "2.24.0", - "debug": "4.3.2", + "debug": "4.3.4", "execa": "5.1.1", "lazy-ass": "1.6.0", "ps-tree": "1.2.0", - "wait-on": "6.0.0" + "wait-on": "6.0.1" }, "bin": { "server-test": "src/bin/start.js", @@ -10691,23 +10747,6 @@ "node": ">=6" } }, - "node_modules/start-server-and-test/node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, "node_modules/statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", @@ -11224,15 +11263,18 @@ } }, "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.7.tgz", + "integrity": "sha512-ueeb9YybpjhivjbHP2LdFDAjbS948fGEPj+ACAMs4xCMmh72OCOMQWBQKlaN4ZNQ04yfLSDLSx1tGRIoWimObQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -11532,28 +11574,28 @@ } }, "node_modules/w3c-xmlserializer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz", - "integrity": "sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", + "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", "dev": true, "dependencies": { "xml-name-validator": "^4.0.0" }, "engines": { - "node": ">=12" + "node": ">=14" } }, "node_modules/wait-on": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-6.0.0.tgz", - "integrity": "sha512-tnUJr9p5r+bEYXPUdRseolmz5XqJTTj98JgOsfBn7Oz2dxfE2g3zw1jE+Mo8lopM3j3et/Mq1yW7kKX6qw7RVw==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-6.0.1.tgz", + "integrity": "sha512-zht+KASY3usTY5u2LgaNqn/Cd8MukxLGjdcZxT2ns5QzDmTFc4XoWBgC+C/na+sMRZTuVygQoMYwdcVjHnYIVw==", "dev": true, "dependencies": { - "axios": "^0.21.1", - "joi": "^17.4.0", + "axios": "^0.25.0", + "joi": "^17.6.0", "lodash": "^4.17.21", "minimist": "^1.2.5", - "rxjs": "^7.1.0" + "rxjs": "^7.5.4" }, "bin": { "wait-on": "bin/wait-on" @@ -11563,12 +11605,12 @@ } }, "node_modules/wait-on/node_modules/axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz", + "integrity": "sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==", "dev": true, "dependencies": { - "follow-redirects": "^1.14.0" + "follow-redirects": "^1.14.7" } }, "node_modules/wcag-act-rules": { @@ -12024,12 +12066,12 @@ } }, "@axe-core/webdriverjs": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@axe-core/webdriverjs/-/webdriverjs-4.5.1.tgz", - "integrity": "sha512-YLMtBd6SmlKOaPQ45wG6rVn4mABKJm8mum93MpxVNdt24/7NJhQ5RCM6qOvDCNxSZ3mC3divplmQaI43YFTqMA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@axe-core/webdriverjs/-/webdriverjs-4.5.2.tgz", + "integrity": "sha512-7OvK9y6vn4VEGiwosyQd0O14YWaDCIvrVDlDG8bbUauFS6jncZin0rVmuwrPWt40SpHY/uxJypfZgPJcENHuPw==", "dev": true, "requires": { - "axe-core": "^4.5.1" + "axe-core": "^4.5.2" } }, "@babel/code-frame": { @@ -12042,41 +12084,41 @@ } }, "@babel/compat-data": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.1.tgz", - "integrity": "sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ==", + "version": "7.20.10", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.10.tgz", + "integrity": "sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg==", "dev": true }, "@babel/core": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.2.tgz", - "integrity": "sha512-w7DbG8DtMrJcFOi4VrLm+8QM4az8Mo+PuLBKLp2zrYRCow8W/f9xiXm5sN53C8HksCyDQwCKha9JiDoIyPjT2g==", + "version": "7.20.12", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz", + "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==", "dev": true, "requires": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.2", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-module-transforms": "^7.20.2", - "@babel/helpers": "^7.20.1", - "@babel/parser": "^7.20.2", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.2", + "@babel/generator": "^7.20.7", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helpers": "^7.20.7", + "@babel/parser": "^7.20.7", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.12", + "@babel/types": "^7.20.7", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", + "json5": "^2.2.2", "semver": "^6.3.0" } }, "@babel/generator": { - "version": "7.20.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.4.tgz", - "integrity": "sha512-luCf7yk/cm7yab6CAW1aiFnmEfBJplb/JojV56MYEK7ziWfGmFlTfmL9Ehwfy4gFhbjBfWO1wj7/TuSbVNEEtA==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.7.tgz", + "integrity": "sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==", "dev": true, "requires": { - "@babel/types": "^7.20.2", + "@babel/types": "^7.20.7", "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" }, @@ -12114,15 +12156,33 @@ } }, "@babel/helper-compilation-targets": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", - "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", + "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", "dev": true, "requires": { - "@babel/compat-data": "^7.20.0", + "@babel/compat-data": "^7.20.5", "@babel/helper-validator-option": "^7.18.6", "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", "semver": "^6.3.0" + }, + "dependencies": { + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + } } }, "@babel/helper-create-class-features-plugin": { @@ -12217,9 +12277,9 @@ } }, "@babel/helper-module-transforms": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", - "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", + "version": "7.20.11", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz", + "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==", "dev": true, "requires": { "@babel/helper-environment-visitor": "^7.18.9", @@ -12227,9 +12287,9 @@ "@babel/helper-simple-access": "^7.20.2", "@babel/helper-split-export-declaration": "^7.18.6", "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.2" + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.10", + "@babel/types": "^7.20.7" } }, "@babel/helper-optimise-call-expression": { @@ -12330,14 +12390,14 @@ } }, "@babel/helpers": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.1.tgz", - "integrity": "sha512-J77mUVaDTUJFZ5BpP6mMn6OIl3rEWymk2ZxDBQJUG3P+PbmyMcF3bYWvz0ma69Af1oobDqT/iAsvzhB58xhQUg==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.7.tgz", + "integrity": "sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA==", "dev": true, "requires": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.0" + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.7", + "@babel/types": "^7.20.7" } }, "@babel/highlight": { @@ -12410,9 +12470,9 @@ } }, "@babel/parser": { - "version": "7.20.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.3.tgz", - "integrity": "sha512-OP/s5a94frIPXwjzEcv5S/tpQfc6XhxYUnmWpgdqMWGgYCuErA3SzozaRAMQgSZWKeTJxht9aWAkUY+0UzvOFg==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.7.tgz", + "integrity": "sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg==", "dev": true }, "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { @@ -12529,16 +12589,16 @@ } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.2.tgz", - "integrity": "sha512-Ks6uej9WFK+fvIMesSqbAto5dD8Dz4VuuFvGJFKgIGSkJuRGcrwGECPA1fDgQK3/DbExBJpEkTeYeB8geIFCSQ==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz", + "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==", "dev": true, "requires": { - "@babel/compat-data": "^7.20.1", - "@babel/helper-compilation-targets": "^7.20.0", + "@babel/compat-data": "^7.20.5", + "@babel/helper-compilation-targets": "^7.20.7", "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.20.1" + "@babel/plugin-transform-parameters": "^7.20.7" } }, "@babel/plugin-proposal-optional-catch-binding": { @@ -12942,9 +13002,9 @@ } }, "@babel/plugin-transform-parameters": { - "version": "7.20.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.3.tgz", - "integrity": "sha512-oZg/Fpx0YDrj13KsLyO8I/CX3Zdw7z0O9qOd95SqcoIzuqy/WTGWvePeHAnZCN54SfdyjHcb1S30gc8zlzlHcA==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.7.tgz", + "integrity": "sha512-WiWBIkeHKVOSYPO0pWkxGPfKeWrCJyD3NJ53+Lrp/QMSZbsVPovrVl2aWZ19D/LTVnaDv5Ap7GJ/B2CTOZdrfA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.20.2" @@ -13149,48 +13209,48 @@ } }, "@babel/runtime-corejs3": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.20.1.tgz", - "integrity": "sha512-CGulbEDcg/ND1Im7fUNRZdGXmX2MTWVVZacQi/6DiKE5HNwZ3aVTm5PV4lO8HHz0B2h8WQyvKKjbX5XgTtydsg==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.20.7.tgz", + "integrity": "sha512-jr9lCZ4RbRQmCR28Q8U8Fu49zvFqLxTY9AMOUz+iyMohMoAgpEcVxY+wJNay99oXOpOcCTODkk70NDN2aaJEeg==", "dev": true, "requires": { "core-js-pure": "^3.25.1", - "regenerator-runtime": "^0.13.10" + "regenerator-runtime": "^0.13.11" } }, "@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", "dev": true, "requires": { "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" } }, "@babel/traverse": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.1.tgz", - "integrity": "sha512-d3tN8fkVJwFLkHkBN479SOsw4DMZnz8cdbL/gvuDuzy3TS6Nfw80HuQqhw1pITbIruHyh7d1fMA47kWzmcUEGA==", + "version": "7.20.12", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.12.tgz", + "integrity": "sha512-MsIbFN0u+raeja38qboyF8TIT7K0BFzz/Yd/77ta4MsUsmP2RAnidIlwq7d5HFQrH/OZJecGV6B71C4zAgpoSQ==", "dev": true, "requires": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.1", + "@babel/generator": "^7.20.7", "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-function-name": "^7.19.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.20.1", - "@babel/types": "^7.20.0", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.2.tgz", - "integrity": "sha512-FnnvsNWgZCr232sqtXggapvlkk/tuwR/qhGzcmxI0GXLCjmPYQPzio2FbdlWuY6y1sHFfQKk+rRbUZ9VStQMog==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", + "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", "dev": true, "requires": { "@babel/helper-string-parser": "^7.19.4", @@ -13211,15 +13271,15 @@ "dev": true }, "@eslint/eslintrc": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", - "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", + "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^9.4.0", - "globals": "^13.15.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -13228,9 +13288,9 @@ }, "dependencies": { "globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -13260,9 +13320,9 @@ } }, "@humanwhocodes/config-array": { - "version": "0.11.7", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", - "integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==", + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.1", @@ -13486,9 +13546,9 @@ } }, "@sideway/formula": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz", - "integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==", "dev": true }, "@sideway/pinpoint": { @@ -13516,14 +13576,25 @@ } }, "@sinonjs/samsam": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.1.3.tgz", - "integrity": "sha512-nhOb2dWPeb1sd3IQXL/dVPnKHDOAFfvichtBf4xV00/rU1QbPCQqKMbvIheIjqwVjh7qIgf2AHTHi391yMOMpQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-7.0.1.tgz", + "integrity": "sha512-zsAk2Jkiq89mhZovB2LLOdTCxJF4hqqTToGP0ASWlhp4I1hqOjcfmZGafXntCN7MDC6yySH0mFHrYtHceOeLmw==", "dev": true, "requires": { - "@sinonjs/commons": "^1.6.0", + "@sinonjs/commons": "^2.0.0", "lodash.get": "^4.4.2", "type-detect": "^4.0.8" + }, + "dependencies": { + "@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + } } }, "@sinonjs/text-encoding": { @@ -13740,6 +13811,12 @@ "picomatch": "^2.0.4" } }, + "arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true + }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -13826,9 +13903,9 @@ "dev": true }, "axe-core": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.5.1.tgz", - "integrity": "sha512-1exVbW0X1O/HSr/WMwnaweyqcWOgZgLiVxdLG34pvSQk4NlYQr9OUy0JLwuhFfuVNQzzqgH57eYzkFBCb3bIsQ==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.6.2.tgz", + "integrity": "sha512-b1WlTV8+XKLj9gZy2DZXgQiyDp9xkkoe2a6U6UbYccScq2wgH/YwCeI2/Jq2mgo0HzQxqJOjWZBLeA/mqsk5Mg==", "dev": true }, "axios": { @@ -14363,6 +14440,12 @@ "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "dev": true } } }, @@ -14676,9 +14759,9 @@ "dev": true }, "core-js": { - "version": "3.26.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.26.1.tgz", - "integrity": "sha512-21491RRQVzUn0GGM9Z1Jrpr6PNPxPi+Za8OM9q4tksTSnlbXXGKK1nXNg/QvwFYettXvSX6zWKCtHHfjN4puyA==", + "version": "3.27.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.27.1.tgz", + "integrity": "sha512-GutwJLBChfGCpwwhbYoqfv03LAfmiz7e7D/BNxzeMxwQf10GRSzqiOjx7AmtEk+heiD/JWmBuyBPgFtx0Sg1ww==", "dev": true }, "core-js-compat": { @@ -15167,9 +15250,9 @@ } }, "engine.io": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.0.tgz", - "integrity": "sha512-4KzwW3F3bk+KlzSOY57fj/Jx6LyRQ1nbcyIadehl+AnXjKT7gDO0ORdRi/84ixvMKTym6ZKuxvbzN62HDDU1Lg==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.1.tgz", + "integrity": "sha512-ECceEFcAaNRybd3lsGQKas3ZlMVjN3cyWwMP25D2i0zWfyiytVbTpRPa34qrr+FHddtpBVOmq4H/DCv1O0lZRA==", "dev": true, "requires": { "@types/cookie": "^0.4.1", @@ -15424,13 +15507,13 @@ } }, "eslint": { - "version": "8.27.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.27.0.tgz", - "integrity": "sha512-0y1bfG2ho7mty+SiILVf9PfuRA49ek4Nc60Wmmu62QlobNR+CeXa4xXIJgcuwSQgZiWaPH+5BDsctpIW0PR/wQ==", + "version": "8.31.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.31.0.tgz", + "integrity": "sha512-0tQQEVdmPZ1UtUKXjX7EMm9BlgJ08G90IhWh0PKDCb3ZLsgAOHI8fYSIzYVZej92zsgq+ft0FGsxhJ3xo2tbuA==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.3.3", - "@humanwhocodes/config-array": "^0.11.6", + "@eslint/eslintrc": "^1.4.1", + "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.10.0", @@ -15449,7 +15532,7 @@ "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.15.0", + "globals": "^13.19.0", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", @@ -15471,9 +15554,9 @@ }, "dependencies": { "globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -15488,9 +15571,9 @@ } }, "eslint-config-prettier": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", - "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.6.0.tgz", + "integrity": "sha512-bAF0eLpLVqP5oEVUFKpMA+NnRFICwn9X8B5jrR9FcqnYBuPbqWEjTEspPWMj5ye6czoSLDweCzSo3Ko7gGrZaA==", "dev": true, "requires": {} }, @@ -16763,9 +16846,9 @@ "dev": true }, "husky": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.2.tgz", - "integrity": "sha512-Tkv80jtvbnkK3mYWxPZePGFpQ/tT3HNSs/sasF9P2YfkMezDl3ON37YN6jUUI4eTg5LcyVynlb6r4eyvOmspvg==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", + "integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==", "dev": true }, "iconv-lite": { @@ -17220,9 +17303,9 @@ } }, "jquery": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.1.tgz", - "integrity": "sha512-opJeO4nCucVnsjiXOE+/PcCgYw9Gwpvs/a6B1LL/lQhwWwpbVEVYDZ1FokFr8PRc7ghYlrFPuyHuiiDNTQxmcw==", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.3.tgz", + "integrity": "sha512-bZ5Sy3YzKo9Fyc8wH2iIQK4JImJ6R0GWI9kL1/k7Z91ZBNgkRXE6U0JfHIizZbort8ZunhSI3jw9I6253ahKfg==", "dev": true }, "js-sdsl": { @@ -17287,18 +17370,18 @@ } }, "jsdom": { - "version": "20.0.2", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.2.tgz", - "integrity": "sha512-AHWa+QO/cgRg4N+DsmHg1Y7xnz+8KU3EflM0LVDTdmrYOc1WWTSkOjtpUveQH+1Bqd5rtcVnb/DuxV/UjDO4rA==", + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-21.0.0.tgz", + "integrity": "sha512-AIw+3ZakSUtDYvhwPwWHiZsUi3zHugpMEKlNPaurviseYoBqo0zBd3zqoUi3LPCNtPFlEP8FiW9MqCZdjb2IYA==", "dev": true, "requires": { "abab": "^2.0.6", - "acorn": "^8.8.0", + "acorn": "^8.8.1", "acorn-globals": "^7.0.0", "cssom": "^0.5.0", "cssstyle": "^2.3.0", "data-urls": "^3.0.2", - "decimal.js": "^10.4.1", + "decimal.js": "^10.4.2", "domexception": "^4.0.0", "escodegen": "^2.0.0", "form-data": "^4.0.0", @@ -17311,12 +17394,12 @@ "saxes": "^6.0.0", "symbol-tree": "^3.2.4", "tough-cookie": "^4.1.2", - "w3c-xmlserializer": "^3.0.0", + "w3c-xmlserializer": "^4.0.0", "webidl-conversions": "^7.0.0", "whatwg-encoding": "^2.0.0", "whatwg-mimetype": "^3.0.0", "whatwg-url": "^11.0.0", - "ws": "^8.9.0", + "ws": "^8.11.0", "xml-name-validator": "^4.0.0" } }, @@ -17357,9 +17440,9 @@ "dev": true }, "json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true }, "jsonfile": { @@ -17523,9 +17606,9 @@ "requires": {} }, "karma-spec-reporter": { - "version": "0.0.34", - "resolved": "https://registry.npmjs.org/karma-spec-reporter/-/karma-spec-reporter-0.0.34.tgz", - "integrity": "sha512-l5H/Nh9q4g2Ysx2CDU2m+NIPyLQpCVbk9c4V02BTZHw3NM6RO1dq3eRpKXCSSdPt4RGfhHk8jDt3XYkGp+5PWg==", + "version": "0.0.36", + "resolved": "https://registry.npmjs.org/karma-spec-reporter/-/karma-spec-reporter-0.0.36.tgz", + "integrity": "sha512-11bvOl1x6ryKZph7kmbmMpbi8vsngEGxGOoeTlIcDaH3ab3j8aPJnZ+r+K/SS0sBSGy5VGkGYO2+hLct7hw/6w==", "dev": true, "requires": { "colors": "1.4.0" @@ -17619,9 +17702,9 @@ } }, "lilconfig": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.5.tgz", - "integrity": "sha512-xaYmXZtTHPAw5m+xLN8ab9C+3a8YmV3asNSPOATITbtwrfbwaLJj8h66H1WMIpALCkqsIzK3h7oQ+PdX+LQ9Eg==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz", + "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==", "dev": true }, "lines-and-columns": { @@ -17640,24 +17723,24 @@ } }, "lint-staged": { - "version": "13.0.3", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-13.0.3.tgz", - "integrity": "sha512-9hmrwSCFroTSYLjflGI8Uk+GWAwMB4OlpU4bMJEAT5d/llQwtYKoim4bLOyLCuWFAhWEupE0vkIFqtw/WIsPug==", + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-13.1.0.tgz", + "integrity": "sha512-pn/sR8IrcF/T0vpWLilih8jmVouMlxqXxKuAojmbiGX5n/gDnz+abdPptlj0vYnbfE0SQNl3CY/HwtM0+yfOVQ==", "dev": true, "requires": { "cli-truncate": "^3.1.0", - "colorette": "^2.0.17", - "commander": "^9.3.0", + "colorette": "^2.0.19", + "commander": "^9.4.1", "debug": "^4.3.4", "execa": "^6.1.0", - "lilconfig": "2.0.5", - "listr2": "^4.0.5", + "lilconfig": "2.0.6", + "listr2": "^5.0.5", "micromatch": "^4.0.5", "normalize-path": "^3.0.0", "object-inspect": "^1.12.2", "pidtree": "^0.6.0", "string-argv": "^0.3.1", - "yaml": "^2.1.1" + "yaml": "^2.1.3" }, "dependencies": { "execa": { @@ -17728,17 +17811,17 @@ } }, "listr2": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-4.0.5.tgz", - "integrity": "sha512-juGHV1doQdpNT3GSTs9IUN43QJb7KHdF9uqg7Vufs/tG9VTzpFphqF4pm/ICdAABGQxsyNn9CiYA3StkI6jpwA==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-5.0.6.tgz", + "integrity": "sha512-u60KxKBy1BR2uLJNTWNptzWQ1ob/gjMzIJPZffAENzpZqbMZ/5PrXXOomDcevIS/+IB7s1mmCEtSlT2qHWMqag==", "dev": true, "requires": { "cli-truncate": "^2.1.0", - "colorette": "^2.0.16", + "colorette": "^2.0.19", "log-update": "^4.0.0", "p-map": "^4.0.0", "rfdc": "^1.3.0", - "rxjs": "^7.5.5", + "rxjs": "^7.5.7", "through": "^2.3.8", "wrap-ansi": "^7.0.0" }, @@ -18207,9 +18290,9 @@ "dev": true }, "mocha": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.1.0.tgz", - "integrity": "sha512-vUF7IYxEoN7XhQpFLxQAEMtE4W91acW4B6En9l97MwE9stL1A9gusXfoHZCLVHDUJ/7V5+lbCM6yMqzo5vNymg==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", + "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", "dev": true, "requires": { "ansi-colors": "4.1.1", @@ -19055,9 +19138,9 @@ "dev": true }, "prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.2.tgz", + "integrity": "sha512-BtRV9BcncDyI2tsuS19zzhzoxD8Dh8LiCx7j7tHzrkz8GFXAexeWFdi22mjE1d16dftH2qNaytVxqiRTGlMfpw==", "dev": true }, "pretty-bytes": { @@ -19423,9 +19506,9 @@ } }, "regenerator-runtime": { - "version": "0.13.10", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz", - "integrity": "sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw==", + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", "dev": true }, "regenerator-transform": { @@ -19651,9 +19734,9 @@ "dev": true }, "selenium-webdriver": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.6.0.tgz", - "integrity": "sha512-HIH/+J+V7l/lbSRSOwyLcpjezg9CV4DLo1pBhP9aphuMlf/PJXEDwC/A/Ht2bFc1AqQppFBGvClYcuMzyO6tRw==", + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.7.1.tgz", + "integrity": "sha512-IfTM9OE8HtCKjOJwyudbAVtAHQKOJK8mu2qrXXbKyj4lqgXF+2lYW4rSZXCV6SLQRWZ+DVGkomCmFzq5orD/ZA==", "dev": true, "requires": { "jszip": "^3.10.0", @@ -19778,17 +19861,37 @@ "dev": true }, "sinon": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-11.1.2.tgz", - "integrity": "sha512-59237HChms4kg7/sXhiRcUzdSkKuydDeTiamT/jesUVHshBgL8XAmhgFo0GfK6RruMDM/iRSij1EybmMog9cJw==", + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.0.1.tgz", + "integrity": "sha512-PZXKc08f/wcA/BMRGBze2Wmw50CWPiAH3E21EOi4B49vJ616vW4DQh4fQrqsYox2aNR/N3kCqLuB0PwwOucQrg==", "dev": true, "requires": { - "@sinonjs/commons": "^1.8.3", - "@sinonjs/fake-timers": "^7.1.2", - "@sinonjs/samsam": "^6.0.2", + "@sinonjs/commons": "^2.0.0", + "@sinonjs/fake-timers": "10.0.2", + "@sinonjs/samsam": "^7.0.1", "diff": "^5.0.0", - "nise": "^5.1.0", + "nise": "^5.1.2", "supports-color": "^7.2.0" + }, + "dependencies": { + "@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", + "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^2.0.0" + } + } } }, "slash": { @@ -20016,29 +20119,19 @@ } }, "start-server-and-test": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-1.14.0.tgz", - "integrity": "sha512-on5ELuxO2K0t8EmNj9MtVlFqwBMxfWOhu4U7uZD1xccVpFlOQKR93CSe0u98iQzfNxRyaNTb/CdadbNllplTsw==", + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-1.15.2.tgz", + "integrity": "sha512-t5xJX04Hg7hqxiKHMJBz/n4zIMsE6G7hpAcerFAH+4Vh9le/LeyFcJERJM7WLiPygWF9TOg33oroJF1XOzJtYQ==", "dev": true, "requires": { + "arg": "^5.0.2", "bluebird": "3.7.2", "check-more-types": "2.24.0", - "debug": "4.3.2", + "debug": "4.3.4", "execa": "5.1.1", "lazy-ass": "1.6.0", "ps-tree": "1.2.0", - "wait-on": "6.0.0" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - } + "wait-on": "6.0.1" } }, "statuses": { @@ -20443,15 +20536,15 @@ } }, "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.7.tgz", + "integrity": "sha512-ueeb9YybpjhivjbHP2LdFDAjbS948fGEPj+ACAMs4xCMmh72OCOMQWBQKlaN4ZNQ04yfLSDLSx1tGRIoWimObQ==", "dev": true }, "typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", "dev": true }, "ua-parser-js": { @@ -20660,34 +20753,34 @@ "dev": true }, "w3c-xmlserializer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz", - "integrity": "sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", + "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", "dev": true, "requires": { "xml-name-validator": "^4.0.0" } }, "wait-on": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-6.0.0.tgz", - "integrity": "sha512-tnUJr9p5r+bEYXPUdRseolmz5XqJTTj98JgOsfBn7Oz2dxfE2g3zw1jE+Mo8lopM3j3et/Mq1yW7kKX6qw7RVw==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-6.0.1.tgz", + "integrity": "sha512-zht+KASY3usTY5u2LgaNqn/Cd8MukxLGjdcZxT2ns5QzDmTFc4XoWBgC+C/na+sMRZTuVygQoMYwdcVjHnYIVw==", "dev": true, "requires": { - "axios": "^0.21.1", - "joi": "^17.4.0", + "axios": "^0.25.0", + "joi": "^17.6.0", "lodash": "^4.17.21", "minimist": "^1.2.5", - "rxjs": "^7.1.0" + "rxjs": "^7.5.4" }, "dependencies": { "axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz", + "integrity": "sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==", "dev": true, "requires": { - "follow-redirects": "^1.14.0" + "follow-redirects": "^1.14.7" } } } diff --git a/package.json b/package.json index 9c2c689398..def8957863 100644 --- a/package.json +++ b/package.json @@ -109,27 +109,27 @@ "postbuild": "prettier --write ./locales/_template.json ./doc/rule-descriptions.md" }, "devDependencies": { - "@axe-core/webdriverjs": "^4.4.3", - "@babel/core": "^7.18.6", - "@babel/plugin-proposal-object-rest-spread": "^7.18.6", - "@babel/preset-env": "^7.18.6", - "@babel/runtime-corejs3": "^7.18.6", + "@axe-core/webdriverjs": "^4.5.2", + "@babel/core": "^7.20.12", + "@babel/plugin-proposal-object-rest-spread": "^7.20.7", + "@babel/preset-env": "^7.20.2", + "@babel/runtime-corejs3": "^7.20.7", "@deque/dot": "^1.1.5", "aria-practices": "github:w3c/aria-practices#edbf534", - "aria-query": "^5.0.0", + "aria-query": "^5.1.3", "browser-driver-manager": "1.0.4", - "chai": "~4.3.6", + "chai": "^4.3.7", "chalk": "^4.x", "chromedriver": "latest", "clone": "^2.1.2", "conventional-commits-parser": "^3.2.4", - "core-js": "^3.23.5", + "core-js": "^3.27.1", "css-selector-parser": "^1.4.1", "emoji-regex": "^10.2.1", "es6-promise": "^4.2.8", "esbuild": "^0.10.x", - "eslint": "^8.19.0", - "eslint-config-prettier": "^8.5.0", + "eslint": "^8.31.0", + "eslint-config-prettier": "^8.6.0", "eslint-plugin-mocha-no-only": "^1.1.1", "execa": "5.x", "globby": "11.x", @@ -142,38 +142,38 @@ "grunt-contrib-watch": "^1.1.0", "html-entities": "1.x", "http-server": "^14.1.1", - "husky": "^8.0.1", - "jquery": "^3.6.0", + "husky": "^8.0.3", + "jquery": "^3.6.3", "jsdoc": "^3.6.11", - "jsdom": "^20.0.0", - "karma": "^6.4.0", + "jsdom": "^21.0.0", + "karma": "^6.4.1", "karma-chai": "^0.1.0", "karma-chrome-launcher": "^3.1.1", "karma-firefox-launcher": "^2.1.2", "karma-ie-launcher": "^1.0.0", "karma-mocha": "^2.0.1", "karma-sinon": "^1.0.5", - "karma-spec-reporter": "0.0.34", - "lint-staged": "^13.0.3", + "karma-spec-reporter": "^0.0.36", + "lint-staged": "^13.1.0", "make-dir": "^3.1.0", "markdown-table": "2.x", "memoizee": "^0.4.15", "minami": "^1.2.3", - "mocha": "^10.0.0", + "mocha": "^10.2.0", "node-notifier": "^10.0.1", "npm-run-all": "^4.1.5", - "prettier": "^2.7.1", + "prettier": "^2.8.2", "proxyquire": "^2.1.3", - "revalidator": "~0.3.1", - "selenium-webdriver": "^4.5.0", - "serve-handler": "^6.1.3", - "sinon": "^11.1.2", + "revalidator": "^0.3.1", + "selenium-webdriver": "^4.7.1", + "serve-handler": "^6.1.5", + "sinon": "^15.0.1", "sri-toolbox": "^0.2.0", "standard-version": "^9.5.0", - "start-server-and-test": "^1.14.0", - "typedarray": "^0.0.6", - "typescript": "^4.7.4", - "uglify-js": "^3.16.2", + "start-server-and-test": "^1.15.2", + "typedarray": "^0.0.7", + "typescript": "^4.9.4", + "uglify-js": "^3.17.4", "wcag-act-rules": "github:w3c/wcag-act-rules#9416ea6", "weakmap-polyfill": "^2.0.4" }, From c41d278e8b86e15f5d689dbd0d61e73dbd634589 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 11 Jan 2023 19:09:24 -0500 Subject: [PATCH 05/12] ci: checkout before installing chrome (#3856) * ci: checkout before installing chrome * checkout before install --- .circleci/config.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7bd090cc0f..0929805123 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -84,8 +84,8 @@ jobs: <<: *defaults <<: *unix_box steps: - - browser-tools/install-browser-tools - checkout + - browser-tools/install-browser-tools - <<: *restore_dependency_cache_unix - run: npx browser-driver-manager install chromedriver --verbose - <<: *restore_build @@ -96,8 +96,8 @@ jobs: <<: *defaults <<: *unix_box steps: - - browser-tools/install-browser-tools - checkout + - browser-tools/install-browser-tools - <<: *restore_dependency_cache_unix - <<: *restore_build - run: npm run test -- --browsers Firefox @@ -108,8 +108,8 @@ jobs: <<: *defaults <<: *unix_box steps: - - browser-tools/install-browser-tools - checkout + - browser-tools/install-browser-tools - <<: *restore_dependency_cache_unix - run: npx browser-driver-manager install chromedriver --verbose - <<: *restore_build @@ -120,8 +120,8 @@ jobs: <<: *defaults <<: *unix_box steps: - - browser-tools/install-browser-tools - checkout + - browser-tools/install-browser-tools - <<: *restore_dependency_cache_unix - run: npx browser-driver-manager install chromedriver --verbose - <<: *restore_build @@ -132,8 +132,8 @@ jobs: <<: *defaults <<: *unix_box steps: - - browser-tools/install-browser-tools - checkout + - browser-tools/install-browser-tools - <<: *restore_dependency_cache_unix - run: npx browser-driver-manager install chromedriver --verbose - <<: *restore_build @@ -144,8 +144,8 @@ jobs: <<: *defaults <<: *unix_box steps: - - browser-tools/install-browser-tools - checkout + - browser-tools/install-browser-tools - <<: *restore_dependency_cache_unix - run: npx browser-driver-manager install chromedriver --verbose - <<: *restore_build @@ -156,8 +156,8 @@ jobs: <<: *defaults <<: *unix_box steps: - - browser-tools/install-browser-tools - checkout + - browser-tools/install-browser-tools - <<: *restore_dependency_cache_unix - run: npx browser-driver-manager install chromedriver --verbose - <<: *restore_build From ec4c9df9d06451839eed92e477a1cf5ea4e55685 Mon Sep 17 00:00:00 2001 From: Steven Lambert <2433219+straker@users.noreply.github.com> Date: Mon, 16 Jan 2023 08:42:15 -0700 Subject: [PATCH 06/12] test: refactor is-focusable tests (#3855) * tests: refactor is-focusable tests * negative tabindex * Update test/commons/dom/is-natively-focusable.js Co-authored-by: Wilco Fiers Co-authored-by: Wilco Fiers --- lib/commons/dom/index.js | 1 + test/commons/dom/focus-disabled.js | 66 ++ test/commons/dom/inserted-into-focus-order.js | 211 +++++ test/commons/dom/is-focusable.js | 772 ++++-------------- test/commons/dom/is-natively-focusable.js | 285 +++++++ 5 files changed, 704 insertions(+), 631 deletions(-) create mode 100644 test/commons/dom/focus-disabled.js create mode 100644 test/commons/dom/inserted-into-focus-order.js create mode 100644 test/commons/dom/is-natively-focusable.js diff --git a/lib/commons/dom/index.js b/lib/commons/dom/index.js index 92daa75184..20a972cb47 100644 --- a/lib/commons/dom/index.js +++ b/lib/commons/dom/index.js @@ -7,6 +7,7 @@ export { default as findElmsInContext } from './find-elms-in-context'; export { default as findUpVirtual } from './find-up-virtual'; export { default as findUp } from './find-up'; export { default as findNearbyElms } from './find-nearby-elms'; +export { default as focusDisabled } from './focus-disabled'; export { default as getComposedParent } from './get-composed-parent'; export { default as getElementByReference } from './get-element-by-reference'; export { default as getElementCoordinates } from './get-element-coordinates'; diff --git a/test/commons/dom/focus-disabled.js b/test/commons/dom/focus-disabled.js new file mode 100644 index 0000000000..2f8a242dc4 --- /dev/null +++ b/test/commons/dom/focus-disabled.js @@ -0,0 +1,66 @@ +describe('dom.focus-disabled', () => { + const focusDisabled = axe.commons.dom.focusDisabled; + const { queryFixture, queryShadowFixture } = axe.testUtils; + + it('returns false for non-disabled element', () => { + const vNode = queryFixture(''); + + assert.isFalse(focusDisabled(vNode)); + }); + + it('returns true for disabled element which is allowed to be disabled', () => { + const vNode = queryFixture(''); + + assert.isTrue(focusDisabled(vNode)); + }); + + it('returns false for disabled element which is not allowed to be disabled', () => { + const vNode = queryFixture(''); + + assert.isFalse(focusDisabled(vNode)); + }); + + it('returns true if parent fieldset is disabled', () => { + const vNode = queryFixture( + '
' + ); + + assert.isTrue(focusDisabled(vNode)); + }); + + it('returns false if element is inside a legend inside a disabled fieldset', () => { + const vNode = queryFixture( + '
' + ); + + assert.isFalse(focusDisabled(vNode)); + }); + + it('returns false for disabled fieldset outside shadow tree', () => { + const vNode = queryShadowFixture( + '
', + '' + ); + + assert.isFalse(focusDisabled(vNode)); + }); + + it('returns true if element is hidden for everyone', () => { + const vNode = queryFixture(''); + + assert.isTrue(focusDisabled(vNode)); + }); + + describe('SerialVirtualNode', () => { + it('returns false if element is hidden for everyone', () => { + const vNode = new axe.SerialVirtualNode({ + nodeName: 'button', + attributes: { + hidden: true + } + }); + + assert.isFalse(focusDisabled(vNode)); + }); + }); +}); diff --git a/test/commons/dom/inserted-into-focus-order.js b/test/commons/dom/inserted-into-focus-order.js new file mode 100644 index 0000000000..e3e06186fb --- /dev/null +++ b/test/commons/dom/inserted-into-focus-order.js @@ -0,0 +1,211 @@ +describe('dom.insertedIntoFocusOrder', () => { + const fixture = document.getElementById('fixture'); + const { fixtureSetup } = axe.testUtils; + const insertedIntoFocusOrder = axe.commons.dom.insertedIntoFocusOrder; + + function hideByClipping(el) { + el.style.cssText = + 'position: absolute !important;' + + ' clip: rect(0px 0px 0px 0px); /* IE6, IE7 */' + + ' clip: rect(0px, 0px, 0px, 0px);'; + } + + function hideByMovingOffScreen(el) { + el.style.cssText = + 'position:absolute;' + + ' left:-10000px;' + + ' top:auto;' + + ' width:1px;' + + ' height:1px;' + + ' overflow:hidden;'; + } + + it('should return true for span with tabindex 0', () => { + fixtureSetup(''); + const node = fixture.querySelector('#spanTabindex0'); + + assert.isTrue(insertedIntoFocusOrder(node)); + }); + + it('should return true for clipped span with tabindex 0', () => { + fixtureSetup(''); + const node = fixture.querySelector('#clippedSpanTabindex0'); + hideByClipping(node); + + assert.isTrue(insertedIntoFocusOrder(node)); + }); + + it('should return true for off screen span with tabindex 0', () => { + fixtureSetup(''); + const node = fixture.querySelector('#offScreenSpanTabindex0'); + hideByMovingOffScreen(node); + + assert.isTrue(insertedIntoFocusOrder(node)); + }); + + it('should return false for span with negative tabindex', () => { + fixtureSetup(''); + const node = fixture.querySelector('#spanNegativeTabindex'); + + assert.isFalse(insertedIntoFocusOrder(node)); + }); + + it('should return false for native button with tabindex 0', () => { + fixtureSetup(''); + const node = fixture.querySelector('#nativeButtonTabindex0'); + + assert.isFalse(insertedIntoFocusOrder(node)); + }); + + it('should return false for native button with tabindex implicitly 0', () => { + fixtureSetup(''); + const node = fixture.querySelector('#nativeButtonTabindexImplicitly0'); + + assert.isFalse(insertedIntoFocusOrder(node)); + }); + + it('should return false for anchor with href and positive tabindex', () => { + fixtureSetup( + '' + ); + const node = fixture.querySelector('#anchorWithHrefAndPositiveTabindex'); + + assert.isFalse(insertedIntoFocusOrder(node)); + }); + + it('should return false for input with tabindex 0', () => { + fixtureSetup(''); + const node = fixture.querySelector('#inputWithTabindex0'); + + assert.isFalse(insertedIntoFocusOrder(node)); + }); + + it('should return false for off screen native button with tabindex 0', () => { + fixtureSetup( + '' + ); + const node = fixture.querySelector('#offScreenNativeButtonTabindex0'); + hideByMovingOffScreen(node); + + assert.isFalse(insertedIntoFocusOrder(node)); + }); + + it('should return false for off screen anchor with href and tabindex 1', () => { + fixtureSetup( + '' + ); + const node = fixture.querySelector('#offScreenAnchorWithHrefTabindex1'); + hideByMovingOffScreen(node); + + assert.isFalse(insertedIntoFocusOrder(node)); + }); + + it('should return false for off screen input with tabindex 0', () => { + fixtureSetup(''); + const node = fixture.querySelector('#offScreenInputWithTabindex0'); + hideByMovingOffScreen(node); + + assert.isFalse(insertedIntoFocusOrder(node)); + }); + + it('should return false for clipped native button with tabindex 0', () => { + fixtureSetup( + '' + ); + const node = fixture.querySelector('#clippedNativeButtonTabindex0'); + hideByClipping(node); + + assert.isFalse(insertedIntoFocusOrder(node)); + }); + + it('should return false for display none native button with tabindex 0', () => { + fixtureSetup( + '' + ); + const node = fixture.querySelector('#displayNoneNativeButtonTabindex0'); + + assert.isFalse(insertedIntoFocusOrder(node)); + }); + + it('should return false for clipped anchor with href and tabindex 1', () => { + fixtureSetup( + '' + ); + const node = fixture.querySelector('#clippedAnchorWithHrefTabindex1'); + hideByClipping(node); + + assert.isFalse(insertedIntoFocusOrder(node)); + }); + + it('should return false for display none anchor with href and tabindex 1', () => { + fixtureSetup( + '' + ); + const node = fixture.querySelector('#displayNoneAnchorWithHrefTabindex1'); + + assert.isFalse(insertedIntoFocusOrder(node)); + }); + + it('should return false for clipped input with tabindex 0', () => { + fixtureSetup(''); + const node = fixture.querySelector('#clippedInputWithTabindex0'); + hideByClipping(node); + + assert.isFalse(insertedIntoFocusOrder(node)); + }); + + it('should return false for display none input with tabindex 0', () => { + fixtureSetup(''); + const node = fixture.querySelector('#displayNoneInputWithTabindex0'); + + assert.isFalse(insertedIntoFocusOrder(node)); + }); + + it('should return false for hidden native button with tabindex 0', () => { + fixtureSetup( + '' + ); + const node = fixture.querySelector('#hiddenNativeButtonTabindex0'); + + assert.isFalse(insertedIntoFocusOrder(node)); + }); + + it('should return false for hidden anchor with href and tabindex 1', () => { + fixtureSetup( + '' + ); + const node = fixture.querySelector('#hiddenAnchorWithHrefTabindex1'); + + assert.isFalse(insertedIntoFocusOrder(node)); + }); + + it('should return false for hidden input with tabindex 0', () => { + fixtureSetup(''); + const node = fixture.querySelector('#hiddenInputWithTabindex0'); + + assert.isFalse(insertedIntoFocusOrder(node)); + }); + + it('should return false for disabled native button with tabindex 0', () => { + fixtureSetup( + '' + ); + const node = fixture.querySelector('#disabledNativeButtonTabindex0'); + + assert.isFalse(insertedIntoFocusOrder(node)); + }); + + it('should return false for disabled input with tabindex 0', () => { + fixtureSetup(''); + const node = fixture.querySelector('#disabledInputTabindex0'); + + assert.isFalse(insertedIntoFocusOrder(node)); + }); + + it('should return false for an invalid tabindex', () => { + fixtureSetup(''); + const node = fixture.querySelector('#spanTabindexInvalid'); + + assert.isFalse(insertedIntoFocusOrder(node)); + }); +}); diff --git a/test/commons/dom/is-focusable.js b/test/commons/dom/is-focusable.js index 6787f68fe1..34bf27d3f9 100644 --- a/test/commons/dom/is-focusable.js +++ b/test/commons/dom/is-focusable.js @@ -1,665 +1,175 @@ -describe('is-focusable', function () { - function hideByClipping(el) { - el.style.cssText = - 'position: absolute !important;' + - ' clip: rect(0px 0px 0px 0px); /* IE6, IE7 */' + - ' clip: rect(0px, 0px, 0px, 0px);'; - } - - function hideByMovingOffScreen(el) { - el.style.cssText = - 'position:absolute;' + - ' left:-10000px;' + - ' top:auto;' + - ' width:1px;' + - ' height:1px;' + - ' overflow:hidden;'; - } - - var fixtureSetup = axe.testUtils.fixtureSetup; - var flatTreeSetup = axe.testUtils.flatTreeSetup; - - describe('dom.isFocusable', function () { - 'use strict'; - - var fixture = document.getElementById('fixture'); - - afterEach(function () { - document.getElementById('fixture').innerHTML = ''; - }); - - it('should return true for visible, enabled textareas', function () { - fixture.innerHTML = ''; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isTrue(axe.commons.dom.isFocusable(el)); - }); - - it('should return true for visible, enabled selects', function () { - fixture.innerHTML = ''; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isTrue(axe.commons.dom.isFocusable(el)); - }); - - it('should return true for visible, enabled buttons', function () { - fixture.innerHTML = ''; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isTrue(axe.commons.dom.isFocusable(el)); - }); - - it('should return true for visible, enabled, non-hidden inputs', function () { - fixture.innerHTML = ''; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isTrue(axe.commons.dom.isFocusable(el)); - }); - - it('should return false for non-element nodes', function () { - fixture.innerHTML = 'Hello World'; - flatTreeSetup(fixture); - var el = document.getElementById('target').childNodes[0]; - - assert.isFalse(axe.commons.dom.isFocusable(el)); - }); - - it('should return false for disabled elements', function () { - fixture.innerHTML = ''; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isFalse(axe.commons.dom.isFocusable(el)); - }); - - it('should return false for hidden inputs', function () { - fixture.innerHTML = ''; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isFalse(axe.commons.dom.isFocusable(el)); - }); - - it('should return false for hidden inputs with tabindex', function () { - fixture.innerHTML = ''; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isFalse(axe.commons.dom.isFocusable(el)); - }); - - it('should return false for hidden buttons with tabindex', function () { - fixture.innerHTML = - ''; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isFalse(axe.commons.dom.isFocusable(el)); - }); - - it('should return false for disabled buttons with tabindex', function () { - fixture.innerHTML = ''; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isFalse(axe.commons.dom.isFocusable(el)); - }); - - it('should return false for non-visible elements', function () { - fixture.innerHTML = - ''; - var el = document.getElementById('target'); - flatTreeSetup(fixture); +describe('dom.isFocusable', () => { + const flatTreeSetup = axe.testUtils.flatTreeSetup; + const fixture = document.getElementById('fixture'); - assert.isFalse(axe.commons.dom.isFocusable(el)); - }); + it('should return true for visible, enabled textareas', () => { + fixture.innerHTML = ''; + const el = document.getElementById('target'); + flatTreeSetup(fixture); - it('should return true for an anchor with an href', function () { - fixture.innerHTML = ''; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isTrue(axe.commons.dom.isFocusable(el)); - }); - - it('should return false for an anchor with no href', function () { - fixture.innerHTML = ''; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isFalse(axe.commons.dom.isFocusable(el)); - }); - - it('should return true for a div with a tabindex with spaces', function () { - fixture.innerHTML = '
'; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isTrue(axe.commons.dom.isFocusable(el)); - }); - - it('should return true for a div with a tabindex', function () { - fixture.innerHTML = '
'; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isTrue(axe.commons.dom.isFocusable(el)); - }); - - it('should return false for a div with a non-numeric tabindex', function () { - fixture.innerHTML = '
'; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isFalse(axe.commons.dom.isFocusable(el)); - }); - - it('should return true for a summary element', function () { - fixture.innerHTML = - '
Summary

Detail

'; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isTrue(axe.commons.dom.isFocusable(el)); - }); - - it('should return true for a details element without a summary element', function () { - fixture.innerHTML = '

Detail

'; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isTrue(axe.commons.dom.isFocusable(el)); - }); - - it('should return false for a details element with a summary element', function () { - fixture.innerHTML = - '
Summary

Detail

'; - var el = document.getElementById('target'); - flatTreeSetup(fixture); + assert.isTrue(axe.commons.dom.isFocusable(el)); + }); + + it('should return true for visible, enabled selects', () => { + fixture.innerHTML = ''; + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isTrue(axe.commons.dom.isFocusable(el)); + }); + + it('should return true for visible, enabled buttons', () => { + fixture.innerHTML = ''; + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isTrue(axe.commons.dom.isFocusable(el)); + }); + + it('should return true for visible, enabled, non-hidden inputs', () => { + fixture.innerHTML = ''; + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isTrue(axe.commons.dom.isFocusable(el)); + }); + + it('should return false for non-element nodes', () => { + fixture.innerHTML = 'Hello World'; + flatTreeSetup(fixture); + const el = document.getElementById('target').childNodes[0]; + + assert.isFalse(axe.commons.dom.isFocusable(el)); + }); + + it('should return false for disabled elements', () => { + fixture.innerHTML = ''; + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isFalse(axe.commons.dom.isFocusable(el)); + }); - assert.isFalse(axe.commons.dom.isFocusable(el)); - }); - - it('should return false for a div with no tabindex', function () { - fixture.innerHTML = '
'; - var el = document.getElementById('target'); - flatTreeSetup(fixture); + it('should return false for hidden inputs', () => { + fixture.innerHTML = ''; + const el = document.getElementById('target'); + flatTreeSetup(fixture); - assert.isFalse(axe.commons.dom.isFocusable(el)); - }); + assert.isFalse(axe.commons.dom.isFocusable(el)); }); - describe('dom.isNativelyFocusable', function () { - 'use strict'; + it('should return false for hidden inputs with tabindex', () => { + fixture.innerHTML = ''; + const el = document.getElementById('target'); + flatTreeSetup(fixture); - var fixture = document.getElementById('fixture'); + assert.isFalse(axe.commons.dom.isFocusable(el)); + }); - afterEach(function () { - document.getElementById('fixture').innerHTML = ''; - }); + it('should return false for hidden buttons with tabindex', () => { + fixture.innerHTML = + ''; + const el = document.getElementById('target'); + flatTreeSetup(fixture); - it('should return true for buttons with redundant tabindex', function () { - fixture.innerHTML = ''; - var el = document.getElementById('target'); - flatTreeSetup(fixture); + assert.isFalse(axe.commons.dom.isFocusable(el)); + }); - assert.isTrue(axe.commons.dom.isNativelyFocusable(el)); - }); + it('should return false for disabled buttons with tabindex', () => { + fixture.innerHTML = ''; + const el = document.getElementById('target'); + flatTreeSetup(fixture); - it('should return true for buttons with tabindex -1', function () { - fixture.innerHTML = ''; - var el = document.getElementById('target'); - flatTreeSetup(fixture); + assert.isFalse(axe.commons.dom.isFocusable(el)); + }); - assert.isTrue(axe.commons.dom.isNativelyFocusable(el)); - }); + it('should return false for non-visible elements', () => { + fixture.innerHTML = ''; + const el = document.getElementById('target'); + flatTreeSetup(fixture); - it('should return true for visible, enabled textareas', function () { - fixture.innerHTML = ''; - var el = document.getElementById('target'); - flatTreeSetup(fixture); + assert.isFalse(axe.commons.dom.isFocusable(el)); + }); - assert.isTrue(axe.commons.dom.isNativelyFocusable(el)); - }); + it('should return true for an anchor with an href', () => { + fixture.innerHTML = ''; + const el = document.getElementById('target'); + flatTreeSetup(fixture); - it('should return true for visible, enabled selects', function () { - fixture.innerHTML = ''; - var el = document.getElementById('target'); - flatTreeSetup(fixture); + assert.isTrue(axe.commons.dom.isFocusable(el)); + }); - assert.isTrue(axe.commons.dom.isNativelyFocusable(el)); - }); - - it('should return true for visible, enabled buttons', function () { - fixture.innerHTML = ''; - var el = document.getElementById('target'); - flatTreeSetup(fixture); + it('should return false for an anchor with no href', () => { + fixture.innerHTML = ''; + const el = document.getElementById('target'); + flatTreeSetup(fixture); - assert.isTrue(axe.commons.dom.isNativelyFocusable(el)); - }); - - it('should return true for visible, enabled, non-hidden inputs', function () { - fixture.innerHTML = ''; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isTrue(axe.commons.dom.isNativelyFocusable(el)); - }); - - it('should return false for disabled elements', function () { - fixture.innerHTML = ''; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isFalse(axe.commons.dom.isNativelyFocusable(el)); - }); - - it('should return false for hidden inputs', function () { - fixture.innerHTML = ''; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isFalse(axe.commons.dom.isNativelyFocusable(el)); - }); - - it('should return false for elements hidden with display:none', function () { - fixture.innerHTML = - ''; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isFalse(axe.commons.dom.isNativelyFocusable(el)); - }); - - it('should return false for elements hidden with visibility:hidden', function () { - fixture.innerHTML = - ''; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isFalse(axe.commons.dom.isNativelyFocusable(el)); - }); - - it('should return false for elements collapsed with visibility:collapse', function () { - fixture.innerHTML = - ''; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isFalse(axe.commons.dom.isNativelyFocusable(el)); - }); - - it('should return true for clipped elements', function () { - fixture.innerHTML = ''; - var el = document.getElementById('target'); - hideByClipping(el); - flatTreeSetup(fixture); - - assert.isTrue(axe.commons.dom.isNativelyFocusable(el)); - }); - - it('should return true for elements positioned off screen', function () { - fixture.innerHTML = ''; - var el = document.getElementById('target'); - hideByMovingOffScreen(el); - flatTreeSetup(fixture); - - assert.isTrue(axe.commons.dom.isNativelyFocusable(el)); - }); - - it('should return false for elements hidden with display:none on an ancestor', function () { - fixture.innerHTML = - ''; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isFalse(axe.commons.dom.isNativelyFocusable(el)); - }); - - it('should return false for elements hidden with visibility:hidden on an ancestor', function () { - fixture.innerHTML = - ''; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isFalse(axe.commons.dom.isNativelyFocusable(el)); - }); - - it('should return false for elements collapsed with visibility:collapse on an ancestor', function () { - fixture.innerHTML = - '
'; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isFalse(axe.commons.dom.isNativelyFocusable(el)); - }); - - it('should return true for elements with a clipped ancestor', function () { - fixture.innerHTML = - '
'; - hideByClipping(document.getElementById('parent')); - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isTrue(axe.commons.dom.isNativelyFocusable(el)); - }); - - it('should return true for elements off-screened by an ancestor', function () { - fixture.innerHTML = - '
'; - hideByMovingOffScreen(document.getElementById('parent')); - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isTrue(axe.commons.dom.isNativelyFocusable(el)); - }); - - it('should return false for hidden inputs with tabindex', function () { - fixture.innerHTML = ''; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isFalse(axe.commons.dom.isFocusable(el)); - }); - - it('should return false for disabled inputs with tabindex', function () { - fixture.innerHTML = ''; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isFalse(axe.commons.dom.isFocusable(el)); - }); - - it('should return false for hidden buttons with tabindex', function () { - fixture.innerHTML = - ''; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isFalse(axe.commons.dom.isFocusable(el)); - }); - - it('should return false for disabled buttons with tabindex', function () { - fixture.innerHTML = ''; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isFalse(axe.commons.dom.isFocusable(el)); - }); - - it('should return true for an anchor with an href', function () { - fixture.innerHTML = ''; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isTrue(axe.commons.dom.isNativelyFocusable(el)); - }); - - it('should return false for an anchor with no href', function () { - fixture.innerHTML = ''; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isFalse(axe.commons.dom.isNativelyFocusable(el)); - }); - - it('should return false for a div with a tabindex with spaces', function () { - fixture.innerHTML = '
'; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isFalse(axe.commons.dom.isNativelyFocusable(el)); - }); - - it('should return false for a div with a tabindex', function () { - fixture.innerHTML = '
'; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isFalse(axe.commons.dom.isNativelyFocusable(el)); - }); - - it('should return false for a div with a non-numeric tabindex', function () { - fixture.innerHTML = '
'; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isFalse(axe.commons.dom.isNativelyFocusable(el)); - }); - - it('should return true for a summary element', function () { - fixture.innerHTML = - '
Summary

Detail

'; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isTrue(axe.commons.dom.isFocusable(el)); - }); - - it('should return true for a details element without a summary element', function () { - fixture.innerHTML = '

Detail

'; - var el = document.getElementById('target'); - flatTreeSetup(fixture); - - assert.isTrue(axe.commons.dom.isFocusable(el)); - }); - - it('should return false for a details element with a summary element', function () { - fixture.innerHTML = - '
Summary

Detail

'; - var el = document.getElementById('target'); - flatTreeSetup(fixture); + assert.isFalse(axe.commons.dom.isFocusable(el)); + }); - assert.isFalse(axe.commons.dom.isFocusable(el)); - }); - - it('should return false for a div with no tabindex', function () { - fixture.innerHTML = '
'; - var el = document.getElementById('target'); - flatTreeSetup(fixture); + it('should return true for a div with a tabindex with spaces', () => { + fixture.innerHTML = '
'; + const el = document.getElementById('target'); + flatTreeSetup(fixture); - assert.isFalse(axe.commons.dom.isNativelyFocusable(el)); - }); + assert.isTrue(axe.commons.dom.isFocusable(el)); }); - describe('dom.insertedIntoFocusOrder', function () { - var fixture = document.getElementById('fixture'); + it('should return true for a div with a tabindex', () => { + fixture.innerHTML = '
'; + const el = document.getElementById('target'); + flatTreeSetup(fixture); - beforeEach(function () { - fixture.innerHTML = ''; - }); + assert.isTrue(axe.commons.dom.isFocusable(el)); + }); - it('should return true for span with tabindex 0', function () { - fixtureSetup(''); - var node = fixture.querySelector('#spanTabindex0'); + it('should return true for a div with a negative tabindex', () => { + fixture.innerHTML = '
'; + const el = document.getElementById('target'); + flatTreeSetup(fixture); - assert.isTrue(axe.commons.dom.insertedIntoFocusOrder(node)); - }); + assert.isTrue(axe.commons.dom.isFocusable(el)); + }); - it('should return true for clipped span with tabindex 0', function () { - fixtureSetup(''); - var node = fixture.querySelector('#clippedSpanTabindex0'); - hideByClipping(node); - - assert.isTrue(axe.commons.dom.insertedIntoFocusOrder(node)); - }); + it('should return false for a div with a non-numeric tabindex', () => { + fixture.innerHTML = '
'; + const el = document.getElementById('target'); + flatTreeSetup(fixture); - it('should return true for off screen span with tabindex 0', function () { - fixtureSetup(''); - var node = fixture.querySelector('#offScreenSpanTabindex0'); - hideByMovingOffScreen(node); - - assert.isTrue(axe.commons.dom.insertedIntoFocusOrder(node)); - }); + assert.isFalse(axe.commons.dom.isFocusable(el)); + }); - it('should return false for span with negative tabindex', function () { - fixtureSetup(''); - var node = fixture.querySelector('#spanNegativeTabindex'); + it('should return true for a summary element', () => { + fixture.innerHTML = + '
Summary

Detail

'; + const el = document.getElementById('target'); + flatTreeSetup(fixture); - assert.isFalse(axe.commons.dom.insertedIntoFocusOrder(node)); - }); - - it('should return false for native button with tabindex 0', function () { - fixtureSetup(''); - var node = fixture.querySelector('#nativeButtonTabindex0'); + assert.isTrue(axe.commons.dom.isFocusable(el)); + }); - assert.isFalse(axe.commons.dom.insertedIntoFocusOrder(node)); - }); - - it('should return false for native button with tabindex implicitly 0', function () { - fixtureSetup(''); - var node = fixture.querySelector('#nativeButtonTabindexImplicitly0'); + it('should return true for a details element without a summary element', () => { + fixture.innerHTML = '

Detail

'; + const el = document.getElementById('target'); + flatTreeSetup(fixture); - assert.isFalse(axe.commons.dom.insertedIntoFocusOrder(node)); - }); - - it('should return false for anchor with href and positive tabindex', function () { - fixtureSetup( - '' - ); - var node = fixture.querySelector('#anchorWithHrefAndPositiveTabindex'); + assert.isTrue(axe.commons.dom.isFocusable(el)); + }); + + it('should return false for a details element with a summary element', () => { + fixture.innerHTML = + '
Summary

Detail

'; + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isFalse(axe.commons.dom.isFocusable(el)); + }); - assert.isFalse(axe.commons.dom.insertedIntoFocusOrder(node)); - }); - - it('should return false for input with tabindex 0', function () { - fixtureSetup(''); - var node = fixture.querySelector('#inputWithTabindex0'); - - assert.isFalse(axe.commons.dom.insertedIntoFocusOrder(node)); - }); - - it('should return false for off screen native button with tabindex 0', function () { - fixtureSetup( - '' - ); - var node = fixture.querySelector('#offScreenNativeButtonTabindex0'); - hideByMovingOffScreen(node); + it('should return false for a div with no tabindex', () => { + fixture.innerHTML = '
'; + const el = document.getElementById('target'); + flatTreeSetup(fixture); - assert.isFalse(axe.commons.dom.insertedIntoFocusOrder(node)); - }); - - it('should return false for off screen anchor with href and tabindex 1', function () { - fixtureSetup( - '' - ); - var node = fixture.querySelector('#offScreenAnchorWithHrefTabindex1'); - hideByMovingOffScreen(node); - - assert.isFalse(axe.commons.dom.insertedIntoFocusOrder(node)); - }); - - it('should return false for off screen input with tabindex 0', function () { - fixtureSetup(''); - var node = fixture.querySelector('#offScreenInputWithTabindex0'); - hideByMovingOffScreen(node); - - assert.isFalse(axe.commons.dom.insertedIntoFocusOrder(node)); - }); - - it('should return false for clipped native button with tabindex 0', function () { - fixtureSetup( - '' - ); - var node = fixture.querySelector('#clippedNativeButtonTabindex0'); - hideByClipping(node); - - assert.isFalse(axe.commons.dom.insertedIntoFocusOrder(node)); - }); - - it('should return false for display none native button with tabindex 0', function () { - fixtureSetup( - '' - ); - var node = fixture.querySelector('#displayNoneNativeButtonTabindex0'); - - assert.isFalse(axe.commons.dom.insertedIntoFocusOrder(node)); - }); - - it('should return false for clipped anchor with href and tabindex 1', function () { - fixtureSetup( - '' - ); - var node = fixture.querySelector('#clippedAnchorWithHrefTabindex1'); - hideByClipping(node); - - assert.isFalse(axe.commons.dom.insertedIntoFocusOrder(node)); - }); - - it('should return false for display none anchor with href and tabindex 1', function () { - fixtureSetup( - '' - ); - var node = fixture.querySelector('#displayNoneAnchorWithHrefTabindex1'); - - assert.isFalse(axe.commons.dom.insertedIntoFocusOrder(node)); - }); - - it('should return false for clipped input with tabindex 0', function () { - fixtureSetup(''); - var node = fixture.querySelector('#clippedInputWithTabindex0'); - hideByClipping(node); - - assert.isFalse(axe.commons.dom.insertedIntoFocusOrder(node)); - }); - - it('should return false for display none input with tabindex 0', function () { - fixtureSetup(''); - var node = fixture.querySelector('#displayNoneInputWithTabindex0'); - - assert.isFalse(axe.commons.dom.insertedIntoFocusOrder(node)); - }); - - it('should return false for hidden native button with tabindex 0', function () { - fixtureSetup( - '' - ); - var node = fixture.querySelector('#hiddenNativeButtonTabindex0'); - - assert.isFalse(axe.commons.dom.insertedIntoFocusOrder(node)); - }); - - it('should return false for hidden anchor with href and tabindex 1', function () { - fixtureSetup( - '' - ); - var node = fixture.querySelector('#hiddenAnchorWithHrefTabindex1'); - - assert.isFalse(axe.commons.dom.insertedIntoFocusOrder(node)); - }); - - it('should return false for hidden input with tabindex 0', function () { - fixtureSetup(''); - var node = fixture.querySelector('#hiddenInputWithTabindex0'); - - assert.isFalse(axe.commons.dom.insertedIntoFocusOrder(node)); - }); - - it('should return false for disabled native button with tabindex 0', function () { - fixtureSetup( - '' - ); - var node = fixture.querySelector('#disabledNativeButtonTabindex0'); - - assert.isFalse(axe.commons.dom.insertedIntoFocusOrder(node)); - }); - - it('should return false for disabled input with tabindex 0', function () { - fixtureSetup(''); - var node = fixture.querySelector('#disabledInputTabindex0'); - - assert.isFalse(axe.commons.dom.insertedIntoFocusOrder(node)); - }); - - it('should return false for an invalid tabindex', function () { - fixtureSetup(''); - var node = fixture.querySelector('#spanTabindexInvalid'); - - assert.isFalse(axe.commons.dom.insertedIntoFocusOrder(node)); - }); + assert.isFalse(axe.commons.dom.isFocusable(el)); }); }); diff --git a/test/commons/dom/is-natively-focusable.js b/test/commons/dom/is-natively-focusable.js new file mode 100644 index 0000000000..128b98c999 --- /dev/null +++ b/test/commons/dom/is-natively-focusable.js @@ -0,0 +1,285 @@ +describe('dom.isNativelyFocusable', () => { + const fixture = document.getElementById('fixture'); + const isNativelyFocusable = axe.commons.dom.isNativelyFocusable; + const { flatTreeSetup } = axe.testUtils; + + function hideByClipping(el) { + el.style.cssText = + 'position: absolute !important;' + + ' clip: rect(0px 0px 0px 0px); /* IE6, IE7 */' + + ' clip: rect(0px, 0px, 0px, 0px);'; + } + + function hideByMovingOffScreen(el) { + el.style.cssText = + 'position:absolute;' + + ' left:-10000px;' + + ' top:auto;' + + ' width:1px;' + + ' height:1px;' + + ' overflow:hidden;'; + } + + it('should return true for buttons with redundant tabindex', () => { + fixture.innerHTML = ''; + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isTrue(isNativelyFocusable(el)); + }); + + it('should return true for buttons with tabindex -1', () => { + fixture.innerHTML = ''; + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isTrue(isNativelyFocusable(el)); + }); + + it('should return true for visible, enabled textareas', () => { + fixture.innerHTML = ''; + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isTrue(isNativelyFocusable(el)); + }); + + it('should return true for visible, enabled selects', () => { + fixture.innerHTML = ''; + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isTrue(isNativelyFocusable(el)); + }); + + it('should return true for visible, enabled buttons', () => { + fixture.innerHTML = ''; + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isTrue(isNativelyFocusable(el)); + }); + + it('should return true for visible, enabled, non-hidden inputs', () => { + fixture.innerHTML = ''; + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isTrue(isNativelyFocusable(el)); + }); + + it('should return false for disabled elements', () => { + fixture.innerHTML = ''; + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isFalse(isNativelyFocusable(el)); + }); + + it('should return false for hidden inputs', () => { + fixture.innerHTML = ''; + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isFalse(isNativelyFocusable(el)); + }); + + it('should return false for elements hidden with display:none', () => { + fixture.innerHTML = + ''; + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isFalse(isNativelyFocusable(el)); + }); + + it('should return false for elements hidden with visibility:hidden', () => { + fixture.innerHTML = + ''; + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isFalse(isNativelyFocusable(el)); + }); + + it('should return false for elements collapsed with visibility:collapse', () => { + fixture.innerHTML = + ''; + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isFalse(isNativelyFocusable(el)); + }); + + it('should return true for clipped elements', () => { + fixture.innerHTML = ''; + const el = document.getElementById('target'); + hideByClipping(el); + flatTreeSetup(fixture); + + assert.isTrue(isNativelyFocusable(el)); + }); + + it('should return true for elements positioned off screen', () => { + fixture.innerHTML = ''; + const el = document.getElementById('target'); + hideByMovingOffScreen(el); + flatTreeSetup(fixture); + + assert.isTrue(isNativelyFocusable(el)); + }); + + it('should return false for elements hidden with display:none on an ancestor', () => { + fixture.innerHTML = + ''; + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isFalse(isNativelyFocusable(el)); + }); + + it('should return false for elements hidden with visibility:hidden on an ancestor', () => { + fixture.innerHTML = + ''; + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isFalse(isNativelyFocusable(el)); + }); + + it('should return false for elements collapsed with visibility:collapse on an ancestor', () => { + fixture.innerHTML = + '
'; + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isFalse(isNativelyFocusable(el)); + }); + + it('should return true for elements with a clipped ancestor', () => { + fixture.innerHTML = + '
'; + hideByClipping(document.getElementById('parent')); + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isTrue(isNativelyFocusable(el)); + }); + + it('should return true for elements off-screened by an ancestor', () => { + fixture.innerHTML = + '
'; + hideByMovingOffScreen(document.getElementById('parent')); + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isTrue(isNativelyFocusable(el)); + }); + + it('should return false for hidden inputs with tabindex', () => { + fixture.innerHTML = ''; + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isFalse(axe.commons.dom.isFocusable(el)); + }); + + it('should return false for disabled inputs with tabindex', () => { + fixture.innerHTML = ''; + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isFalse(axe.commons.dom.isFocusable(el)); + }); + + it('should return false for hidden buttons with tabindex', () => { + fixture.innerHTML = + ''; + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isFalse(axe.commons.dom.isFocusable(el)); + }); + + it('should return false for disabled buttons with tabindex', () => { + fixture.innerHTML = ''; + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isFalse(axe.commons.dom.isFocusable(el)); + }); + + it('should return true for an anchor with an href', () => { + fixture.innerHTML = ''; + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isTrue(isNativelyFocusable(el)); + }); + + it('should return false for an anchor with no href', () => { + fixture.innerHTML = ''; + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isFalse(isNativelyFocusable(el)); + }); + + it('should return false for a div with a tabindex with spaces', () => { + fixture.innerHTML = '
'; + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isFalse(isNativelyFocusable(el)); + }); + + it('should return false for a div with a tabindex', () => { + fixture.innerHTML = '
'; + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isFalse(isNativelyFocusable(el)); + }); + + it('should return false for a div with a non-numeric tabindex', () => { + fixture.innerHTML = '
'; + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isFalse(isNativelyFocusable(el)); + }); + + it('should return true for a summary element', () => { + fixture.innerHTML = + '
Summary

Detail

'; + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isTrue(axe.commons.dom.isFocusable(el)); + }); + + it('should return true for a details element without a summary element', () => { + fixture.innerHTML = '

Detail

'; + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isTrue(axe.commons.dom.isFocusable(el)); + }); + + it('should return false for a details element with a summary element', () => { + fixture.innerHTML = + '
Summary

Detail

'; + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isFalse(axe.commons.dom.isFocusable(el)); + }); + + it('should return false for a div with no tabindex', () => { + fixture.innerHTML = '
'; + const el = document.getElementById('target'); + flatTreeSetup(fixture); + + assert.isFalse(isNativelyFocusable(el)); + }); +}); From 45a08b6447c869d6a9ac4f4609fec25cc3c87f7e Mon Sep 17 00:00:00 2001 From: Steven Lambert <2433219+straker@users.noreply.github.com> Date: Wed, 18 Jan 2023 10:26:13 -0700 Subject: [PATCH 07/12] test: prevent setting read-only properties on DOMRect (#3858) --- test/testutils.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/testutils.js b/test/testutils.js index cf935ed650..843441bbf4 100644 --- a/test/testutils.js +++ b/test/testutils.js @@ -562,6 +562,18 @@ testUtils.getCheckEvaluate = function getCheckEvaluate(checkId, testOptions) { axe.testUtils = testUtils; if (typeof beforeEach !== 'undefined' && typeof afterEach !== 'undefined') { + // prevent setting read-only properties + // @see https://github.com/dequelabs/axe-core/issues/3837 + const readonlyRect = new DOMRectReadOnly(); + const proto = Object.getPrototypeOf(readonlyRect); + ['left', 'right', 'top', 'bottom'].forEach(prop => { + Object.defineProperty(proto, prop, { + set(value) { + throw new TypeError(`setting getter-only property "${prop}"`); + } + }); + }); + beforeEach(function () { // reset from axe._load overriding checks = originalChecks; From 3be2bad2a896e72a92fe70810500fc1ef67b7027 Mon Sep 17 00:00:00 2001 From: Steven Lambert <2433219+straker@users.noreply.github.com> Date: Wed, 18 Jan 2023 10:26:29 -0700 Subject: [PATCH 08/12] feat: deprecate color.filteredRectStack, color.getRectStack, and dom.visuallyContains (#3859) --- lib/commons/color/filtered-rect-stack.js | 1 + lib/commons/color/get-rect-stack.js | 1 + lib/commons/dom/visually-contains.js | 1 + 3 files changed, 3 insertions(+) diff --git a/lib/commons/color/filtered-rect-stack.js b/lib/commons/color/filtered-rect-stack.js index bca9f3b43d..f07cc0579c 100644 --- a/lib/commons/color/filtered-rect-stack.js +++ b/lib/commons/color/filtered-rect-stack.js @@ -3,6 +3,7 @@ import incompleteData from './incomplete-data'; /** * Get filtered stack of block and inline elements, excluding line breaks + * @deprecated use color.getBackgroundStack instead * @method filteredRectStack * @memberof axe.commons.color * @param {Element} elm diff --git a/lib/commons/color/get-rect-stack.js b/lib/commons/color/get-rect-stack.js index c608f34463..0f2274228f 100644 --- a/lib/commons/color/get-rect-stack.js +++ b/lib/commons/color/get-rect-stack.js @@ -3,6 +3,7 @@ import getTextElementStack from '../dom/get-text-element-stack'; /** * Get relevant stacks of block and inline elements, excluding line breaks + * @deprecated use color.getBackgroundStack instead * @method getRectStack * @memberof axe.commons.color * @param {Element} elm diff --git a/lib/commons/dom/visually-contains.js b/lib/commons/dom/visually-contains.js index c46f8b0fdc..84df0fec1e 100644 --- a/lib/commons/dom/visually-contains.js +++ b/lib/commons/dom/visually-contains.js @@ -3,6 +3,7 @@ import { getNodeFromTree, getScroll } from '../../core/utils'; /** * Checks whether a parent element visually contains its child, either directly or via scrolling. * Assumes that |parent| is an ancestor of |node|. + * @deprecated * @method visuallyContains * @memberof axe.commons.dom * @instance From 273c97199bd596a288378427becba672b4482678 Mon Sep 17 00:00:00 2001 From: Steven Lambert <2433219+straker@users.noreply.github.com> Date: Thu, 19 Jan 2023 15:00:48 -0700 Subject: [PATCH 09/12] feat(dom.focusDisabled,dom.isVisibleForScreenreader): support the inert attribute (#3857) * feat(dom.focus-disabled,dom.is-visible-for-screenreader): support the inert attribute * typos * integration tests --- lib/commons/dom/focus-disabled.js | 7 +++- lib/commons/dom/index.js | 1 + lib/commons/dom/is-inert.js | 37 +++++++++++++++++ .../dom/is-visible-for-screenreader.js | 3 +- test/commons/dom/focus-disabled.js | 23 +++++++++++ test/commons/dom/is-inert.js | 40 +++++++++++++++++++ .../dom/is-visible-for-screenreader.js | 32 +++++++++++++++ .../aria-hidden-focus/aria-hidden-focus.html | 6 +++ .../aria-hidden-focus/aria-hidden-focus.json | 3 +- .../frame-focusable-content.html | 5 +++ 10 files changed, 153 insertions(+), 4 deletions(-) create mode 100644 lib/commons/dom/is-inert.js create mode 100644 test/commons/dom/is-inert.js diff --git a/lib/commons/dom/focus-disabled.js b/lib/commons/dom/focus-disabled.js index 427c1aa0c0..8ba7be8855 100644 --- a/lib/commons/dom/focus-disabled.js +++ b/lib/commons/dom/focus-disabled.js @@ -1,6 +1,8 @@ import AbstractVirtualNode from '../../core/base/virtual-node/abstract-virtual-node'; import { getNodeFromTree } from '../../core/utils'; import isHiddenForEveryone from './is-hidden-for-everyone'; +import isInert from './is-inert'; + // Source: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/disabled const allowedDisabledNodeNames = [ 'button', @@ -27,8 +29,9 @@ function focusDisabled(el) { const vNode = el instanceof AbstractVirtualNode ? el : getNodeFromTree(el); if ( - isDisabledAttrAllowed(vNode.props.nodeName) && - vNode.hasAttr('disabled') + (isDisabledAttrAllowed(vNode.props.nodeName) && + vNode.hasAttr('disabled')) || + isInert(vNode) ) { return true; } diff --git a/lib/commons/dom/index.js b/lib/commons/dom/index.js index 20a972cb47..99389d55f8 100644 --- a/lib/commons/dom/index.js +++ b/lib/commons/dom/index.js @@ -31,6 +31,7 @@ export { default as isHiddenForEveryone } from './is-hidden-for-everyone'; export { default as isHTML5 } from './is-html5'; export { default as isInTabOrder } from './is-in-tab-order'; export { default as isInTextBlock } from './is-in-text-block'; +export { default as isInert } from './is-inert'; export { default as isModalOpen } from './is-modal-open'; export { default as isMultiline } from './is-multiline'; export { default as isNativelyFocusable } from './is-natively-focusable'; diff --git a/lib/commons/dom/is-inert.js b/lib/commons/dom/is-inert.js new file mode 100644 index 0000000000..fc4c821da5 --- /dev/null +++ b/lib/commons/dom/is-inert.js @@ -0,0 +1,37 @@ +import memoize from '../../core/utils/memoize'; + +/** + * Determines if an element is inside an inert subtree. + * @param {VirtualNode} vNode + * @param {Boolean} [options.skipAncestors] If the ancestor tree should not be used + * @return {Boolean} The element's inert state + */ +export default function isInert(vNode, { skipAncestors } = {}) { + if (skipAncestors) { + return isInertSelf(vNode); + } + + return isInertAncestors(vNode); +} + +/** + * Check the element for inert + */ +const isInertSelf = memoize(function isInertSelfMemoized(vNode) { + return vNode.hasAttr('inert'); +}); + +/** + * Check the element and ancestors for inert + */ +const isInertAncestors = memoize(function isInertAncestorsMemoized(vNode) { + if (isInertSelf(vNode)) { + return true; + } + + if (!vNode.parent) { + return false; + } + + return isInertAncestors(vNode.parent); +}); diff --git a/lib/commons/dom/is-visible-for-screenreader.js b/lib/commons/dom/is-visible-for-screenreader.js index 712acbda37..79771e9129 100644 --- a/lib/commons/dom/is-visible-for-screenreader.js +++ b/lib/commons/dom/is-visible-for-screenreader.js @@ -3,6 +3,7 @@ import { getNodeFromTree } from '../../core/utils'; import memoize from '../../core/utils/memoize'; import isHiddenForEveryone from './is-hidden-for-everyone'; import { ariaHidden, areaHidden } from './visibility-methods'; +import isInert from './is-inert'; /** * Determine if an element is visible to a screen reader @@ -21,7 +22,7 @@ export default function isVisibleToScreenReaders(vNode) { */ const isVisibleToScreenReadersVirtual = memoize( function isVisibleToScreenReadersMemoized(vNode, isAncestor) { - if (ariaHidden(vNode)) { + if (ariaHidden(vNode) || isInert(vNode, { skipAncestors: true })) { return false; } diff --git a/test/commons/dom/focus-disabled.js b/test/commons/dom/focus-disabled.js index 2f8a242dc4..998dd60f9d 100644 --- a/test/commons/dom/focus-disabled.js +++ b/test/commons/dom/focus-disabled.js @@ -51,6 +51,29 @@ describe('dom.focus-disabled', () => { assert.isTrue(focusDisabled(vNode)); }); + it('returns true for element with inert', () => { + const vNode = queryFixture(''); + + assert.isTrue(focusDisabled(vNode)); + }); + + it('returns true for ancestor with inert', () => { + const vNode = queryFixture( + '
' + ); + + assert.isTrue(focusDisabled(vNode)); + }); + + it('returns true for ancestor with inert outside shadow tree', () => { + const vNode = queryShadowFixture( + '
', + '' + ); + + assert.isTrue(focusDisabled(vNode)); + }); + describe('SerialVirtualNode', () => { it('returns false if element is hidden for everyone', () => { const vNode = new axe.SerialVirtualNode({ diff --git a/test/commons/dom/is-inert.js b/test/commons/dom/is-inert.js new file mode 100644 index 0000000000..bd1d344c56 --- /dev/null +++ b/test/commons/dom/is-inert.js @@ -0,0 +1,40 @@ +describe('dom.isInert', () => { + const isInert = axe.commons.dom.isInert; + const { queryFixture } = axe.testUtils; + + it('returns true for element with "inert=false`', () => { + const vNode = queryFixture('
'); + + assert.isTrue(isInert(vNode)); + }); + + it('returns true for element with "inert`', () => { + const vNode = queryFixture('
'); + + assert.isTrue(isInert(vNode)); + }); + + it('returns false for element without inert', () => { + const vNode = queryFixture('
'); + + assert.isFalse(isInert(vNode)); + }); + + it('returns true for ancestor with inert', () => { + const vNode = queryFixture( + '
' + ); + + assert.isTrue(isInert(vNode)); + }); + + describe('options.skipAncestors', () => { + it('returns false for ancestor with inert', () => { + const vNode = queryFixture( + '
' + ); + + assert.isFalse(isInert(vNode, { skipAncestors: true })); + }); + }); +}); diff --git a/test/commons/dom/is-visible-for-screenreader.js b/test/commons/dom/is-visible-for-screenreader.js index 354b1becd8..3586366a2a 100644 --- a/test/commons/dom/is-visible-for-screenreader.js +++ b/test/commons/dom/is-visible-for-screenreader.js @@ -62,6 +62,13 @@ describe('dom.isVisibleToScreenReaders', function () { assert.isFalse(isVisibleToScreenReaders(vNode)); }); + it('should return false if `inert` is set', function () { + var vNode = queryFixture( + '
Hidden from screen readers
' + ); + assert.isFalse(isVisibleToScreenReaders(vNode)); + }); + it('should return false if `display: none` is set', function () { var vNode = queryFixture( '' @@ -230,5 +237,30 @@ describe('dom.isVisibleToScreenReaders', function () { vNode.parent = parentVNode; assert.isFalse(isVisibleToScreenReaders(vNode)); }); + + it('should return false if `inert` is set', function () { + var vNode = new axe.SerialVirtualNode({ + nodeName: 'div', + attributes: { + inert: true + } + }); + assert.isFalse(isVisibleToScreenReaders(vNode)); + }); + + it('should return false if `inert` is set on parent', function () { + var vNode = new axe.SerialVirtualNode({ + nodeName: 'div' + }); + var parentVNode = new axe.SerialVirtualNode({ + nodeName: 'div', + attributes: { + inert: true + } + }); + parentVNode.children = [vNode]; + vNode.parent = parentVNode; + assert.isFalse(isVisibleToScreenReaders(vNode)); + }); }); }); diff --git a/test/integration/rules/aria-hidden-focus/aria-hidden-focus.html b/test/integration/rules/aria-hidden-focus/aria-hidden-focus.html index 59d9532886..b43814699a 100644 --- a/test/integration/rules/aria-hidden-focus/aria-hidden-focus.html +++ b/test/integration/rules/aria-hidden-focus/aria-hidden-focus.html @@ -27,6 +27,12 @@ + + diff --git a/test/integration/rules/aria-hidden-focus/aria-hidden-focus.json b/test/integration/rules/aria-hidden-focus/aria-hidden-focus.json index 1c6640ebd9..908a0e7178 100644 --- a/test/integration/rules/aria-hidden-focus/aria-hidden-focus.json +++ b/test/integration/rules/aria-hidden-focus/aria-hidden-focus.json @@ -16,7 +16,8 @@ ["#pass3"], ["#pass4"], ["#pass5"], - ["#pass6"] + ["#pass6"], + ["#pass7"] ], "incomplete": [["#incomplete1"], ["#incomplete2"]] } diff --git a/test/integration/rules/frame-focusable-content/frame-focusable-content.html b/test/integration/rules/frame-focusable-content/frame-focusable-content.html index f61fdba0be..8928fc6800 100644 --- a/test/integration/rules/frame-focusable-content/frame-focusable-content.html +++ b/test/integration/rules/frame-focusable-content/frame-focusable-content.html @@ -46,3 +46,8 @@ height="0" id="inapplicable-3" > + From b0bdefa34b85363e742ff04e319c014fe95f31f7 Mon Sep 17 00:00:00 2001 From: Wilco Fiers Date: Fri, 20 Jan 2023 11:11:59 +0100 Subject: [PATCH 10/12] fix(scrollable-region-focusable): skip native controls (#3862) --- lib/rules/scrollable-region-focusable.json | 1 + .../scrollable-region-focusable.html | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/lib/rules/scrollable-region-focusable.json b/lib/rules/scrollable-region-focusable.json index 5b8601298d..2394107759 100644 --- a/lib/rules/scrollable-region-focusable.json +++ b/lib/rules/scrollable-region-focusable.json @@ -1,5 +1,6 @@ { "id": "scrollable-region-focusable", + "selector": "*:not(select,textarea)", "matches": "scrollable-region-focusable-matches", "tags": ["cat.keyboard", "wcag2a", "wcag211"], "actIds": ["0ssw9k"], diff --git a/test/integration/rules/scrollable-region-focusable/scrollable-region-focusable.html b/test/integration/rules/scrollable-region-focusable/scrollable-region-focusable.html index d25dbf0648..750785c2be 100644 --- a/test/integration/rules/scrollable-region-focusable/scrollable-region-focusable.html +++ b/test/integration/rules/scrollable-region-focusable/scrollable-region-focusable.html @@ -132,3 +132,15 @@

Content

+ + + + From 5f900402470f925686a0d8b41ac01731492bbd30 Mon Sep 17 00:00:00 2001 From: Wilco Fiers Date: Fri, 20 Jan 2023 11:56:32 +0100 Subject: [PATCH 11/12] fix(link-in-text-block): allow links with identical colors (#3861) --- doc/check-options.md | 10 ++++ .../color/link-in-text-block-evaluate.js | 6 +- lib/checks/color/link-in-text-block.json | 3 +- test/checks/color/link-in-text-block.js | 57 ++++++++++++------- .../link-in-text-block.html | 7 +++ .../link-in-text-block.json | 3 +- 6 files changed, 64 insertions(+), 22 deletions(-) diff --git a/doc/check-options.md b/doc/check-options.md index 0f6c60d027..87c6adda42 100644 --- a/doc/check-options.md +++ b/doc/check-options.md @@ -36,6 +36,7 @@ - [region](#region) - [inline-style-property](#inline-style-property) - [invalid-children](#invalid-children) + - [link-in-text-block](#link-in-text-block) ## How Checks Work @@ -538,3 +539,12 @@ This evaluation method is used in the `list` and `definition-list` rule to deter | `validNodeNames` | Nodes without role allowed as children | | `validRoles` | Roles allowed on child elements | | `divGroups` | Whether the child nodes can be grouped in a div without any role (false by default) | + +### link-in-text-block + +This evaluation method is used in the `link-in-text-block` rule and tests that either the foreground color or the background color has sufficient contrast between the link text and the surrounding text. + +| Option | Default | Description | +| ----------------------- | :------ | :-------------------------------------------------------------------------- | +| `requiredContrastRatio` | `3` | Minimum contrast needed to pass the check between text or background colors | +| `allowSameColor` | `true` | Whether links with colors identical to its surroundings should pass | diff --git a/lib/checks/color/link-in-text-block-evaluate.js b/lib/checks/color/link-in-text-block-evaluate.js index df9b03f446..acadb1aec5 100644 --- a/lib/checks/color/link-in-text-block-evaluate.js +++ b/lib/checks/color/link-in-text-block-evaluate.js @@ -25,7 +25,7 @@ function isBlock(elm) { } function linkInTextBlockEvaluate(node, options) { - const { requiredContrastRatio } = options; + const { requiredContrastRatio, allowSameColor } = options; if (isBlock(node)) { return false; @@ -86,6 +86,10 @@ function linkInTextBlockEvaluate(node, options) { return undefined; } + if (allowSameColor && textContrast === 1 && backgroundContrast === 1) { + return true; + } + // Report bgContrast only if the background changes but text color stays the same if (textContrast === 1 && backgroundContrast > 1) { this.data({ diff --git a/lib/checks/color/link-in-text-block.json b/lib/checks/color/link-in-text-block.json index 767697de31..04c21841cb 100644 --- a/lib/checks/color/link-in-text-block.json +++ b/lib/checks/color/link-in-text-block.json @@ -2,7 +2,8 @@ "id": "link-in-text-block", "evaluate": "link-in-text-block-evaluate", "options": { - "requiredContrastRatio": 3 + "requiredContrastRatio": 3, + "allowSameColor": true }, "metadata": { "impact": "serious", diff --git a/test/checks/color/link-in-text-block.js b/test/checks/color/link-in-text-block.js index 9811041797..46fe3e362a 100644 --- a/test/checks/color/link-in-text-block.js +++ b/test/checks/color/link-in-text-block.js @@ -98,7 +98,7 @@ describe('link-in-text-block', function () { it('passes the selected node and closest ancestral block element', function () { fixture.innerHTML = - '
' + + '
' + '

' + ' link text ' + ' inside block

inside block' + @@ -192,24 +192,6 @@ describe('link-in-text-block', function () { assert.equal(checkContext._relatedNodes[0], linkElm.parentNode); }); - it('returns false with fgContrast key if nodes have same foreground color and same background color', function () { - var linkElm = getLinkElm( - { - color: 'black' - }, - { - color: '#000' - } - ); - assert.isFalse( - axe.testUtils - .getCheckEvaluate('link-in-text-block') - .call(checkContext, linkElm) - ); - assert.equal(checkContext._data.messageKey, 'fgContrast'); - assert.equal(checkContext._relatedNodes[0], linkElm.parentNode); - }); - it('returns false with fgContrast key if nodes have insufficient foreground contrast and same background color', function () { var linkElm = getLinkElm( { @@ -353,5 +335,42 @@ describe('link-in-text-block', function () { parentBackgroundColor: '#f0f0f0' }); }); + + describe('options.allowSameColor', () => { + it('when true, passes when link and text colors are identical', () => { + var linkElm = getLinkElm( + { + color: 'black' + }, + { + color: '#000' + } + ); + assert.isTrue( + axe.testUtils + .getCheckEvaluate('link-in-text-block') + .call(checkContext, linkElm, { allowSameColor: true }) + ); + assert.equal(checkContext._relatedNodes[0], linkElm.parentNode); + }); + + it('when false, fails when link and text colors are identical', () => { + var linkElm = getLinkElm( + { + color: 'black' + }, + { + color: '#000' + } + ); + assert.isFalse( + axe.testUtils + .getCheckEvaluate('link-in-text-block') + .call(checkContext, linkElm, { allowSameColor: false }) + ); + assert.equal(checkContext._data.messageKey, 'fgContrast'); + assert.equal(checkContext._relatedNodes[0], linkElm.parentNode); + }); + }); }); }); diff --git a/test/integration/rules/link-in-text-block/link-in-text-block.html b/test/integration/rules/link-in-text-block/link-in-text-block.html index f8f79e02fa..260a259e4f 100644 --- a/test/integration/rules/link-in-text-block/link-in-text-block.html +++ b/test/integration/rules/link-in-text-block/link-in-text-block.html @@ -105,6 +105,13 @@

Color change tests

>

+

+ paragraph of text (pass: text color has sufficient contrast against paragraph) + + Link text +

+

paragraph of text (fail: text color has insufficient contrast against paragraph) diff --git a/test/integration/rules/link-in-text-block/link-in-text-block.json b/test/integration/rules/link-in-text-block/link-in-text-block.json index fec07c6d6f..366b5f07dd 100644 --- a/test/integration/rules/link-in-text-block/link-in-text-block.json +++ b/test/integration/rules/link-in-text-block/link-in-text-block.json @@ -11,7 +11,8 @@ ["#pass-different-weight"], ["#pass-different-size"], ["#pass-background-color"], - ["#pass-text-color"] + ["#pass-text-color"], + ["#pass-same-colors"] ], "incomplete": [["#incomplete-low-contrast-parent-has-gradient"]] } From 0ba3ab3768f0eec4d5715279436a091f5554bb58 Mon Sep 17 00:00:00 2001 From: API Team CI User Date: Fri, 20 Jan 2023 10:58:33 +0000 Subject: [PATCH 12/12] chore(release): 4.7.0 --- CHANGELOG.md | 13 +++ bower.json | 2 +- doc/rule-descriptions.md | 198 +++++++++++++++++++-------------------- package-lock.json | 4 +- package.json | 2 +- sri-history.json | 4 + 6 files changed, 120 insertions(+), 103 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b27eb1ac9..0ef3e9eeae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,19 @@ 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. +## [4.7.0](https://github.com/dequelabs/axe-core/compare/v4.6.2...v4.7.0) (2023-01-20) + +### Features + +- deprecate color.filteredRectStack, color.getRectStack, and dom.visuallyContains ([#3859](https://github.com/dequelabs/axe-core/issues/3859)) ([3be2bad](https://github.com/dequelabs/axe-core/commit/3be2bad2a896e72a92fe70810500fc1ef67b7027)) +- **dom.focusDisabled,dom.isVisibleForScreenreader:** support the inert attribute ([#3857](https://github.com/dequelabs/axe-core/issues/3857)) ([273c971](https://github.com/dequelabs/axe-core/commit/273c97199bd596a288378427becba672b4482678)) + +### Bug Fixes + +- **color-contrast:** correctly compute color contrast of elements ([#3847](https://github.com/dequelabs/axe-core/issues/3847)) ([4c3a00c](https://github.com/dequelabs/axe-core/commit/4c3a00c7bd6de68b2795be37113a59d804d0a313)) +- **link-in-text-block:** allow links with identical colors ([#3861](https://github.com/dequelabs/axe-core/issues/3861)) ([5f90040](https://github.com/dequelabs/axe-core/commit/5f900402470f925686a0d8b41ac01731492bbd30)) +- **scrollable-region-focusable:** skip native controls ([#3862](https://github.com/dequelabs/axe-core/issues/3862)) ([b0bdefa](https://github.com/dequelabs/axe-core/commit/b0bdefa34b85363e742ff04e319c014fe95f31f7)) + ### [4.6.2](https://github.com/dequelabs/axe-core/compare/v4.6.1...v4.6.2) (2022-12-23) ### Bug Fixes diff --git a/bower.json b/bower.json index 809161182d..bf43eb2dd2 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "axe-core", - "version": "4.6.2", + "version": "4.7.0", "contributors": [ { "name": "David Sturley", diff --git a/doc/rule-descriptions.md b/doc/rule-descriptions.md index 77afb94ca5..de812b3b40 100644 --- a/doc/rule-descriptions.md +++ b/doc/rule-descriptions.md @@ -14,71 +14,71 @@ | Rule ID | Description | Impact | Tags | Issue Type | ACT Rules | | :------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------- | :-------------------------------------------------------------------------------- | :------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [area-alt](https://dequeuniversity.com/rules/axe/4.6/area-alt?application=RuleDescription) | Ensures <area> elements of image maps have alternate text | Critical | cat.text-alternatives, wcag2a, wcag244, wcag412, section508, section508.22.a, ACT | failure, needs review | [c487ae](https://act-rules.github.io/rules/c487ae) | -| [aria-allowed-attr](https://dequeuniversity.com/rules/axe/4.6/aria-allowed-attr?application=RuleDescription) | Ensures ARIA attributes are allowed for an element's role | Serious, Critical | cat.aria, wcag2a, wcag412 | failure, needs review | [5c01ea](https://act-rules.github.io/rules/5c01ea) | -| [aria-command-name](https://dequeuniversity.com/rules/axe/4.6/aria-command-name?application=RuleDescription) | Ensures every ARIA button, link and menuitem has an accessible name | Serious | cat.aria, wcag2a, wcag412, ACT | failure, needs review | [97a4e1](https://act-rules.github.io/rules/97a4e1) | -| [aria-hidden-body](https://dequeuniversity.com/rules/axe/4.6/aria-hidden-body?application=RuleDescription) | Ensures aria-hidden='true' is not present on the document body. | Critical | cat.aria, wcag2a, wcag412 | failure | | -| [aria-hidden-focus](https://dequeuniversity.com/rules/axe/4.6/aria-hidden-focus?application=RuleDescription) | Ensures aria-hidden elements are not focusable nor contain focusable elements | Serious | cat.name-role-value, wcag2a, wcag412 | failure, needs review | [6cfa84](https://act-rules.github.io/rules/6cfa84) | -| [aria-input-field-name](https://dequeuniversity.com/rules/axe/4.6/aria-input-field-name?application=RuleDescription) | Ensures every ARIA input field has an accessible name | Moderate, Serious | cat.aria, wcag2a, wcag412, ACT | failure, needs review | [e086e5](https://act-rules.github.io/rules/e086e5) | -| [aria-meter-name](https://dequeuniversity.com/rules/axe/4.6/aria-meter-name?application=RuleDescription) | Ensures every ARIA meter node has an accessible name | Serious | cat.aria, wcag2a, wcag111 | failure, needs review | | -| [aria-progressbar-name](https://dequeuniversity.com/rules/axe/4.6/aria-progressbar-name?application=RuleDescription) | Ensures every ARIA progressbar node has an accessible name | Serious | cat.aria, wcag2a, wcag111 | failure, needs review | | -| [aria-required-attr](https://dequeuniversity.com/rules/axe/4.6/aria-required-attr?application=RuleDescription) | Ensures elements with ARIA roles have all required ARIA attributes | Critical | cat.aria, wcag2a, wcag412 | failure | [4e8ab6](https://act-rules.github.io/rules/4e8ab6) | -| [aria-required-children](https://dequeuniversity.com/rules/axe/4.6/aria-required-children?application=RuleDescription) | Ensures elements with an ARIA role that require child roles contain them | Critical | cat.aria, wcag2a, wcag131 | failure, needs review | [bc4a75](https://act-rules.github.io/rules/bc4a75), [ff89c9](https://act-rules.github.io/rules/ff89c9) | -| [aria-required-parent](https://dequeuniversity.com/rules/axe/4.6/aria-required-parent?application=RuleDescription) | Ensures elements with an ARIA role that require parent roles are contained by them | Critical | cat.aria, wcag2a, wcag131 | failure | [ff89c9](https://act-rules.github.io/rules/ff89c9) | -| [aria-roledescription](https://dequeuniversity.com/rules/axe/4.6/aria-roledescription?application=RuleDescription) | Ensure aria-roledescription is only used on elements with an implicit or explicit role | Serious | cat.aria, wcag2a, wcag412 | failure, needs review | | -| [aria-roles](https://dequeuniversity.com/rules/axe/4.6/aria-roles?application=RuleDescription) | Ensures all elements with a role attribute use a valid value | Minor, Serious, Critical | cat.aria, wcag2a, wcag412 | failure | [674b10](https://act-rules.github.io/rules/674b10) | -| [aria-toggle-field-name](https://dequeuniversity.com/rules/axe/4.6/aria-toggle-field-name?application=RuleDescription) | Ensures every ARIA toggle field has an accessible name | Moderate, Serious | cat.aria, wcag2a, wcag412, ACT | failure, needs review | [e086e5](https://act-rules.github.io/rules/e086e5) | -| [aria-tooltip-name](https://dequeuniversity.com/rules/axe/4.6/aria-tooltip-name?application=RuleDescription) | Ensures every ARIA tooltip node has an accessible name | Serious | cat.aria, wcag2a, wcag412 | failure, needs review | | -| [aria-valid-attr-value](https://dequeuniversity.com/rules/axe/4.6/aria-valid-attr-value?application=RuleDescription) | Ensures all ARIA attributes have valid values | Serious, Critical | cat.aria, wcag2a, wcag412 | failure, needs review | [6a7281](https://act-rules.github.io/rules/6a7281) | -| [aria-valid-attr](https://dequeuniversity.com/rules/axe/4.6/aria-valid-attr?application=RuleDescription) | Ensures attributes that begin with aria- are valid ARIA attributes | Critical | cat.aria, wcag2a, wcag412 | failure | [5f99a7](https://act-rules.github.io/rules/5f99a7) | -| [audio-caption](https://dequeuniversity.com/rules/axe/4.6/audio-caption?application=RuleDescription) | Ensures <audio> elements have captions | Critical | cat.time-and-media, wcag2a, wcag121, section508, section508.22.a | needs review | [2eb176](https://act-rules.github.io/rules/2eb176), [afb423](https://act-rules.github.io/rules/afb423) | -| [blink](https://dequeuniversity.com/rules/axe/4.6/blink?application=RuleDescription) | Ensures <blink> elements are not used | Serious | cat.time-and-media, wcag2a, wcag222, section508, section508.22.j | failure | | -| [button-name](https://dequeuniversity.com/rules/axe/4.6/button-name?application=RuleDescription) | Ensures buttons have discernible text | Critical | cat.name-role-value, wcag2a, wcag412, section508, section508.22.a, ACT | failure, needs review | [97a4e1](https://act-rules.github.io/rules/97a4e1), [m6b1q3](https://act-rules.github.io/rules/m6b1q3) | -| [bypass](https://dequeuniversity.com/rules/axe/4.6/bypass?application=RuleDescription) | Ensures each page has at least one mechanism for a user to bypass navigation and jump straight to the content | Serious | cat.keyboard, wcag2a, wcag241, section508, section508.22.o | needs review | [cf77f2](https://act-rules.github.io/rules/cf77f2), [047fe0](https://act-rules.github.io/rules/047fe0), [b40fd1](https://act-rules.github.io/rules/b40fd1), [3e12e1](https://act-rules.github.io/rules/3e12e1), [ye5d6e](https://act-rules.github.io/rules/ye5d6e) | -| [color-contrast](https://dequeuniversity.com/rules/axe/4.6/color-contrast?application=RuleDescription) | Ensures the contrast between foreground and background colors meets WCAG 2 AA contrast ratio thresholds | Serious | cat.color, wcag2aa, wcag143, ACT | failure, needs review | [afw4f7](https://act-rules.github.io/rules/afw4f7), [09o5cg](https://act-rules.github.io/rules/09o5cg) | -| [definition-list](https://dequeuniversity.com/rules/axe/4.6/definition-list?application=RuleDescription) | Ensures <dl> elements are structured correctly | Serious | cat.structure, wcag2a, wcag131 | failure | | -| [dlitem](https://dequeuniversity.com/rules/axe/4.6/dlitem?application=RuleDescription) | Ensures <dt> and <dd> elements are contained by a <dl> | Serious | cat.structure, wcag2a, wcag131 | failure | | -| [document-title](https://dequeuniversity.com/rules/axe/4.6/document-title?application=RuleDescription) | Ensures each HTML document contains a non-empty <title> element | Serious | cat.text-alternatives, wcag2a, wcag242, ACT | failure | [2779a5](https://act-rules.github.io/rules/2779a5) | -| [duplicate-id-active](https://dequeuniversity.com/rules/axe/4.6/duplicate-id-active?application=RuleDescription) | Ensures every id attribute value of active elements is unique | Serious | cat.parsing, wcag2a, wcag411 | failure | [3ea0c8](https://act-rules.github.io/rules/3ea0c8) | -| [duplicate-id-aria](https://dequeuniversity.com/rules/axe/4.6/duplicate-id-aria?application=RuleDescription) | Ensures every id attribute value used in ARIA and in labels is unique | Critical | cat.parsing, wcag2a, wcag411 | failure | [3ea0c8](https://act-rules.github.io/rules/3ea0c8) | -| [duplicate-id](https://dequeuniversity.com/rules/axe/4.6/duplicate-id?application=RuleDescription) | Ensures every id attribute value is unique | Minor | cat.parsing, wcag2a, wcag411 | failure | [3ea0c8](https://act-rules.github.io/rules/3ea0c8) | -| [form-field-multiple-labels](https://dequeuniversity.com/rules/axe/4.6/form-field-multiple-labels?application=RuleDescription) | Ensures form field does not have multiple label elements | Moderate | cat.forms, wcag2a, wcag332 | needs review | | -| [frame-focusable-content](https://dequeuniversity.com/rules/axe/4.6/frame-focusable-content?application=RuleDescription) | Ensures <frame> and <iframe> elements with focusable content do not have tabindex=-1 | Serious | cat.keyboard, wcag2a, wcag211 | failure, needs review | [akn7bn](https://act-rules.github.io/rules/akn7bn) | -| [frame-title-unique](https://dequeuniversity.com/rules/axe/4.6/frame-title-unique?application=RuleDescription) | Ensures <iframe> and <frame> elements contain a unique title attribute | Serious | cat.text-alternatives, wcag412, wcag2a | needs review | [4b1c6c](https://act-rules.github.io/rules/4b1c6c) | -| [frame-title](https://dequeuniversity.com/rules/axe/4.6/frame-title?application=RuleDescription) | Ensures <iframe> and <frame> elements have an accessible name | Serious | cat.text-alternatives, wcag2a, wcag412, section508, section508.22.i | failure, needs review | [cae760](https://act-rules.github.io/rules/cae760) | -| [html-has-lang](https://dequeuniversity.com/rules/axe/4.6/html-has-lang?application=RuleDescription) | Ensures every HTML document has a lang attribute | Serious | cat.language, wcag2a, wcag311, ACT | failure | [b5c3f8](https://act-rules.github.io/rules/b5c3f8) | -| [html-lang-valid](https://dequeuniversity.com/rules/axe/4.6/html-lang-valid?application=RuleDescription) | Ensures the lang attribute of the <html> element has a valid value | Serious | cat.language, wcag2a, wcag311, ACT | failure | [bf051a](https://act-rules.github.io/rules/bf051a) | -| [html-xml-lang-mismatch](https://dequeuniversity.com/rules/axe/4.6/html-xml-lang-mismatch?application=RuleDescription) | Ensure that HTML elements with both valid lang and xml:lang attributes agree on the base language of the page | Moderate | cat.language, wcag2a, wcag311, ACT | failure | [5b7ae0](https://act-rules.github.io/rules/5b7ae0) | -| [image-alt](https://dequeuniversity.com/rules/axe/4.6/image-alt?application=RuleDescription) | Ensures <img> elements have alternate text or a role of none or presentation | Critical | cat.text-alternatives, wcag2a, wcag111, section508, section508.22.a, ACT | failure, needs review | [23a2a8](https://act-rules.github.io/rules/23a2a8) | -| [input-button-name](https://dequeuniversity.com/rules/axe/4.6/input-button-name?application=RuleDescription) | Ensures input buttons have discernible text | Critical | cat.name-role-value, wcag2a, wcag412, section508, section508.22.a, ACT | failure, needs review | [97a4e1](https://act-rules.github.io/rules/97a4e1) | -| [input-image-alt](https://dequeuniversity.com/rules/axe/4.6/input-image-alt?application=RuleDescription) | Ensures <input type="image"> elements have alternate text | Critical | cat.text-alternatives, wcag2a, wcag111, wcag412, section508, section508.22.a, ACT | failure, needs review | [59796f](https://act-rules.github.io/rules/59796f) | -| [label](https://dequeuniversity.com/rules/axe/4.6/label?application=RuleDescription) | Ensures every form element has a label | Minor, Critical | cat.forms, wcag2a, wcag412, section508, section508.22.n, ACT | failure, needs review | [e086e5](https://act-rules.github.io/rules/e086e5) | -| [link-in-text-block](https://dequeuniversity.com/rules/axe/4.6/link-in-text-block?application=RuleDescription) | Ensure links are distinguished from surrounding text in a way that does not rely on color | Serious | cat.color, wcag2a, wcag141 | failure, needs review | | -| [link-name](https://dequeuniversity.com/rules/axe/4.6/link-name?application=RuleDescription) | Ensures links have discernible text | Serious | cat.name-role-value, wcag2a, wcag412, wcag244, section508, section508.22.a, ACT | failure, needs review | [c487ae](https://act-rules.github.io/rules/c487ae) | -| [list](https://dequeuniversity.com/rules/axe/4.6/list?application=RuleDescription) | Ensures that lists are structured correctly | Serious | cat.structure, wcag2a, wcag131 | failure | | -| [listitem](https://dequeuniversity.com/rules/axe/4.6/listitem?application=RuleDescription) | Ensures <li> elements are used semantically | Serious | cat.structure, wcag2a, wcag131 | failure | | -| [marquee](https://dequeuniversity.com/rules/axe/4.6/marquee?application=RuleDescription) | Ensures <marquee> elements are not used | Serious | cat.parsing, wcag2a, wcag222 | failure | | -| [meta-refresh](https://dequeuniversity.com/rules/axe/4.6/meta-refresh?application=RuleDescription) | Ensures <meta http-equiv="refresh"> is not used for delayed refresh | Critical | cat.time-and-media, wcag2a, wcag221 | failure | [bc659a](https://act-rules.github.io/rules/bc659a), [bisz58](https://act-rules.github.io/rules/bisz58) | -| [meta-viewport](https://dequeuniversity.com/rules/axe/4.6/meta-viewport?application=RuleDescription) | Ensures <meta name="viewport"> does not disable text scaling and zooming | Critical | cat.sensory-and-visual-cues, wcag2aa, wcag144, ACT | failure | [b4f0c3](https://act-rules.github.io/rules/b4f0c3) | -| [nested-interactive](https://dequeuniversity.com/rules/axe/4.6/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) | -| [no-autoplay-audio](https://dequeuniversity.com/rules/axe/4.6/no-autoplay-audio?application=RuleDescription) | Ensures <video> or <audio> elements do not autoplay audio for more than 3 seconds without a control mechanism to stop or mute the audio | Moderate | cat.time-and-media, wcag2a, wcag142, ACT | needs review | [80f0bf](https://act-rules.github.io/rules/80f0bf) | -| [object-alt](https://dequeuniversity.com/rules/axe/4.6/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.6/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) | -| [scrollable-region-focusable](https://dequeuniversity.com/rules/axe/4.6/scrollable-region-focusable?application=RuleDescription) | Ensure elements that have scrollable content are accessible by keyboard | Moderate | cat.keyboard, wcag2a, wcag211 | failure | [0ssw9k](https://act-rules.github.io/rules/0ssw9k) | -| [select-name](https://dequeuniversity.com/rules/axe/4.6/select-name?application=RuleDescription) | Ensures select element has an accessible name | Minor, Critical | cat.forms, wcag2a, wcag412, section508, section508.22.n, ACT | failure, needs review | [e086e5](https://act-rules.github.io/rules/e086e5) | -| [server-side-image-map](https://dequeuniversity.com/rules/axe/4.6/server-side-image-map?application=RuleDescription) | Ensures that server-side image maps are not used | Minor | cat.text-alternatives, wcag2a, wcag211, section508, section508.22.f | needs review | | -| [svg-img-alt](https://dequeuniversity.com/rules/axe/4.6/svg-img-alt?application=RuleDescription) | Ensures <svg> elements with an img, graphics-document or graphics-symbol role have an accessible text | Serious | cat.text-alternatives, wcag2a, wcag111, section508, section508.22.a, ACT | failure, needs review | [7d6734](https://act-rules.github.io/rules/7d6734) | -| [td-headers-attr](https://dequeuniversity.com/rules/axe/4.6/td-headers-attr?application=RuleDescription) | Ensure that each cell in a table that uses the headers attribute refers only to other cells in that table | Serious | cat.tables, wcag2a, wcag131, section508, section508.22.g | failure, needs review | [a25f45](https://act-rules.github.io/rules/a25f45) | -| [th-has-data-cells](https://dequeuniversity.com/rules/axe/4.6/th-has-data-cells?application=RuleDescription) | Ensure that <th> elements and elements with role=columnheader/rowheader have data cells they describe | Serious | cat.tables, wcag2a, wcag131, section508, section508.22.g | failure, needs review | [d0f69e](https://act-rules.github.io/rules/d0f69e) | -| [valid-lang](https://dequeuniversity.com/rules/axe/4.6/valid-lang?application=RuleDescription) | Ensures lang attributes have valid values | Serious | cat.language, wcag2aa, wcag312, ACT | failure | [de46e4](https://act-rules.github.io/rules/de46e4) | -| [video-caption](https://dequeuniversity.com/rules/axe/4.6/video-caption?application=RuleDescription) | Ensures <video> elements have captions | Critical | cat.text-alternatives, wcag2a, wcag122, section508, section508.22.a | needs review | [eac66b](https://act-rules.github.io/rules/eac66b) | +| [area-alt](https://dequeuniversity.com/rules/axe/4.7/area-alt?application=RuleDescription) | Ensures <area> elements of image maps have alternate text | Critical | cat.text-alternatives, wcag2a, wcag244, wcag412, section508, section508.22.a, ACT | failure, needs review | [c487ae](https://act-rules.github.io/rules/c487ae) | +| [aria-allowed-attr](https://dequeuniversity.com/rules/axe/4.7/aria-allowed-attr?application=RuleDescription) | Ensures ARIA attributes are allowed for an element's role | Serious, Critical | cat.aria, wcag2a, wcag412 | failure, needs review | [5c01ea](https://act-rules.github.io/rules/5c01ea) | +| [aria-command-name](https://dequeuniversity.com/rules/axe/4.7/aria-command-name?application=RuleDescription) | Ensures every ARIA button, link and menuitem has an accessible name | Serious | cat.aria, wcag2a, wcag412, ACT | failure, needs review | [97a4e1](https://act-rules.github.io/rules/97a4e1) | +| [aria-hidden-body](https://dequeuniversity.com/rules/axe/4.7/aria-hidden-body?application=RuleDescription) | Ensures aria-hidden='true' is not present on the document body. | Critical | cat.aria, wcag2a, wcag412 | failure | | +| [aria-hidden-focus](https://dequeuniversity.com/rules/axe/4.7/aria-hidden-focus?application=RuleDescription) | Ensures aria-hidden elements are not focusable nor contain focusable elements | Serious | cat.name-role-value, wcag2a, wcag412 | failure, needs review | [6cfa84](https://act-rules.github.io/rules/6cfa84) | +| [aria-input-field-name](https://dequeuniversity.com/rules/axe/4.7/aria-input-field-name?application=RuleDescription) | Ensures every ARIA input field has an accessible name | Moderate, Serious | cat.aria, wcag2a, wcag412, ACT | failure, needs review | [e086e5](https://act-rules.github.io/rules/e086e5) | +| [aria-meter-name](https://dequeuniversity.com/rules/axe/4.7/aria-meter-name?application=RuleDescription) | Ensures every ARIA meter node has an accessible name | Serious | cat.aria, wcag2a, wcag111 | failure, needs review | | +| [aria-progressbar-name](https://dequeuniversity.com/rules/axe/4.7/aria-progressbar-name?application=RuleDescription) | Ensures every ARIA progressbar node has an accessible name | Serious | cat.aria, wcag2a, wcag111 | failure, needs review | | +| [aria-required-attr](https://dequeuniversity.com/rules/axe/4.7/aria-required-attr?application=RuleDescription) | Ensures elements with ARIA roles have all required ARIA attributes | Critical | cat.aria, wcag2a, wcag412 | failure | [4e8ab6](https://act-rules.github.io/rules/4e8ab6) | +| [aria-required-children](https://dequeuniversity.com/rules/axe/4.7/aria-required-children?application=RuleDescription) | Ensures elements with an ARIA role that require child roles contain them | Critical | cat.aria, wcag2a, wcag131 | failure, needs review | [bc4a75](https://act-rules.github.io/rules/bc4a75), [ff89c9](https://act-rules.github.io/rules/ff89c9) | +| [aria-required-parent](https://dequeuniversity.com/rules/axe/4.7/aria-required-parent?application=RuleDescription) | Ensures elements with an ARIA role that require parent roles are contained by them | Critical | cat.aria, wcag2a, wcag131 | failure | [ff89c9](https://act-rules.github.io/rules/ff89c9) | +| [aria-roledescription](https://dequeuniversity.com/rules/axe/4.7/aria-roledescription?application=RuleDescription) | Ensure aria-roledescription is only used on elements with an implicit or explicit role | Serious | cat.aria, wcag2a, wcag412 | failure, needs review | | +| [aria-roles](https://dequeuniversity.com/rules/axe/4.7/aria-roles?application=RuleDescription) | Ensures all elements with a role attribute use a valid value | Minor, Serious, Critical | cat.aria, wcag2a, wcag412 | failure | [674b10](https://act-rules.github.io/rules/674b10) | +| [aria-toggle-field-name](https://dequeuniversity.com/rules/axe/4.7/aria-toggle-field-name?application=RuleDescription) | Ensures every ARIA toggle field has an accessible name | Moderate, Serious | cat.aria, wcag2a, wcag412, ACT | failure, needs review | [e086e5](https://act-rules.github.io/rules/e086e5) | +| [aria-tooltip-name](https://dequeuniversity.com/rules/axe/4.7/aria-tooltip-name?application=RuleDescription) | Ensures every ARIA tooltip node has an accessible name | Serious | cat.aria, wcag2a, wcag412 | failure, needs review | | +| [aria-valid-attr-value](https://dequeuniversity.com/rules/axe/4.7/aria-valid-attr-value?application=RuleDescription) | Ensures all ARIA attributes have valid values | Serious, Critical | cat.aria, wcag2a, wcag412 | failure, needs review | [6a7281](https://act-rules.github.io/rules/6a7281) | +| [aria-valid-attr](https://dequeuniversity.com/rules/axe/4.7/aria-valid-attr?application=RuleDescription) | Ensures attributes that begin with aria- are valid ARIA attributes | Critical | cat.aria, wcag2a, wcag412 | failure | [5f99a7](https://act-rules.github.io/rules/5f99a7) | +| [audio-caption](https://dequeuniversity.com/rules/axe/4.7/audio-caption?application=RuleDescription) | Ensures <audio> elements have captions | Critical | cat.time-and-media, wcag2a, wcag121, section508, section508.22.a | needs review | [2eb176](https://act-rules.github.io/rules/2eb176), [afb423](https://act-rules.github.io/rules/afb423) | +| [blink](https://dequeuniversity.com/rules/axe/4.7/blink?application=RuleDescription) | Ensures <blink> elements are not used | Serious | cat.time-and-media, wcag2a, wcag222, section508, section508.22.j | failure | | +| [button-name](https://dequeuniversity.com/rules/axe/4.7/button-name?application=RuleDescription) | Ensures buttons have discernible text | Critical | cat.name-role-value, wcag2a, wcag412, section508, section508.22.a, ACT | failure, needs review | [97a4e1](https://act-rules.github.io/rules/97a4e1), [m6b1q3](https://act-rules.github.io/rules/m6b1q3) | +| [bypass](https://dequeuniversity.com/rules/axe/4.7/bypass?application=RuleDescription) | Ensures each page has at least one mechanism for a user to bypass navigation and jump straight to the content | Serious | cat.keyboard, wcag2a, wcag241, section508, section508.22.o | needs review | [cf77f2](https://act-rules.github.io/rules/cf77f2), [047fe0](https://act-rules.github.io/rules/047fe0), [b40fd1](https://act-rules.github.io/rules/b40fd1), [3e12e1](https://act-rules.github.io/rules/3e12e1), [ye5d6e](https://act-rules.github.io/rules/ye5d6e) | +| [color-contrast](https://dequeuniversity.com/rules/axe/4.7/color-contrast?application=RuleDescription) | Ensures the contrast between foreground and background colors meets WCAG 2 AA contrast ratio thresholds | Serious | cat.color, wcag2aa, wcag143, ACT | failure, needs review | [afw4f7](https://act-rules.github.io/rules/afw4f7), [09o5cg](https://act-rules.github.io/rules/09o5cg) | +| [definition-list](https://dequeuniversity.com/rules/axe/4.7/definition-list?application=RuleDescription) | Ensures <dl> elements are structured correctly | Serious | cat.structure, wcag2a, wcag131 | failure | | +| [dlitem](https://dequeuniversity.com/rules/axe/4.7/dlitem?application=RuleDescription) | Ensures <dt> and <dd> elements are contained by a <dl> | Serious | cat.structure, wcag2a, wcag131 | failure | | +| [document-title](https://dequeuniversity.com/rules/axe/4.7/document-title?application=RuleDescription) | Ensures each HTML document contains a non-empty <title> element | Serious | cat.text-alternatives, wcag2a, wcag242, ACT | failure | [2779a5](https://act-rules.github.io/rules/2779a5) | +| [duplicate-id-active](https://dequeuniversity.com/rules/axe/4.7/duplicate-id-active?application=RuleDescription) | Ensures every id attribute value of active elements is unique | Serious | cat.parsing, wcag2a, wcag411 | failure | [3ea0c8](https://act-rules.github.io/rules/3ea0c8) | +| [duplicate-id-aria](https://dequeuniversity.com/rules/axe/4.7/duplicate-id-aria?application=RuleDescription) | Ensures every id attribute value used in ARIA and in labels is unique | Critical | cat.parsing, wcag2a, wcag411 | failure | [3ea0c8](https://act-rules.github.io/rules/3ea0c8) | +| [duplicate-id](https://dequeuniversity.com/rules/axe/4.7/duplicate-id?application=RuleDescription) | Ensures every id attribute value is unique | Minor | cat.parsing, wcag2a, wcag411 | failure | [3ea0c8](https://act-rules.github.io/rules/3ea0c8) | +| [form-field-multiple-labels](https://dequeuniversity.com/rules/axe/4.7/form-field-multiple-labels?application=RuleDescription) | Ensures form field does not have multiple label elements | Moderate | cat.forms, wcag2a, wcag332 | needs review | | +| [frame-focusable-content](https://dequeuniversity.com/rules/axe/4.7/frame-focusable-content?application=RuleDescription) | Ensures <frame> and <iframe> elements with focusable content do not have tabindex=-1 | Serious | cat.keyboard, wcag2a, wcag211 | failure, needs review | [akn7bn](https://act-rules.github.io/rules/akn7bn) | +| [frame-title-unique](https://dequeuniversity.com/rules/axe/4.7/frame-title-unique?application=RuleDescription) | Ensures <iframe> and <frame> elements contain a unique title attribute | Serious | cat.text-alternatives, wcag412, wcag2a | needs review | [4b1c6c](https://act-rules.github.io/rules/4b1c6c) | +| [frame-title](https://dequeuniversity.com/rules/axe/4.7/frame-title?application=RuleDescription) | Ensures <iframe> and <frame> elements have an accessible name | Serious | cat.text-alternatives, wcag2a, wcag412, section508, section508.22.i | failure, needs review | [cae760](https://act-rules.github.io/rules/cae760) | +| [html-has-lang](https://dequeuniversity.com/rules/axe/4.7/html-has-lang?application=RuleDescription) | Ensures every HTML document has a lang attribute | Serious | cat.language, wcag2a, wcag311, ACT | failure | [b5c3f8](https://act-rules.github.io/rules/b5c3f8) | +| [html-lang-valid](https://dequeuniversity.com/rules/axe/4.7/html-lang-valid?application=RuleDescription) | Ensures the lang attribute of the <html> element has a valid value | Serious | cat.language, wcag2a, wcag311, ACT | failure | [bf051a](https://act-rules.github.io/rules/bf051a) | +| [html-xml-lang-mismatch](https://dequeuniversity.com/rules/axe/4.7/html-xml-lang-mismatch?application=RuleDescription) | Ensure that HTML elements with both valid lang and xml:lang attributes agree on the base language of the page | Moderate | cat.language, wcag2a, wcag311, ACT | failure | [5b7ae0](https://act-rules.github.io/rules/5b7ae0) | +| [image-alt](https://dequeuniversity.com/rules/axe/4.7/image-alt?application=RuleDescription) | Ensures <img> elements have alternate text or a role of none or presentation | Critical | cat.text-alternatives, wcag2a, wcag111, section508, section508.22.a, ACT | failure, needs review | [23a2a8](https://act-rules.github.io/rules/23a2a8) | +| [input-button-name](https://dequeuniversity.com/rules/axe/4.7/input-button-name?application=RuleDescription) | Ensures input buttons have discernible text | Critical | cat.name-role-value, wcag2a, wcag412, section508, section508.22.a, ACT | failure, needs review | [97a4e1](https://act-rules.github.io/rules/97a4e1) | +| [input-image-alt](https://dequeuniversity.com/rules/axe/4.7/input-image-alt?application=RuleDescription) | Ensures <input type="image"> elements have alternate text | Critical | cat.text-alternatives, wcag2a, wcag111, wcag412, section508, section508.22.a, ACT | failure, needs review | [59796f](https://act-rules.github.io/rules/59796f) | +| [label](https://dequeuniversity.com/rules/axe/4.7/label?application=RuleDescription) | Ensures every form element has a label | Minor, Critical | cat.forms, wcag2a, wcag412, section508, section508.22.n, ACT | failure, needs review | [e086e5](https://act-rules.github.io/rules/e086e5) | +| [link-in-text-block](https://dequeuniversity.com/rules/axe/4.7/link-in-text-block?application=RuleDescription) | Ensure links are distinguished from surrounding text in a way that does not rely on color | Serious | cat.color, wcag2a, wcag141 | failure, needs review | | +| [link-name](https://dequeuniversity.com/rules/axe/4.7/link-name?application=RuleDescription) | Ensures links have discernible text | Serious | cat.name-role-value, wcag2a, wcag412, wcag244, section508, section508.22.a, ACT | failure, needs review | [c487ae](https://act-rules.github.io/rules/c487ae) | +| [list](https://dequeuniversity.com/rules/axe/4.7/list?application=RuleDescription) | Ensures that lists are structured correctly | Serious | cat.structure, wcag2a, wcag131 | failure | | +| [listitem](https://dequeuniversity.com/rules/axe/4.7/listitem?application=RuleDescription) | Ensures <li> elements are used semantically | Serious | cat.structure, wcag2a, wcag131 | failure | | +| [marquee](https://dequeuniversity.com/rules/axe/4.7/marquee?application=RuleDescription) | Ensures <marquee> elements are not used | Serious | cat.parsing, wcag2a, wcag222 | failure | | +| [meta-refresh](https://dequeuniversity.com/rules/axe/4.7/meta-refresh?application=RuleDescription) | Ensures <meta http-equiv="refresh"> is not used for delayed refresh | Critical | cat.time-and-media, wcag2a, wcag221 | failure | [bc659a](https://act-rules.github.io/rules/bc659a), [bisz58](https://act-rules.github.io/rules/bisz58) | +| [meta-viewport](https://dequeuniversity.com/rules/axe/4.7/meta-viewport?application=RuleDescription) | Ensures <meta name="viewport"> does not disable text scaling and zooming | Critical | cat.sensory-and-visual-cues, wcag2aa, wcag144, ACT | failure | [b4f0c3](https://act-rules.github.io/rules/b4f0c3) | +| [nested-interactive](https://dequeuniversity.com/rules/axe/4.7/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) | +| [no-autoplay-audio](https://dequeuniversity.com/rules/axe/4.7/no-autoplay-audio?application=RuleDescription) | Ensures <video> or <audio> elements do not autoplay audio for more than 3 seconds without a control mechanism to stop or mute the audio | Moderate | cat.time-and-media, wcag2a, wcag142, ACT | needs review | [80f0bf](https://act-rules.github.io/rules/80f0bf) | +| [object-alt](https://dequeuniversity.com/rules/axe/4.7/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.7/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) | +| [scrollable-region-focusable](https://dequeuniversity.com/rules/axe/4.7/scrollable-region-focusable?application=RuleDescription) | Ensure elements that have scrollable content are accessible by keyboard | Moderate | cat.keyboard, wcag2a, wcag211 | failure | [0ssw9k](https://act-rules.github.io/rules/0ssw9k) | +| [select-name](https://dequeuniversity.com/rules/axe/4.7/select-name?application=RuleDescription) | Ensures select element has an accessible name | Minor, Critical | cat.forms, wcag2a, wcag412, section508, section508.22.n, ACT | failure, needs review | [e086e5](https://act-rules.github.io/rules/e086e5) | +| [server-side-image-map](https://dequeuniversity.com/rules/axe/4.7/server-side-image-map?application=RuleDescription) | Ensures that server-side image maps are not used | Minor | cat.text-alternatives, wcag2a, wcag211, section508, section508.22.f | needs review | | +| [svg-img-alt](https://dequeuniversity.com/rules/axe/4.7/svg-img-alt?application=RuleDescription) | Ensures <svg> elements with an img, graphics-document or graphics-symbol role have an accessible text | Serious | cat.text-alternatives, wcag2a, wcag111, section508, section508.22.a, ACT | failure, needs review | [7d6734](https://act-rules.github.io/rules/7d6734) | +| [td-headers-attr](https://dequeuniversity.com/rules/axe/4.7/td-headers-attr?application=RuleDescription) | Ensure that each cell in a table that uses the headers attribute refers only to other cells in that table | Serious | cat.tables, wcag2a, wcag131, section508, section508.22.g | failure, needs review | [a25f45](https://act-rules.github.io/rules/a25f45) | +| [th-has-data-cells](https://dequeuniversity.com/rules/axe/4.7/th-has-data-cells?application=RuleDescription) | Ensure that <th> elements and elements with role=columnheader/rowheader have data cells they describe | Serious | cat.tables, wcag2a, wcag131, section508, section508.22.g | failure, needs review | [d0f69e](https://act-rules.github.io/rules/d0f69e) | +| [valid-lang](https://dequeuniversity.com/rules/axe/4.7/valid-lang?application=RuleDescription) | Ensures lang attributes have valid values | Serious | cat.language, wcag2aa, wcag312, ACT | failure | [de46e4](https://act-rules.github.io/rules/de46e4) | +| [video-caption](https://dequeuniversity.com/rules/axe/4.7/video-caption?application=RuleDescription) | Ensures <video> elements have captions | Critical | cat.text-alternatives, wcag2a, wcag122, section508, section508.22.a | needs review | [eac66b](https://act-rules.github.io/rules/eac66b) | ## WCAG 2.1 Level A & AA Rules | Rule ID | Description | Impact | Tags | Issue Type | ACT Rules | | :----------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------- | :------ | :------------------------------------- | :--------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [autocomplete-valid](https://dequeuniversity.com/rules/axe/4.6/autocomplete-valid?application=RuleDescription) | Ensure the autocomplete attribute is correct and suitable for the form field | Serious | cat.forms, wcag21aa, wcag135, ACT | failure | [73f2c2](https://act-rules.github.io/rules/73f2c2) | -| [avoid-inline-spacing](https://dequeuniversity.com/rules/axe/4.6/avoid-inline-spacing?application=RuleDescription) | Ensure that text spacing set through style attributes can be adjusted with custom stylesheets | Serious | cat.structure, wcag21aa, wcag1412, ACT | failure | [24afc2](https://act-rules.github.io/rules/24afc2), [9e45ec](https://act-rules.github.io/rules/9e45ec), [78fd32](https://act-rules.github.io/rules/78fd32) | +| [autocomplete-valid](https://dequeuniversity.com/rules/axe/4.7/autocomplete-valid?application=RuleDescription) | Ensure the autocomplete attribute is correct and suitable for the form field | Serious | cat.forms, wcag21aa, wcag135, ACT | failure | [73f2c2](https://act-rules.github.io/rules/73f2c2) | +| [avoid-inline-spacing](https://dequeuniversity.com/rules/axe/4.7/avoid-inline-spacing?application=RuleDescription) | Ensure that text spacing set through style attributes can be adjusted with custom stylesheets | Serious | cat.structure, wcag21aa, wcag1412, ACT | failure | [24afc2](https://act-rules.github.io/rules/24afc2), [9e45ec](https://act-rules.github.io/rules/9e45ec), [78fd32](https://act-rules.github.io/rules/78fd32) | ## WCAG 2.2 Level A & AA Rules @@ -86,7 +86,7 @@ These rules are disabled by default, until WCAG 2.2 is more widely adopted and r | Rule ID | Description | Impact | Tags | Issue Type | ACT Rules | | :----------------------------------------------------------------------------------------------- | :------------------------------------------------- | :------ | :--------------------------------------------- | :------------------------- | :-------- | -| [target-size](https://dequeuniversity.com/rules/axe/4.6/target-size?application=RuleDescription) | Ensure touch target have sufficient size and space | Serious | wcag22aa, wcag258, cat.sensory-and-visual-cues | failure, needs review | | +| [target-size](https://dequeuniversity.com/rules/axe/4.7/target-size?application=RuleDescription) | Ensure touch target have sufficient size and space | Serious | wcag22aa, wcag258, cat.sensory-and-visual-cues | failure, needs review | | ## Best Practices Rules @@ -94,34 +94,34 @@ Rules that do not necessarily conform to WCAG success criterion but are industry | Rule ID | Description | Impact | Tags | Issue Type | ACT Rules | | :----------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------- | :----------------- | :----------------------------------------- | :------------------------- | :------------------------------------------------- | -| [accesskeys](https://dequeuniversity.com/rules/axe/4.6/accesskeys?application=RuleDescription) | Ensures every accesskey attribute value is unique | Serious | cat.keyboard, best-practice | failure | | -| [aria-allowed-role](https://dequeuniversity.com/rules/axe/4.6/aria-allowed-role?application=RuleDescription) | Ensures role attribute has an appropriate value for the element | Minor | cat.aria, best-practice | failure, needs review | | -| [aria-dialog-name](https://dequeuniversity.com/rules/axe/4.6/aria-dialog-name?application=RuleDescription) | Ensures every ARIA dialog and alertdialog node has an accessible name | Serious | cat.aria, best-practice | failure, needs review | | -| [aria-text](https://dequeuniversity.com/rules/axe/4.6/aria-text?application=RuleDescription) | Ensures "role=text" is used on elements with no focusable descendants | Serious | cat.aria, best-practice | failure, needs review | | -| [aria-treeitem-name](https://dequeuniversity.com/rules/axe/4.6/aria-treeitem-name?application=RuleDescription) | Ensures every ARIA treeitem node has an accessible name | Serious | cat.aria, best-practice | failure, needs review | | -| [empty-heading](https://dequeuniversity.com/rules/axe/4.6/empty-heading?application=RuleDescription) | Ensures headings have discernible text | Minor | cat.name-role-value, best-practice | failure, needs review | [ffd0e9](https://act-rules.github.io/rules/ffd0e9) | -| [empty-table-header](https://dequeuniversity.com/rules/axe/4.6/empty-table-header?application=RuleDescription) | Ensures table headers have discernible text | Minor | cat.name-role-value, best-practice | failure, needs review | | -| [frame-tested](https://dequeuniversity.com/rules/axe/4.6/frame-tested?application=RuleDescription) | Ensures <iframe> and <frame> elements contain the axe-core script | Critical | cat.structure, review-item, best-practice | failure, needs review | | -| [heading-order](https://dequeuniversity.com/rules/axe/4.6/heading-order?application=RuleDescription) | Ensures the order of headings is semantically correct | Moderate | cat.semantics, best-practice | failure, needs review | | -| [image-redundant-alt](https://dequeuniversity.com/rules/axe/4.6/image-redundant-alt?application=RuleDescription) | Ensure image alternative is not repeated as text | Minor | cat.text-alternatives, best-practice | failure | | -| [label-title-only](https://dequeuniversity.com/rules/axe/4.6/label-title-only?application=RuleDescription) | Ensures that every form element has a visible label and is not solely labeled using hidden labels, or the title or aria-describedby attributes | Serious | cat.forms, best-practice | failure | | -| [landmark-banner-is-top-level](https://dequeuniversity.com/rules/axe/4.6/landmark-banner-is-top-level?application=RuleDescription) | Ensures the banner landmark is at top level | Moderate | cat.semantics, best-practice | failure | | -| [landmark-complementary-is-top-level](https://dequeuniversity.com/rules/axe/4.6/landmark-complementary-is-top-level?application=RuleDescription) | Ensures the complementary landmark or aside is at top level | Moderate | cat.semantics, best-practice | failure | | -| [landmark-contentinfo-is-top-level](https://dequeuniversity.com/rules/axe/4.6/landmark-contentinfo-is-top-level?application=RuleDescription) | Ensures the contentinfo landmark is at top level | Moderate | cat.semantics, best-practice | failure | | -| [landmark-main-is-top-level](https://dequeuniversity.com/rules/axe/4.6/landmark-main-is-top-level?application=RuleDescription) | Ensures the main landmark is at top level | Moderate | cat.semantics, best-practice | failure | | -| [landmark-no-duplicate-banner](https://dequeuniversity.com/rules/axe/4.6/landmark-no-duplicate-banner?application=RuleDescription) | Ensures the document has at most one banner landmark | Moderate | cat.semantics, best-practice | failure | | -| [landmark-no-duplicate-contentinfo](https://dequeuniversity.com/rules/axe/4.6/landmark-no-duplicate-contentinfo?application=RuleDescription) | Ensures the document has at most one contentinfo landmark | Moderate | cat.semantics, best-practice | failure | | -| [landmark-no-duplicate-main](https://dequeuniversity.com/rules/axe/4.6/landmark-no-duplicate-main?application=RuleDescription) | Ensures the document has at most one main landmark | Moderate | cat.semantics, best-practice | failure | | -| [landmark-one-main](https://dequeuniversity.com/rules/axe/4.6/landmark-one-main?application=RuleDescription) | Ensures the document has a main landmark | Moderate | cat.semantics, best-practice | failure | | -| [landmark-unique](https://dequeuniversity.com/rules/axe/4.6/landmark-unique?application=RuleDescription) | Landmarks should have a unique role or role/label/title (i.e. accessible name) combination | Moderate | cat.semantics, best-practice | failure | | -| [meta-viewport-large](https://dequeuniversity.com/rules/axe/4.6/meta-viewport-large?application=RuleDescription) | Ensures <meta name="viewport"> can scale a significant amount | Minor | cat.sensory-and-visual-cues, best-practice | failure | | -| [page-has-heading-one](https://dequeuniversity.com/rules/axe/4.6/page-has-heading-one?application=RuleDescription) | Ensure that the page, or at least one of its frames contains a level-one heading | Moderate | cat.semantics, best-practice | failure | | -| [presentation-role-conflict](https://dequeuniversity.com/rules/axe/4.6/presentation-role-conflict?application=RuleDescription) | Elements marked as presentational should not have global ARIA or tabindex to ensure all screen readers ignore them | Minor | cat.aria, best-practice, ACT | failure | [46ca7f](https://act-rules.github.io/rules/46ca7f) | -| [region](https://dequeuniversity.com/rules/axe/4.6/region?application=RuleDescription) | Ensures all page content is contained by landmarks | Moderate | cat.keyboard, best-practice | failure | | -| [scope-attr-valid](https://dequeuniversity.com/rules/axe/4.6/scope-attr-valid?application=RuleDescription) | Ensures the scope attribute is used correctly on tables | Moderate, Critical | cat.tables, best-practice | failure | | -| [skip-link](https://dequeuniversity.com/rules/axe/4.6/skip-link?application=RuleDescription) | Ensure all skip links have a focusable target | Moderate | cat.keyboard, best-practice | failure, needs review | | -| [tabindex](https://dequeuniversity.com/rules/axe/4.6/tabindex?application=RuleDescription) | Ensures tabindex attribute values are not greater than 0 | Serious | cat.keyboard, best-practice | failure | | -| [table-duplicate-name](https://dequeuniversity.com/rules/axe/4.6/table-duplicate-name?application=RuleDescription) | Ensure the <caption> element does not contain the same text as the summary attribute | Minor | cat.tables, best-practice | failure, needs review | | +| [accesskeys](https://dequeuniversity.com/rules/axe/4.7/accesskeys?application=RuleDescription) | Ensures every accesskey attribute value is unique | Serious | cat.keyboard, best-practice | failure | | +| [aria-allowed-role](https://dequeuniversity.com/rules/axe/4.7/aria-allowed-role?application=RuleDescription) | Ensures role attribute has an appropriate value for the element | Minor | cat.aria, best-practice | failure, needs review | | +| [aria-dialog-name](https://dequeuniversity.com/rules/axe/4.7/aria-dialog-name?application=RuleDescription) | Ensures every ARIA dialog and alertdialog node has an accessible name | Serious | cat.aria, best-practice | failure, needs review | | +| [aria-text](https://dequeuniversity.com/rules/axe/4.7/aria-text?application=RuleDescription) | Ensures "role=text" is used on elements with no focusable descendants | Serious | cat.aria, best-practice | failure, needs review | | +| [aria-treeitem-name](https://dequeuniversity.com/rules/axe/4.7/aria-treeitem-name?application=RuleDescription) | Ensures every ARIA treeitem node has an accessible name | Serious | cat.aria, best-practice | failure, needs review | | +| [empty-heading](https://dequeuniversity.com/rules/axe/4.7/empty-heading?application=RuleDescription) | Ensures headings have discernible text | Minor | cat.name-role-value, best-practice | failure, needs review | [ffd0e9](https://act-rules.github.io/rules/ffd0e9) | +| [empty-table-header](https://dequeuniversity.com/rules/axe/4.7/empty-table-header?application=RuleDescription) | Ensures table headers have discernible text | Minor | cat.name-role-value, best-practice | failure, needs review | | +| [frame-tested](https://dequeuniversity.com/rules/axe/4.7/frame-tested?application=RuleDescription) | Ensures <iframe> and <frame> elements contain the axe-core script | Critical | cat.structure, review-item, best-practice | failure, needs review | | +| [heading-order](https://dequeuniversity.com/rules/axe/4.7/heading-order?application=RuleDescription) | Ensures the order of headings is semantically correct | Moderate | cat.semantics, best-practice | failure, needs review | | +| [image-redundant-alt](https://dequeuniversity.com/rules/axe/4.7/image-redundant-alt?application=RuleDescription) | Ensure image alternative is not repeated as text | Minor | cat.text-alternatives, best-practice | failure | | +| [label-title-only](https://dequeuniversity.com/rules/axe/4.7/label-title-only?application=RuleDescription) | Ensures that every form element has a visible label and is not solely labeled using hidden labels, or the title or aria-describedby attributes | Serious | cat.forms, best-practice | failure | | +| [landmark-banner-is-top-level](https://dequeuniversity.com/rules/axe/4.7/landmark-banner-is-top-level?application=RuleDescription) | Ensures the banner landmark is at top level | Moderate | cat.semantics, best-practice | failure | | +| [landmark-complementary-is-top-level](https://dequeuniversity.com/rules/axe/4.7/landmark-complementary-is-top-level?application=RuleDescription) | Ensures the complementary landmark or aside is at top level | Moderate | cat.semantics, best-practice | failure | | +| [landmark-contentinfo-is-top-level](https://dequeuniversity.com/rules/axe/4.7/landmark-contentinfo-is-top-level?application=RuleDescription) | Ensures the contentinfo landmark is at top level | Moderate | cat.semantics, best-practice | failure | | +| [landmark-main-is-top-level](https://dequeuniversity.com/rules/axe/4.7/landmark-main-is-top-level?application=RuleDescription) | Ensures the main landmark is at top level | Moderate | cat.semantics, best-practice | failure | | +| [landmark-no-duplicate-banner](https://dequeuniversity.com/rules/axe/4.7/landmark-no-duplicate-banner?application=RuleDescription) | Ensures the document has at most one banner landmark | Moderate | cat.semantics, best-practice | failure | | +| [landmark-no-duplicate-contentinfo](https://dequeuniversity.com/rules/axe/4.7/landmark-no-duplicate-contentinfo?application=RuleDescription) | Ensures the document has at most one contentinfo landmark | Moderate | cat.semantics, best-practice | failure | | +| [landmark-no-duplicate-main](https://dequeuniversity.com/rules/axe/4.7/landmark-no-duplicate-main?application=RuleDescription) | Ensures the document has at most one main landmark | Moderate | cat.semantics, best-practice | failure | | +| [landmark-one-main](https://dequeuniversity.com/rules/axe/4.7/landmark-one-main?application=RuleDescription) | Ensures the document has a main landmark | Moderate | cat.semantics, best-practice | failure | | +| [landmark-unique](https://dequeuniversity.com/rules/axe/4.7/landmark-unique?application=RuleDescription) | Landmarks should have a unique role or role/label/title (i.e. accessible name) combination | Moderate | cat.semantics, best-practice | failure | | +| [meta-viewport-large](https://dequeuniversity.com/rules/axe/4.7/meta-viewport-large?application=RuleDescription) | Ensures <meta name="viewport"> can scale a significant amount | Minor | cat.sensory-and-visual-cues, best-practice | failure | | +| [page-has-heading-one](https://dequeuniversity.com/rules/axe/4.7/page-has-heading-one?application=RuleDescription) | Ensure that the page, or at least one of its frames contains a level-one heading | Moderate | cat.semantics, best-practice | failure | | +| [presentation-role-conflict](https://dequeuniversity.com/rules/axe/4.7/presentation-role-conflict?application=RuleDescription) | Elements marked as presentational should not have global ARIA or tabindex to ensure all screen readers ignore them | Minor | cat.aria, best-practice, ACT | failure | [46ca7f](https://act-rules.github.io/rules/46ca7f) | +| [region](https://dequeuniversity.com/rules/axe/4.7/region?application=RuleDescription) | Ensures all page content is contained by landmarks | Moderate | cat.keyboard, best-practice | failure | | +| [scope-attr-valid](https://dequeuniversity.com/rules/axe/4.7/scope-attr-valid?application=RuleDescription) | Ensures the scope attribute is used correctly on tables | Moderate, Critical | cat.tables, best-practice | failure | | +| [skip-link](https://dequeuniversity.com/rules/axe/4.7/skip-link?application=RuleDescription) | Ensure all skip links have a focusable target | Moderate | cat.keyboard, best-practice | failure, needs review | | +| [tabindex](https://dequeuniversity.com/rules/axe/4.7/tabindex?application=RuleDescription) | Ensures tabindex attribute values are not greater than 0 | Serious | cat.keyboard, best-practice | failure | | +| [table-duplicate-name](https://dequeuniversity.com/rules/axe/4.7/table-duplicate-name?application=RuleDescription) | Ensure the <caption> element does not contain the same text as the summary attribute | Minor | cat.tables, best-practice | failure, needs review | | ## WCAG 2.x level AAA rules @@ -129,9 +129,9 @@ Rules that check for conformance to WCAG AAA success criteria that can be fully | Rule ID | Description | Impact | Tags | Issue Type | ACT Rules | | :--------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------- | :------ | :--------------------------------------------- | :------------------------- | :------------------------------------------------- | -| [color-contrast-enhanced](https://dequeuniversity.com/rules/axe/4.6/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.6/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.6/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) | +| [color-contrast-enhanced](https://dequeuniversity.com/rules/axe/4.7/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.7/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.7/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 @@ -139,13 +139,13 @@ Rules we are still testing and developing. They are disabled by default in axe-c | Rule ID | Description | Impact | Tags | Issue Type | ACT Rules | | :------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------- | :------- | :--------------------------------------------------------------------- | :------------------------- | :------------------------------------------------- | -| [css-orientation-lock](https://dequeuniversity.com/rules/axe/4.6/css-orientation-lock?application=RuleDescription) | Ensures content is not locked to any specific display orientation, and the content is operable in all display orientations | Serious | cat.structure, wcag134, wcag21aa, experimental | failure, needs review | [b33eff](https://act-rules.github.io/rules/b33eff) | -| [focus-order-semantics](https://dequeuniversity.com/rules/axe/4.6/focus-order-semantics?application=RuleDescription) | Ensures elements in the focus order have a role appropriate for interactive content | Minor | cat.keyboard, best-practice, experimental | failure | | -| [hidden-content](https://dequeuniversity.com/rules/axe/4.6/hidden-content?application=RuleDescription) | Informs users about hidden content. | Minor | cat.structure, experimental, review-item, best-practice | failure, needs review | | -| [label-content-name-mismatch](https://dequeuniversity.com/rules/axe/4.6/label-content-name-mismatch?application=RuleDescription) | Ensures that elements labelled through their content must have their visible text as part of their accessible name | Serious | cat.semantics, wcag21a, wcag253, experimental | failure | [2ee8b8](https://act-rules.github.io/rules/2ee8b8) | -| [p-as-heading](https://dequeuniversity.com/rules/axe/4.6/p-as-heading?application=RuleDescription) | Ensure bold, italic text and font-size is not used to style <p> elements as a heading | Serious | cat.semantics, wcag2a, wcag131, experimental | failure, needs review | | -| [table-fake-caption](https://dequeuniversity.com/rules/axe/4.6/table-fake-caption?application=RuleDescription) | Ensure that tables with a caption use the <caption> element. | Serious | cat.tables, experimental, wcag2a, wcag131, section508, section508.22.g | failure | | -| [td-has-header](https://dequeuniversity.com/rules/axe/4.6/td-has-header?application=RuleDescription) | Ensure that each non-empty data cell in a <table> larger than 3 by 3 has one or more table headers | Critical | cat.tables, experimental, wcag2a, wcag131, section508, section508.22.g | failure | | +| [css-orientation-lock](https://dequeuniversity.com/rules/axe/4.7/css-orientation-lock?application=RuleDescription) | Ensures content is not locked to any specific display orientation, and the content is operable in all display orientations | Serious | cat.structure, wcag134, wcag21aa, experimental | failure, needs review | [b33eff](https://act-rules.github.io/rules/b33eff) | +| [focus-order-semantics](https://dequeuniversity.com/rules/axe/4.7/focus-order-semantics?application=RuleDescription) | Ensures elements in the focus order have a role appropriate for interactive content | Minor | cat.keyboard, best-practice, experimental | failure | | +| [hidden-content](https://dequeuniversity.com/rules/axe/4.7/hidden-content?application=RuleDescription) | Informs users about hidden content. | Minor | cat.structure, experimental, review-item, best-practice | failure, needs review | | +| [label-content-name-mismatch](https://dequeuniversity.com/rules/axe/4.7/label-content-name-mismatch?application=RuleDescription) | Ensures that elements labelled through their content must have their visible text as part of their accessible name | Serious | cat.semantics, wcag21a, wcag253, experimental | failure | [2ee8b8](https://act-rules.github.io/rules/2ee8b8) | +| [p-as-heading](https://dequeuniversity.com/rules/axe/4.7/p-as-heading?application=RuleDescription) | Ensure bold, italic text and font-size is not used to style <p> elements as a heading | Serious | cat.semantics, wcag2a, wcag131, experimental | failure, needs review | | +| [table-fake-caption](https://dequeuniversity.com/rules/axe/4.7/table-fake-caption?application=RuleDescription) | Ensure that tables with a caption use the <caption> element. | Serious | cat.tables, experimental, wcag2a, wcag131, section508, section508.22.g | failure | | +| [td-has-header](https://dequeuniversity.com/rules/axe/4.7/td-has-header?application=RuleDescription) | Ensure that each non-empty data cell in a <table> larger than 3 by 3 has one or more table headers | Critical | cat.tables, experimental, wcag2a, wcag131, section508, section508.22.g | failure | | ## Deprecated Rules diff --git a/package-lock.json b/package-lock.json index b7449d9ef4..cd2f4adc1f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "axe-core", - "version": "4.6.2", + "version": "4.7.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "axe-core", - "version": "4.6.2", + "version": "4.7.0", "license": "MPL-2.0", "devDependencies": { "@axe-core/webdriverjs": "^4.5.2", diff --git a/package.json b/package.json index def8957863..cd36437dc8 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "axe-core", "description": "Accessibility engine for automated Web UI testing", - "version": "4.6.2", + "version": "4.7.0", "license": "MPL-2.0", "engines": { "node": ">=4" diff --git a/sri-history.json b/sri-history.json index c357cabf3f..3a1ecae465 100644 --- a/sri-history.json +++ b/sri-history.json @@ -334,5 +334,9 @@ "4.6.2": { "axe.js": "sha256-6BCLF6TcLdHG7Ok3yyV7HOKF/Se1yJQgzgAiz3AnzX0=", "axe.min.js": "sha256-US+MWxPC7r+aFzKfSCl+effrzN0Qoz4tS2wxlIpmsCM=" + }, + "4.7.0": { + "axe.js": "sha256-ZETQEPTBfZtHwDnVXUrlT5xdl5QeJD/Cq2FUCEhPFys=", + "axe.min.js": "sha256-rTZxWDRhW9b+HgKBkzvRbTZNzotXl+j0YXZgrgYVXZc=" } }