From c1af750743d5c1ca369f55fd04dd0636edda612e Mon Sep 17 00:00:00 2001 From: Wilco Fiers Date: Wed, 19 Oct 2022 11:50:17 +0200 Subject: [PATCH 1/9] docs(readme): add new locales (#3732) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index f63f8e3946..5c9a5ecef6 100644 --- a/README.md +++ b/README.md @@ -144,8 +144,10 @@ Axe-core supports the following locales. Do note that since locales are contribu - Dutch - French - German +- Hebrew - Japanese - Korean +- Norwegian (BokmÃ¥l) - Polish - Portuguese (Brazilian) - Spanish From 30218777e41386048b1f61aab052248e25a48e56 Mon Sep 17 00:00:00 2001 From: Steven Lambert <2433219+straker@users.noreply.github.com> Date: Fri, 21 Oct 2022 11:15:15 -0600 Subject: [PATCH 2/9] ci: fix chrome integration tests and split browser tests (#3735) --- .circleci/config.yml | 43 +++++++---- test/integration/full/test-webdriver.js | 99 +++++++------------------ 2 files changed, 57 insertions(+), 85 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index e78803f565..1614d85370 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -51,7 +51,7 @@ jobs: - run: npm run eslint # Run the test suite. - test_unix: + test_chrome: <<: *defaults <<: *unix_box steps: @@ -60,8 +60,18 @@ jobs: - <<: *restore_dependency_cache_unix - run: npx browser-driver-manager install chromedriver --verbose - run: npm run build - - run: npm run test -- --browsers Chrome,Firefox + - run: npm run test -- --browsers Chrome - run: npm run test:integration:chrome + + test_firefox: + <<: *defaults + <<: *unix_box + steps: + - browser-tools/install-browser-tools + - checkout + - <<: *restore_dependency_cache_unix + - run: npm run build + - run: npm run test -- --browsers Firefox - run: npm run test:integration:firefox # Run examples under `doc/examples` @@ -276,38 +286,41 @@ workflows: requires: - dependencies_unix # Run tests on all commits, but after installing dependencies - - test_unix: + - test_chrome: requires: - lint + - test_firefox: + requires: + - test_chrome - test_examples: requires: - - test_unix + - test_chrome - test_act: requires: - - test_unix + - test_chrome - test_aria_practices: requires: - - test_unix + - test_chrome - test_locales: requires: - - test_unix + - test_chrome - test_virtual_rules: requires: - - test_unix + - test_chrome - build_api_docs: requires: - - test_unix + - test_chrome - test_rule_help_version: requires: - - test_unix + - test_chrome - test_node: requires: - - test_unix + - test_chrome # Hold for approval - hold: type: approval requires: - - test_unix + - test_chrome - test_examples - test_locales - test_virtual_rules @@ -322,7 +335,8 @@ workflows: - next_release: requires: - dependencies_unix - - test_unix + - test_chrome + - test_firefox - test_examples - test_locales - test_virtual_rules @@ -334,7 +348,8 @@ workflows: - release: requires: - dependencies_unix - - test_unix + - test_chrome + - test_firefox - test_examples - test_locales - test_virtual_rules diff --git a/test/integration/full/test-webdriver.js b/test/integration/full/test-webdriver.js index cefddf01bb..01aacf2c53 100644 --- a/test/integration/full/test-webdriver.js +++ b/test/integration/full/test-webdriver.js @@ -1,18 +1,18 @@ /*global window, Promise */ -var globby = require('globby'); -var WebDriver = require('selenium-webdriver'); -var chrome = require('selenium-webdriver/chrome'); -var chromedriver = require('chromedriver'); +const globby = require('globby'); +const chrome = require('selenium-webdriver/chrome'); +const firefox = require('selenium-webdriver/firefox'); +const chromedriver = require('chromedriver'); -var args = process.argv.slice(2); +const args = process.argv.slice(2); // allow running certain browsers through command line args // (only one browser supported, run multiple times for more browsers) -var browser = 'chrome'; +let browser = 'chrome'; args.forEach(function (arg) { // pattern: browsers=Chrome - var parts = arg.split('='); + const parts = arg.split('='); if (parts[0] === 'browser') { browser = parts[1].toLowerCase(); } @@ -25,7 +25,7 @@ function collectTestResults(driver) { // inject a script that waits half a second return driver .executeAsyncScript(function () { - var callback = arguments[arguments.length - 1]; + const callback = arguments[arguments.length - 1]; setTimeout(function () { if (!window.mocha) { callback('mocha-missing;' + window.location.href); @@ -57,7 +57,7 @@ function collectTestResults(driver) { * Test each URL */ function runTestUrls(driver, isMobile, urls, errors) { - var url = urls.shift(); + const url = urls.shift(); errors = errors || []; return ( @@ -72,9 +72,9 @@ function runTestUrls(driver, isMobile, urls, errors) { }) // And process them .then(function (promiseResults) { - var capabilities = promiseResults[0]; - var result = promiseResults[1]; - var browserName = + const capabilities = promiseResults[0]; + const result = promiseResults[1]; + const browserName = capabilities.get('browserName') + (capabilities.get('mobileEmulationEnabled') ? '-mobile' : ''); console.log(url + ' [' + browserName + ']'); @@ -117,80 +117,45 @@ function runTestUrls(driver, isMobile, urls, errors) { * Build web driver depends whether REMOTE_SELENIUM_URL is set */ function buildWebDriver(browser) { - // Pinned to selenium-webdriver@4.3.0 - // https://github.com/SeleniumHQ/selenium/pull/10796/files#diff-6c87d95a2288e92e15a6bb17710c763c01c2290e679beb26220858f3218b6a62L260 - - var capabilities; - var mobileBrowser = browser.split('-mobile'); - - if (mobileBrowser.length > 1) { - browser = mobileBrowser[0]; - capabilities = { - browserName: mobileBrowser[0], - chromeOptions: { - mobileEmulation: { - deviceMetrics: { - width: 320, - height: 568, - pixelRatio: 2 - } - } - } - }; - } + let webdriver; + const mobileBrowser = browser.split('-mobile'); // fix chrome DevToolsActivePort file doesn't exist in CricleCI (as well as a // host of other problems with starting Chrome). the only thing that seems to // allow Chrome to start without problems consistently is using ChromeHeadless // @see https://stackoverflow.com/questions/50642308/webdriverexception-unknown-error-devtoolsactiveport-file-doesnt-exist-while-t if (browser === 'chrome') { - var service = new chrome.ServiceBuilder(chromedriver.path).build(); - chrome.setDefaultService(service); + const service = new chrome.ServiceBuilder(chromedriver.path).build(); - capabilities = WebDriver.Capabilities.chrome(); - capabilities.set('chromeOptions', { - args: [ + const options = new chrome.Options() + .headless() + .addArguments([ '--no-sandbox', - '--headless', '--disable-extensions', '--disable-dev-shm-usage' - ] - }); + ]); + webdriver = chrome.Driver.createSession(options, service); + } else if (browser === 'firefox') { + const options = new firefox.Options().headless(); + webdriver = firefox.Driver.createSession(options); } - var webdriver = new WebDriver.Builder() - .withCapabilities(capabilities) - .forBrowser(browser); - if (process.env.REMOTE_SELENIUM_URL) { webdriver.usingServer(process.env.REMOTE_SELENIUM_URL); } - // @see https://github.com/SeleniumHQ/selenium/issues/6026 - if (browser === 'safari') { - var safari = require('selenium-webdriver/safari'); - var server = new safari.ServiceBuilder() - .addArguments('--legacy') - .build() - .start(); - - webdriver.usingServer(server); - } - return { - driver: webdriver.build(), + driver: webdriver, isMobile: mobileBrowser.length > 1 }; } function start(options) { - var driver; - var isMobile = false; // yes, really, and this isn't documented anywhere either. options.browser = options.browser === 'edge' ? 'MicrosoftEdge' : options.browser; - var testUrls = globby + const testUrls = globby .sync([ 'test/integration/full/**/*.{html,xhtml}', '!**/frames/**/*.{html,xhtml}' @@ -214,17 +179,9 @@ function start(options) { } // try to load the browser - try { - var webDriver = buildWebDriver(options.browser); - driver = webDriver.driver; - isMobile = webDriver.isMobile; - // If load fails, warn user and move to the next task - } catch (err) { - console.log(); - console.log(err.message); - console.log('Aborted testing using ' + options.browser); - return process.exit(); - } + const webDriver = buildWebDriver(options.browser); + const driver = webDriver.driver; + const isMobile = webDriver.isMobile; driver.manage().setTimeouts({ pageLoad: 50000, From 437f707caa89d9ab4906849fb71965035644a8f7 Mon Sep 17 00:00:00 2001 From: Wilco Fiers Date: Mon, 24 Oct 2022 11:06:20 +0200 Subject: [PATCH 3/9] chore(target-size): fix typo in tag (#3738) --- doc/rule-descriptions.md | 6 +++--- lib/rules/target-size.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/rule-descriptions.md b/doc/rule-descriptions.md index b17be0dd2b..3f2fa5fc82 100644 --- a/doc/rule-descriptions.md +++ b/doc/rule-descriptions.md @@ -84,9 +84,9 @@ These rules are disabled by default, until WCAG 2.2 is more widely adopted and required. -| Rule ID | Description | Impact | Tags | Issue Type | ACT Rules | -| :----------------------------------------------------------------------------------------------- | :------------------------------------------------- | :------ | :------------------------------------------- | :------------------------- | :-------- | -| [target-size](https://dequeuniversity.com/rules/axe/4.4/target-size?application=RuleDescription) | Ensure touch target have sufficient size and space | Serious | wcag22aa, sc258, cat.sensory-and-visual-cues | failure, needs review | | +| Rule ID | Description | Impact | Tags | Issue Type | ACT Rules | +| :----------------------------------------------------------------------------------------------- | :------------------------------------------------- | :------ | :--------------------------------------------- | :------------------------- | :-------- | +| [target-size](https://dequeuniversity.com/rules/axe/4.4/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 diff --git a/lib/rules/target-size.json b/lib/rules/target-size.json index 674044ff9f..7891718522 100644 --- a/lib/rules/target-size.json +++ b/lib/rules/target-size.json @@ -3,7 +3,7 @@ "selector": "*", "enabled": false, "matches": "widget-not-inline-matches", - "tags": ["wcag22aa", "sc258", "cat.sensory-and-visual-cues"], + "tags": ["wcag22aa", "wcag258", "cat.sensory-and-visual-cues"], "metadata": { "description": "Ensure touch target have sufficient size and space", "help": "All touch targets must be 24px large, or leave sufficient space" From 5b94565bbd244cb5601096ec9176354211db0a3e Mon Sep 17 00:00:00 2001 From: Steven Lambert <2433219+straker@users.noreply.github.com> Date: Wed, 26 Oct 2022 14:05:08 -0600 Subject: [PATCH 4/9] chore: npm ci for generated files action (#3750) --- .github/workflows/update-generated-files.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update-generated-files.yaml b/.github/workflows/update-generated-files.yaml index c2d4c3ed06..dc2889cdd7 100644 --- a/.github/workflows/update-generated-files.yaml +++ b/.github/workflows/update-generated-files.yaml @@ -19,7 +19,7 @@ jobs: - name: Build run: | - npm install + npm ci npm run build - name: Check for changes From 213ad5c2b1e2929bc0d6a1cef1d189010d4e11a2 Mon Sep 17 00:00:00 2001 From: Stephen Mathieson Date: Thu, 27 Oct 2022 08:36:55 -0400 Subject: [PATCH 5/9] ci: Add action for automatically running Prettier (#3727) * ci: Add action for automatically running Prettier This patch sets up a GitHub Action for automatically running Prettier. Now that #3725 has landed, automatically running Prettier shouldn't [generate too much noise](https://github.com/dequelabs/axe-core/pull/3631#discussion_r963942942). This will prevent needing to spend time opening PRs just for running Prettier, and enables us to remove some of the Grunt code for doing so. * an unpretty change * Prettified Code! Co-authored-by: stephenmathieson --- .github/workflows/format.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .github/workflows/format.yml diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml new file mode 100644 index 0000000000..da41415c6e --- /dev/null +++ b/.github/workflows/format.yml @@ -0,0 +1,17 @@ +name: Formatter + +on: [pull_request] + +jobs: + prettier: + runs-on: ubuntu-latest + steps: + - name: Cloning the repository + uses: actions/checkout@v3 + with: + ref: ${{ github.head_ref }} + fetch-depth: 0 + - name: Prettify the code + uses: creyD/prettier_action@v4.2 + with: + prettier_options: '--write .' From d6b214437c7fbd96ecce22ef716e1ad5be8fcea3 Mon Sep 17 00:00:00 2001 From: Stephen Mathieson Date: Mon, 31 Oct 2022 10:15:04 -0400 Subject: [PATCH 6/9] ci: Simplify formatter workflow (#3757) --- .github/workflows/format.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index da41415c6e..229ac1df47 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -6,11 +6,7 @@ jobs: prettier: runs-on: ubuntu-latest steps: - - name: Cloning the repository - uses: actions/checkout@v3 - with: - ref: ${{ github.head_ref }} - fetch-depth: 0 + - uses: actions/checkout@v3 - name: Prettify the code uses: creyD/prettier_action@v4.2 with: From b74c5d41c4041554c9dd1c00dfd6387cb069d1a5 Mon Sep 17 00:00:00 2001 From: Steven Lambert <2433219+straker@users.noreply.github.com> Date: Mon, 31 Oct 2022 08:17:45 -0600 Subject: [PATCH 7/9] fix: allow axe to run in certain configurations of jsdom (#3755) * fix: allow axe to run in certain configurations of jsdom * have eslint prevent * remove * more explicit --- .eslintrc.js | 20 +++++++++++++++++-- lib/commons/color/get-background-stack.js | 2 +- lib/core/utils/dq-element.js | 4 ++-- .../utils/parse-crossorigin-stylesheet.js | 2 +- lib/core/utils/pollyfills.js | 5 ++--- 5 files changed, 24 insertions(+), 9 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index b62b93d8ba..855c45f454 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -76,7 +76,8 @@ module.exports = { sourceType: 'module' }, env: { - browser: true, + // do not access global window properties without going through window + browser: false, es6: true }, globals: { @@ -95,7 +96,9 @@ module.exports = { parserOptions: { sourceType: 'module' }, - env: {}, + env: { + browser: false + }, globals: {}, rules: { 'func-names': [2, 'as-needed'], @@ -103,6 +106,19 @@ module.exports = { 'no-use-before-define': 'off' } }, + { + // polyfills are mostly copy-pasted from sources so we don't control their styling + files: ['lib/core/utils/pollyfills.js'], + env: { + browser: false + }, + rules: { + 'func-names': 0, + 'no-bitwise': 0, + curly: 0, + eqeqeq: 0 + } + }, { files: ['test/act-rules/**/*.js', 'test/aria-practices/**/*.js'], env: { diff --git a/lib/commons/color/get-background-stack.js b/lib/commons/color/get-background-stack.js index a37833eb9f..87225e2b5d 100644 --- a/lib/commons/color/get-background-stack.js +++ b/lib/commons/color/get-background-stack.js @@ -12,7 +12,7 @@ import reduceToElementsBelowFloating from '../dom/reduce-to-elements-below-float * @return {Boolean} */ function isInlineDescendant(node, descendant) { - const CONTAINED_BY = Node.DOCUMENT_POSITION_CONTAINED_BY; + const CONTAINED_BY = window.Node.DOCUMENT_POSITION_CONTAINED_BY; // eslint-disable-next-line no-bitwise if (!(node.compareDocumentPosition(descendant) & CONTAINED_BY)) { return false; diff --git a/lib/core/utils/dq-element.js b/lib/core/utils/dq-element.js index 4e5d0ffc28..db1c5f65bb 100644 --- a/lib/core/utils/dq-element.js +++ b/lib/core/utils/dq-element.js @@ -20,8 +20,8 @@ function getSource(element) { return ''; } var source = element.outerHTML; - if (!source && typeof XMLSerializer === 'function') { - source = new XMLSerializer().serializeToString(element); + if (!source && typeof window.XMLSerializer === 'function') { + source = new window.XMLSerializer().serializeToString(element); } return truncate(source || ''); } diff --git a/lib/core/utils/parse-crossorigin-stylesheet.js b/lib/core/utils/parse-crossorigin-stylesheet.js index 1a504216ba..3ec44fa526 100644 --- a/lib/core/utils/parse-crossorigin-stylesheet.js +++ b/lib/core/utils/parse-crossorigin-stylesheet.js @@ -26,7 +26,7 @@ function parseCrossOriginStylesheet( importedUrls.push(url); return new Promise((resolve, reject) => { - const request = new XMLHttpRequest(); + const request = new window.XMLHttpRequest(); request.open('GET', url); request.timeout = constants.preload.timeout; diff --git a/lib/core/utils/pollyfills.js b/lib/core/utils/pollyfills.js index fe1de7f354..6829b80dc8 100644 --- a/lib/core/utils/pollyfills.js +++ b/lib/core/utils/pollyfills.js @@ -1,4 +1,3 @@ -/* eslint-disable */ /* These polyfills came directly from the ES Specification itself Contained within: @@ -348,8 +347,8 @@ if (!Array.prototype.flat) { // linked from MDN docs on isConnected // @see https://gist.github.com/eligrey/f109a6d0bf4efe3461201c3d7b745e8f -if (window.Node && !('isConnected' in Node.prototype)) { - Object.defineProperty(Node.prototype, 'isConnected', { +if (window.Node && !('isConnected' in window.Node.prototype)) { + Object.defineProperty(window.Node.prototype, 'isConnected', { get() { return ( !this.ownerDocument || From b1f0c6bba2debc6c6a106412da530975cd4ade24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ari=20Perkki=C3=B6?= Date: Tue, 1 Nov 2022 16:33:57 +0200 Subject: [PATCH 8/9] fix: prevent crash on jsdom when preloading CSSOM (#3754) * fix: prevent crash on jsdom - cssom package does not implement StyleSheet.media * trigger build? Co-authored-by: Steven Lambert --- lib/core/utils/preload-cssom.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/core/utils/preload-cssom.js b/lib/core/utils/preload-cssom.js index 43c2ffcc24..c919d023c4 100644 --- a/lib/core/utils/preload-cssom.js +++ b/lib/core/utils/preload-cssom.js @@ -187,9 +187,13 @@ function getStylesheetsFromDocumentFragment(rootNode, convertDataToStylesheet) { * @returns {Array} */ function getStylesheetsFromDocument(rootNode) { - return Array.from(rootNode.styleSheets).filter(sheet => - filterMediaIsPrint(sheet.media.mediaText) - ); + return Array.from(rootNode.styleSheets).filter(sheet => { + if (!sheet.media) { + return false; + } + + return filterMediaIsPrint(sheet.media.mediaText); + }); } /** From a9cc7de5de4339d580385ea5f43f84483e3c5f07 Mon Sep 17 00:00:00 2001 From: Steven Lambert Date: Tue, 1 Nov 2022 08:35:34 -0600 Subject: [PATCH 9/9] chore(release): 4.5.1 --- CHANGELOG.md | 7 +++++++ bower.json | 2 +- package-lock.json | 4 ++-- package.json | 2 +- sri-history.json | 4 ++++ 5 files changed, 15 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72fc4ce829..e388128a10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ 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.5.1](https://github.com/dequelabs/axe-core/compare/v4.5.0...v4.5.1) (2022-11-01) + +### Bug Fixes + +- allow axe to run in certain configurations of jsdom ([#3755](https://github.com/dequelabs/axe-core/issues/3755)) ([b74c5d4](https://github.com/dequelabs/axe-core/commit/b74c5d41c4041554c9dd1c00dfd6387cb069d1a5)) +- prevent crash on jsdom when preloading CSSOM ([#3754](https://github.com/dequelabs/axe-core/issues/3754)) ([b1f0c6b](https://github.com/dequelabs/axe-core/commit/b1f0c6bba2debc6c6a106412da530975cd4ade24)) + ## [4.5.0](https://github.com/dequelabs/axe-core/compare/v4.4.3...v4.5.0) (2022-10-17) ### Features diff --git a/bower.json b/bower.json index d1efa81b51..3948a8c295 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "axe-core", - "version": "4.5.0", + "version": "4.5.1", "contributors": [ { "name": "David Sturley", diff --git a/package-lock.json b/package-lock.json index 074c15d411..e280668ef4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "axe-core", - "version": "4.5.0", + "version": "4.5.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "axe-core", - "version": "4.5.0", + "version": "4.5.1", "license": "MPL-2.0", "devDependencies": { "@axe-core/webdriverjs": "^4.4.3", diff --git a/package.json b/package.json index 3524bc81eb..93898692fa 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "axe-core", "description": "Accessibility engine for automated Web UI testing", - "version": "4.5.0", + "version": "4.5.1", "license": "MPL-2.0", "engines": { "node": ">=4" diff --git a/sri-history.json b/sri-history.json index a89094be13..d314f12a0a 100644 --- a/sri-history.json +++ b/sri-history.json @@ -314,5 +314,9 @@ "4.5.0": { "axe.js": "sha256-AYLBIQscniY92RkIlsESUAIu3cOplhUmJ3Y4/DKR4SE=", "axe.min.js": "sha256-cdG6H1F9kSiSIpyWgjGYXkbV3mcfc6/SvE7Zbq2km/A=" + }, + "4.5.1": { + "axe.js": "sha256-IkK+029qUdULyO88zkDU2TeO5kQB8AjncJvjmFKqBHQ=", + "axe.min.js": "sha256-Ost3Bp9ymk0FCZFL9pOU2g/ph8u06GuVCm8go6W+THw=" } }