Skip to content

Commit d9f41e0

Browse files
authored
Merge pull request #84 from browserstack/release-2.4.0
Release 2.4.0
2 parents 0b2f622 + 8c0d988 commit d9f41e0

10 files changed

+131
-5
lines changed

Gruntfile.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ module.exports = function (grunt) {
1515
grunt.loadTasks('build/tasks');
1616

1717
var langs;
18+
var wrapper = !!grunt.option('wrapper');
1819
if (grunt.option('lang')) {
1920
langs = (grunt.option('lang') || '').split(/[,;]/g).map(function (lang) {
2021
lang = lang.trim();
@@ -85,11 +86,11 @@ module.exports = function (grunt) {
8586
files: langs.map(function (lang, i) {
8687
return {
8788
src: [
88-
'lib/intro.stub',
89+
wrapper ? 'lib/custom/intro.stub' : 'lib/intro.stub',
8990
'<%= concat.engine.coreFiles %>',
9091
// include rules / checks / commons
9192
'<%= configure.rules.files[' + i + '].dest.auto %>',
92-
'lib/outro.stub'
93+
wrapper ? 'lib/custom/outro.stub' : 'lib/outro.stub'
9394
],
9495
dest: 'axe' + lang + '.js'
9596
};
@@ -127,7 +128,8 @@ module.exports = function (grunt) {
127128
entry: 'lib/commons/aria/index.js',
128129
destFile: 'doc/aria-supported.md',
129130
options: {
130-
langs: langs
131+
langs: langs,
132+
wrapper: wrapper
131133
},
132134
listType: 'unsupported' // Possible values for listType: 'supported', 'unsupported', 'all'
133135
}

build/tasks/aria-supported.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ module.exports = function (grunt) {
1616
* hence cannot be required at the top of the file.
1717
*/
1818
const done = this.async();
19-
const { langs } = this.options();
19+
const { langs, wrapper } = this.options();
20+
if (wrapper) return true;
2021
const fileNameSuffix = langs && langs.length > 0 ? `${langs[0]}` : '';
2122
const axe = require(`../../axe${fileNameSuffix}`);
2223
const listType = this.data.listType.toLowerCase();

lib/core/public/load.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
/*global a11yEngine*/
12
import Audit from '../base/audit';
23
import cleanup from './cleanup';
34
import runRules from './run-rules';
45
import respondable from '../utils/respondable';
56
import nodeSerializer from '../utils/node-serializer';
7+
import mergeErrors from '../utils/merge-errors';
68

79
/**
810
* Sets up Rules, Messages and default options for Checks, must be invoked before attempting analysis
@@ -36,6 +38,21 @@ function runCommand(data, keepalive, callback) {
3638
(results, cleanupFn) => {
3739
// Serialize all DqElements
3840
results = nodeSerializer.mapRawResults(results);
41+
42+
//a11y-engine iframe rules error merging logic
43+
const errors = a11yEngine.getErrors();
44+
if (Object.keys(errors).length !== 0) {
45+
if (results[results.length - 1].a11yEngineErrors) {
46+
const error = results.pop();
47+
delete error.a11yEngineErrors;
48+
const mergedErrors = mergeErrors(error, errors);
49+
results.push({ ...mergedErrors, a11yEngineErrors: true });
50+
} else {
51+
results.push({ ...errors, a11yEngineErrors: true });
52+
}
53+
}
54+
a11yEngine.clearErrors();
55+
3956
resolve(results);
4057
// Cleanup AFTER resolve so that selectors can be generated
4158
cleanupFn();

lib/core/public/run-rules.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/*global a11yEngine*/
12
import Context from '../base/context';
23
import teardown from './teardown';
34
import {
@@ -36,6 +37,12 @@ export default function runRules(context, options, resolve, reject) {
3637
performanceTimer.auditStart();
3738
}
3839

40+
// If advanced run for iframes is true then setup socket for iframes
41+
if (options.a11yEngineConfig && options.a11yEngineConfig.iframesAdvancedRun) {
42+
a11yEngine.setup(options.a11yEngineConfig);
43+
}
44+
45+
// If run for iframes is true then collect results from iframes
3946
if (context.frames.length && options.iframes !== false) {
4047
q.defer((res, rej) => {
4148
collectResultsFromFrames(context, options, 'rules', null, res, rej);
@@ -59,6 +66,13 @@ export default function runRules(context, options, resolve, reject) {
5966

6067
// after should only run once, so ensure we are in the top level window
6168
if (context.initiator) {
69+
// Return a11y-engine errors when at top level window
70+
if (results[results.length - 1].a11yEngineErrors) {
71+
const error = results.pop();
72+
delete error.a11yEngineErrors;
73+
a11yEngine.mergeErrors(error);
74+
}
75+
6276
results = audit.after(results, options);
6377

6478
results.forEach(publishMetaData);

lib/core/utils/collect-results-from-frames.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ export default function collectResultsFromFrames(
2222
// elementRefs can't be passed across frame boundaries
2323
options = { ...options, elementRef: false };
2424

25+
// check a11yengine iframe advance run flag
26+
if (
27+
options.a11yEngineConfig &&
28+
options.a11yEngineConfig.iframesAdvancedRun === false
29+
) {
30+
options.a11yEngineConfig.iframesAdvancedRun = true;
31+
}
32+
2533
var q = queue();
2634
var frames = parentContent.frames;
2735

lib/core/utils/merge-errors.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Function to merge errors for a11y-engine.
2+
// Handles errors differently for check_errors and other errors.
3+
// It also adds the target selector to the errors for better identification.
4+
5+
function mergeErrors(mergedErrors, frameErrors, frameSpec) {
6+
for (const [key, value] of Object.entries(frameErrors)) {
7+
if (key === 'check_errors') {
8+
if (!mergedErrors[key]) {
9+
mergedErrors[key] = {};
10+
}
11+
12+
for (const [checkNameKey, checkNameValue] of Object.entries(value)) {
13+
// Add the target if not present. If present then append parents target.
14+
checkNameValue.forEach(checkNameValueError => {
15+
if (!checkNameValueError.target && frameSpec) {
16+
checkNameValueError.target = frameSpec?.selector;
17+
} else if (checkNameValueError.target && frameSpec) {
18+
checkNameValueError.target = [
19+
...frameSpec.selector,
20+
...checkNameValueError.target
21+
];
22+
}
23+
});
24+
if (mergedErrors[key][checkNameKey]) {
25+
mergedErrors[key][checkNameKey].push(...checkNameValue);
26+
} else {
27+
mergedErrors[key][checkNameKey] = Array.isArray(checkNameValue)
28+
? [...checkNameValue]
29+
: [checkNameValue];
30+
}
31+
}
32+
} else {
33+
// Add the target if not present. If present then append parents target.
34+
value.forEach(errorValue => {
35+
if (!errorValue.target && frameSpec) {
36+
errorValue.target = frameSpec?.selector;
37+
} else if (errorValue.target && frameSpec) {
38+
errorValue.target = [...frameSpec.selector, ...errorValue.target];
39+
}
40+
});
41+
if (mergedErrors[key]) {
42+
mergedErrors[key] = [...mergedErrors[key], ...value];
43+
} else {
44+
mergedErrors[key] = value;
45+
}
46+
}
47+
}
48+
49+
return mergedErrors;
50+
}
51+
52+
export default mergeErrors;

lib/core/utils/merge-results.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import nodeSerializer from './node-serializer';
22
import getAllChecks from './get-all-checks';
33
import findBy from './find-by';
4+
import mergeErrors from './merge-errors';
45

56
/**
67
* Adds the owning frame's CSS selector onto each instance of DqElement
@@ -75,13 +76,22 @@ function normalizeResult(result) {
7576
*/
7677
function mergeResults(frameResults, options) {
7778
const mergedResult = [];
79+
// A11yEngine merged errors
80+
let mergedErrors = {};
7881
frameResults.forEach(frameResult => {
7982
const results = normalizeResult(frameResult);
8083
if (!results || !results.length) {
8184
return;
8285
}
8386

8487
const frameSpec = getFrameSpec(frameResult);
88+
// Extract existing errors and merge with new ones
89+
if (results[results.length - 1].a11yEngineErrors) {
90+
const error = results.pop();
91+
delete error.a11yEngineErrors;
92+
mergedErrors = mergeErrors(mergedErrors, error, frameSpec);
93+
}
94+
8595
results.forEach(ruleResult => {
8696
if (ruleResult.nodes && frameSpec) {
8797
pushFrame(ruleResult.nodes, options, frameSpec);
@@ -106,7 +116,11 @@ function mergeResults(frameResults, options) {
106116
});
107117
}
108118
});
109-
return mergedResult;
119+
120+
if (Object.keys(mergedErrors).length === 0) {
121+
return mergedResult;
122+
}
123+
return [...mergedResult, { ...mergedErrors, a11yEngineErrors: true }];
110124
}
111125

112126
function nodeIndexSort(nodeIndexesA = [], nodeIndexesB = []) {

lib/custom/intro.stub

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*! axe v<%= pkg.version %>
2+
* Copyright (c) 2015 - <%= grunt.template.today("yyyy") %> Deque Systems, Inc.
3+
*
4+
* Your use of this Source Code Form is subject to the terms of the Mozilla Public
5+
* License, v. 2.0. If a copy of the MPL was not distributed with this
6+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
7+
*
8+
* This entire copyright notice must appear in every copy of this file you
9+
* distribute or in any file that contains substantial portions of this source
10+
* code.
11+
*/
12+
const createAxe = () => (function axeFunction (window) {
13+
// A window reference is required to access the axe object in a "global".
14+
var global = window;
15+
var document = window.document;

lib/custom/outro.stub

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
}( typeof window === 'object' ? window : this ));

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
"develop": "grunt dev --force",
7272
"api-docs": "jsdoc --configure .jsdoc.json",
7373
"build": "grunt",
74+
"build:wrapper": "grunt --wrapper=true",
7475
"eslint": "eslint --color --format stylish '{lib,test,build,doc}/**/*.js' 'Gruntfile.js'",
7576
"test": "npm run test:tsc && run-s \"test:unit:* -- {@}\" --",
7677
"test:tsc": "tsc",

0 commit comments

Comments
 (0)