Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(reporter): return one result of each type instead of zero when r… #604

Merged
merged 1 commit into from
Nov 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions doc/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -440,13 +440,14 @@ Additionally, there are a number or properties that allow configuration of diffe

6. Only process certain types of results

The `resultTypes` option can be used to limit the result types that aXe will process, aggregate, and send to the reporter. This can be useful for improving performance on very large or complicated pages when you are only interested in certain types of results.
The `resultTypes` option can be used to limit the result types that aXe will process, aggregate, and send to the reporter. This can be useful for improving performance on very large or complicated pages when you are only interested in certain types of results. The option will return 1 result of each type if that rule has at least one of that type of result instead of returning all of that type of result. The caller can use this information to inform the user of the existence of that type of result if appropriate.

```javascript
{
resultTypes: ['violations', 'incomplete', 'inapplicable']
}
```
This example will only process the specified result types: "violations", "incomplete", and "inapplicable". Notably, it will not process "passes". On a series of extremely large pages, this could improve performance considerably.
This example will only process the specified result types: "violations", "incomplete", and "inapplicable". Notably, it will only process the first pass for each rule that has a pass. On a series of extremely large pages, this could improve performance considerably.

##### Callback Parameter

Expand Down
8 changes: 6 additions & 2 deletions lib/core/reporters/helpers/process-aggregate.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,12 @@ helpers.processAggregate = function (results, options) {

resultKeys.forEach(function (key) {
if (options.resultTypes && !options.resultTypes.includes(key)) {
delete resultObject[key];
return;
// If the user asks us to, truncate certain finding types to maximum one finding
(resultObject[key] || []).forEach(function (ruleResult) {
if (Array.isArray(ruleResult.nodes) && ruleResult.nodes.length > 0) {
ruleResult.nodes = [ruleResult.nodes[0]];
}
});
}
resultObject[key] = (resultObject[key] || []).map(function (ruleResult) {
ruleResult = Object.assign({}, ruleResult);
Expand Down
52 changes: 48 additions & 4 deletions test/core/reporters/helpers/process-aggregate.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,25 @@ describe('helpers.processAggregate', function () {
}],
all: [],
none: []
}, {
result: 'passed',
node: {
element: document.createElement('div'),
selector: 'main > .thing',
source: '<div class=\"thing\">Thing</div>',
xpath: '/main/div[@class="thing"]'
},
any: [{
id: 'passed-rule',
relatedNodes: [{
element: document.createElement('div'),
selector: 'footer > .thing',
source: '<div class=\"thing\">Thing</div>',
xpath: '/footer/div[@class="thing"]',
}]
}],
all: [],
none: []
}],
inapplicable: [],
incomplete: [],
Expand All @@ -51,6 +70,26 @@ describe('helpers.processAggregate', function () {
}],
all: [],
none: []
}, {
result: 'failed',
node: {
selector: '#dopell',
source: '<input id=\"dopell\"/>',
xpath: '/header/input[@id="dopell"]',
fromFrame: true
},
any: [{
id: 'failed-rule',
relatedNodes: [{
element: document.createElement('input'),
selector: '#dopell',
source: '<input id=\"dopell\"/>',
xpath: '/header/input[@id="dopell"]',
fromFrame: true
}]
}],
all: [],
none: []
}],
inapplicable: [],
passes: [],
Expand Down Expand Up @@ -96,12 +135,17 @@ describe('helpers.processAggregate', function () {

describe('`resultTypes` option', function () {

it('should remove non-specified result types from the `resultObject`', function () {
var resultObject = helpers.processAggregate(results, { resultTypes: ['passes', 'violations'] });
it('should reduce the unwanted result types to 1 in the `resultObject`', function () {
var resultObject = helpers.processAggregate(results, { resultTypes: ['violations'] });
assert.isDefined(resultObject.passes);
assert.equal(resultObject.passes[0].nodes.length, 1);
assert.isDefined(resultObject.violations);
assert.isUndefined(resultObject.incomplete);
assert.isUndefined(resultObject.inapplicable);
assert.equal(resultObject.violations[0].nodes.length, 2);
resultObject = helpers.processAggregate(results, { resultTypes: ['passes'] });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the second call to processAggregate here? Is that what happens when it gets called as a result of an analysis?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's just a second test to make sure it's not just 'violations', but also that it works for 'passes'.

assert.equal(resultObject.passes[0].nodes.length, 2);
assert.equal(resultObject.violations[0].nodes.length, 1);
assert.isDefined(resultObject.incomplete);
assert.isDefined(resultObject.inapplicable);
});
});

Expand Down