From 68741de3b6bf96ee7c576fde9e1d2be5f815ef6d Mon Sep 17 00:00:00 2001 From: Stephen Mathieson Date: Mon, 21 Jan 2019 06:51:42 -0500 Subject: [PATCH] feat: add a reference to the `node` a rule failed on (#1321) This patch adds a `.node` reference to an errored rule result. This can be used to determine which node the rule errored on and will be helpful for debugging purposes. Closes #1317. ## Reviewer checks **Required fields, to be filled out by PR reviewer(s)** - [x] Follows the commit message policy, appropriate for next version - [x] Has documentation updated, a DU ticket, or requires no documentation change - [x] Includes new tests, or was unnecessary - [x] Code is reviewed for security by: @WilcoFiers --- lib/core/base/audit.js | 5 ++++- lib/core/base/check.js | 10 +++++++++- test/core/base/audit.js | 5 +++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/lib/core/base/audit.js b/lib/core/base/audit.js index 1f5a09ff75..2cb572dd50 100644 --- a/lib/core/base/audit.js +++ b/lib/core/base/audit.js @@ -391,7 +391,10 @@ function getDefferedRule(rule, context, options) { description: 'An error occured while running this rule', message: err.message, stack: err.stack, - error: err + error: err, + // Add a serialized reference to the node the rule failed on for easier debugging. + // See https://github.com/dequelabs/axe-core/issues/1317. + errorNode: err.errorNode }); // resolve resolve(errResult); diff --git a/lib/core/base/check.js b/lib/core/base/check.js index 7ef4001038..306dfadff2 100644 --- a/lib/core/base/check.js +++ b/lib/core/base/check.js @@ -1,4 +1,4 @@ -/*global CheckResult */ +/*global CheckResult,DqElement */ function createExecutionContext(spec) { /*eslint no-eval:0 */ @@ -58,6 +58,7 @@ Check.prototype.enabled = true; * @param {Function} callback Function to fire when check is complete */ Check.prototype.run = function(node, options, context, resolve, reject) { + /* eslint max-statements: ["error", 17] */ 'use strict'; options = options || {}; var enabled = options.hasOwnProperty('enabled') @@ -84,6 +85,13 @@ Check.prototype.run = function(node, options, context, resolve, reject) { context ); } catch (e) { + // In the "Audit#run: should run all the rules" test, there is no `node` here. I do + // not know if this is intentional or not, so to be safe, we guard against the + // possible reference error. + if (node && node.actualNode) { + // Save a reference to the node we errored on for futher debugging. + e.errorNode = new DqElement(node.actualNode).toJSON(); + } reject(e); return; } diff --git a/test/core/base/audit.js b/test/core/base/audit.js index 405d85340b..4f31701fc6 100644 --- a/test/core/base/audit.js +++ b/test/core/base/audit.js @@ -1035,9 +1035,10 @@ describe('Audit', function() { throw err; } }); - + axe._tree = axe.utils.getFlattenedTree(fixture); + axe._selectorData = axe.utils.getSelectorData(axe._tree); a.run( - { include: [axe.utils.getFlattenedTree(fixture)[0]] }, + { include: [axe._tree[0]] }, { runOnly: { type: 'rule',