accessibility-checker 3.1.0 → 3.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/bin/achecker.d.ts +2 -0
- package/bin/achecker.js +293 -177
- package/bin/achecker.js.map +1 -0
- package/index.d.ts +317 -0
- package/index.js +359 -13
- package/index.js.map +1 -0
- package/lib/ACBrowserManager.d.ts +22 -0
- package/lib/ACBrowserManager.js +237 -0
- package/lib/ACBrowserManager.js.map +1 -0
- package/lib/ACConfigManager.d.ts +6 -0
- package/lib/ACConfigManager.js +399 -0
- package/lib/ACConfigManager.js.map +1 -0
- package/lib/ACConstants.d.ts +17 -0
- package/lib/ACConstants.js +12 -38
- package/lib/ACConstants.js.map +1 -0
- package/lib/ACEngineManager.d.ts +21 -0
- package/lib/ACEngineManager.js +220 -0
- package/lib/ACEngineManager.js.map +1 -0
- package/lib/ACHelper.d.ts +2 -0
- package/lib/ACHelper.js +485 -2085
- package/lib/ACHelper.js.map +1 -0
- package/lib/ACReportManager.d.ts +586 -0
- package/lib/ACReportManager.js +1150 -0
- package/lib/ACReportManager.js.map +1 -0
- package/lib/api/IChecker.d.ts +131 -0
- package/lib/api/IChecker.js +11 -0
- package/lib/api/IChecker.js.map +1 -0
- package/lib/api/IEngine.d.ts +124 -0
- package/lib/api/IEngine.js +110 -0
- package/lib/api/IEngine.js.map +1 -0
- package/lib/api/IMapper.d.ts +37 -0
- package/lib/api/IMapper.js +18 -0
- package/lib/api/IMapper.js.map +1 -0
- package/lib/log/ACMetricsLogger.d.ts +67 -0
- package/lib/log/ACMetricsLogger.js +40 -66
- package/lib/log/ACMetricsLogger.js.map +1 -0
- package/lib/reporters/ACReporterCSV.d.ts +103 -0
- package/lib/reporters/ACReporterCSV.js +83 -152
- package/lib/reporters/ACReporterCSV.js.map +1 -0
- package/lib/reporters/ACReporterHTML.d.ts +114 -0
- package/lib/reporters/ACReporterHTML.js +150 -293
- package/lib/reporters/ACReporterHTML.js.map +1 -0
- package/lib/reporters/ACReporterJSON.d.ts +114 -0
- package/lib/reporters/ACReporterJSON.js +95 -249
- package/lib/reporters/ACReporterJSON.js.map +1 -0
- package/lib/reporters/ReportUtil.d.ts +33 -0
- package/lib/reporters/ReportUtil.js +65 -0
- package/lib/reporters/ReportUtil.js.map +1 -0
- package/lib/reporters/genReport.d.ts +1 -0
- package/lib/reporters/genReport.js +13 -11
- package/lib/reporters/genReport.js.map +1 -0
- package/package.json +4 -3
- package/lib/ACConfigLoader.js +0 -358
package/lib/ACHelper.js
CHANGED
|
@@ -1,360 +1,159 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
See the License for the specific language governing permissions and
|
|
14
|
-
limitations under the License.
|
|
15
|
-
*****************************************************************************/
|
|
16
|
-
|
|
17
|
-
const request = require("request");
|
|
18
|
-
const fs = require("fs");
|
|
19
|
-
const path = require("path");
|
|
20
|
-
const DeepDiff = require("deep-diff");
|
|
21
|
-
const ACMetricsLogger = require('./log/ACMetricsLogger');
|
|
22
|
-
const puppeteer = require('puppeteer');
|
|
23
|
-
const ACReporterJSON = require("./reporters/ACReporterJSON");
|
|
24
|
-
const ACReporterHTML = require("./reporters/ACReporterHTML");
|
|
25
|
-
const ACReporterCSV = require("./reporters/ACReporterCSV");
|
|
26
|
-
|
|
27
|
-
let aChecker = {
|
|
28
|
-
Config: null
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
29
10
|
};
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
aChecker.baselineIssueList = ["ruleId", "xpath"];
|
|
56
|
-
metricsLogger = new ACMetricsLogger("accessibility-checker", logger, aChecker.Config.policies.join(","));
|
|
57
|
-
|
|
58
|
-
// Initialize the scanSummary object with summary information for accessibility-checker
|
|
59
|
-
aChecker.scanSummary = aChecker.initializeSummary();
|
|
60
|
-
|
|
61
|
-
// Initialize the global object which will store all the diff results for a scan that is run, using
|
|
62
|
-
// actual and expected.
|
|
63
|
-
aChecker.diffResults = {};
|
|
64
|
-
|
|
65
|
-
// Initialize the global object which will store all the scan results indexed by the label.
|
|
66
|
-
aChecker.scanResults = {};
|
|
67
|
-
|
|
68
|
-
aChecker.engineLoaded = false;
|
|
69
|
-
return aChecker.loadLocalEngine();
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
let loggerFunction = function (output) {
|
|
73
|
-
aChecker.DEBUG && console.log(output);
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
let loggerCreate = function (type) {
|
|
77
|
-
return logger;
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
let logger = {
|
|
81
|
-
debug: loggerFunction,
|
|
82
|
-
info: loggerFunction,
|
|
83
|
-
error: loggerFunction,
|
|
84
|
-
warn: loggerFunction,
|
|
85
|
-
create: loggerCreate
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
aChecker.getConfig = async () => {
|
|
89
|
-
await initialize();
|
|
90
|
-
return aChecker.Config;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* This function is responsible for initializing the summary object which will store all informations about the
|
|
95
|
-
* scans that will occurs while karma is still running and running compliance scans.
|
|
96
|
-
*
|
|
97
|
-
* @return {Object} scanSummary - return the built scan summary object
|
|
98
|
-
*
|
|
99
|
-
* @memberOf this
|
|
100
|
-
*/
|
|
101
|
-
aChecker.initializeSummary = function () {
|
|
102
|
-
// Variable Decleration
|
|
103
|
-
let scanSummary = {};
|
|
104
|
-
let reportLevels = aChecker.Config.reportLevels;
|
|
105
|
-
|
|
106
|
-
// Initialize counts
|
|
107
|
-
scanSummary.counts = {};
|
|
108
|
-
|
|
109
|
-
// In the case that report levels are provided then populate the count object in
|
|
110
|
-
// scanSummary.counts object with the levels which were provided in reportLevels
|
|
111
|
-
// array.
|
|
112
|
-
if (reportLevels) {
|
|
113
|
-
|
|
114
|
-
// Iterate over the report levels and populate the pageResultsWithCount counts
|
|
115
|
-
// object
|
|
116
|
-
reportLevels.forEach(function (levels) {
|
|
117
|
-
scanSummary.counts[levels] = 0;
|
|
118
|
-
});
|
|
119
|
-
scanSummary.counts.ignored = 0;
|
|
120
|
-
}
|
|
121
|
-
// Populate the scanSummary.counts object with all the levels
|
|
122
|
-
else {
|
|
123
|
-
scanSummary.counts = {
|
|
124
|
-
"violation": 0,
|
|
125
|
-
"potentialviolation": 0,
|
|
126
|
-
"recommendation": 0,
|
|
127
|
-
"potentialrecommendation": 0,
|
|
128
|
-
"manual": 0,
|
|
129
|
-
"pass": 0
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// Add Start time when this script is loaded into browser
|
|
134
|
-
// Start time will be in milliseconds elapsed since 1 January 1970 00:00:00 UTC up until now.
|
|
135
|
-
scanSummary.startReport = Date.now();
|
|
136
|
-
|
|
137
|
-
// Leave end report as empty for now
|
|
138
|
-
scanSummary.endReport = '';
|
|
139
|
-
|
|
140
|
-
// Add the toolID, policies, reportLevels, failLevels and labels from the config to the summary
|
|
141
|
-
scanSummary.toolID = aChecker.Config.toolID;
|
|
142
|
-
scanSummary.policies = aChecker.Config.policies.join(",");
|
|
143
|
-
scanSummary.reportLevels = aChecker.Config.reportLevels;
|
|
144
|
-
scanSummary.labels = aChecker.Config.label;
|
|
145
|
-
scanSummary.failLevels = aChecker.Config.failLevels;
|
|
146
|
-
|
|
147
|
-
// Add scanID (UUID) to the scan summary object
|
|
148
|
-
scanSummary.scanID = aChecker.Config.scanID;
|
|
149
|
-
|
|
150
|
-
// Build the paceScanSummary object which will contains all the items that were scanned and a count
|
|
151
|
-
// summary for each of the scanned items.
|
|
152
|
-
scanSummary.pageScanSummary = [];
|
|
153
|
-
|
|
154
|
-
return scanSummary;
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
function isPuppeteer(content) {
|
|
158
|
-
if (content && content.constructor) {
|
|
159
|
-
return content.constructor.toString().includes("Puppeteer");
|
|
160
|
-
}
|
|
161
|
-
return false;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
function isSelenium(content) {
|
|
165
|
-
if (content && content.constructor) {
|
|
166
|
-
return content.constructor.toString().indexOf("Driver") !== -1 ||
|
|
167
|
-
// check required for selenium >= 3.0.1
|
|
168
|
-
(content.constructor.name && content.constructor.name.indexOf("Driver") !== -1);
|
|
169
|
-
}
|
|
170
|
-
return false;
|
|
11
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
+
function step(op) {
|
|
16
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
+
while (_) try {
|
|
18
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
+
switch (op[0]) {
|
|
21
|
+
case 0: case 1: t = op; break;
|
|
22
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
+
default:
|
|
26
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
+
if (t[2]) _.ops.pop();
|
|
31
|
+
_.trys.pop(); continue;
|
|
32
|
+
}
|
|
33
|
+
op = body.call(thisArg, _);
|
|
34
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
171
36
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.getComplianceHelper = void 0;
|
|
40
|
+
var ACBrowserManager_1 = require("./ACBrowserManager");
|
|
41
|
+
var ACConfigManager_1 = require("./ACConfigManager");
|
|
42
|
+
var ACEngineManager_1 = require("./ACEngineManager");
|
|
43
|
+
var ACReportManager_1 = require("./ACReportManager");
|
|
44
|
+
var loggerCreate = function (type) {
|
|
45
|
+
return logger;
|
|
46
|
+
};
|
|
47
|
+
var logger = {
|
|
48
|
+
debug: function () {
|
|
49
|
+
var output = [];
|
|
50
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
51
|
+
output[_i] = arguments[_i];
|
|
52
|
+
}
|
|
53
|
+
Config && Config.DEBUG && console.debug.apply(console, output);
|
|
54
|
+
},
|
|
55
|
+
info: function () {
|
|
56
|
+
var output = [];
|
|
57
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
58
|
+
output[_i] = arguments[_i];
|
|
59
|
+
}
|
|
60
|
+
Config && Config.DEBUG && console.info.apply(console, output);
|
|
61
|
+
},
|
|
62
|
+
error: function () {
|
|
63
|
+
var output = [];
|
|
64
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
65
|
+
output[_i] = arguments[_i];
|
|
66
|
+
}
|
|
67
|
+
Config && Config.DEBUG && console.error.apply(console, output);
|
|
68
|
+
},
|
|
69
|
+
warn: function () {
|
|
70
|
+
var output = [];
|
|
71
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
72
|
+
output[_i] = arguments[_i];
|
|
73
|
+
}
|
|
74
|
+
Config && Config.DEBUG && console.warn.apply(console, output);
|
|
75
|
+
},
|
|
76
|
+
create: loggerCreate
|
|
77
|
+
};
|
|
78
|
+
var Config;
|
|
79
|
+
var checkPolicy = false;
|
|
80
|
+
function initialize() {
|
|
81
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
82
|
+
return __generator(this, function (_a) {
|
|
83
|
+
switch (_a.label) {
|
|
84
|
+
case 0:
|
|
85
|
+
if (Config)
|
|
86
|
+
return [2 /*return*/];
|
|
87
|
+
return [4 /*yield*/, ACConfigManager_1.ACConfigManager.getConfigUnsupported()];
|
|
88
|
+
case 1:
|
|
89
|
+
Config = _a.sent();
|
|
90
|
+
return [4 /*yield*/, ACReportManager_1.ACReportManager.initialize(logger)];
|
|
91
|
+
case 2:
|
|
92
|
+
_a.sent();
|
|
93
|
+
return [2 /*return*/, ACEngineManager_1.ACEngineManager.loadEngineLocal()];
|
|
182
94
|
}
|
|
183
|
-
|
|
184
|
-
}
|
|
185
|
-
if (errorPolicy.length > 0) {
|
|
186
|
-
errorPolicy = errorPolicy.substr(0, errorPolicy.length - 1);
|
|
187
|
-
console.log(`[WARN] InvalidPolicies: Invalid policies "${errorPolicy}". Valid policy ids are: ${valPolicies}`);
|
|
188
|
-
}
|
|
189
|
-
if (!isValPol) {
|
|
190
|
-
console.error(`[ERROR] ValidPoliciesMissing: No valid policy has been provided. Valid policy ids for the specified archive are: ${valPolicies}`);
|
|
191
|
-
process.exit(-1);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* This function loads the compliance engine.
|
|
197
|
-
* @param {Function} callback - Provide callback function which will be executed once the engine is loaded
|
|
198
|
-
*
|
|
199
|
-
* @return N/A - This function will not return any thing, as it is full async
|
|
200
|
-
*/
|
|
201
|
-
aChecker.loadEngine = async function (content) {
|
|
202
|
-
if (isPuppeteer(content)) {
|
|
203
|
-
aChecker.DEBUG && console.log("[INFO] aChecker.loadEngine detected Puppeteer");
|
|
204
|
-
let page = content;
|
|
205
|
-
const docHandle = await page.evaluateHandle('document');
|
|
206
|
-
await page.evaluate((document, scriptUrl) => {
|
|
207
|
-
try {
|
|
208
|
-
if ('undefined' === typeof(ace)) {
|
|
209
|
-
return new Promise((resolve, reject) => {
|
|
210
|
-
let script = document.createElement('script');
|
|
211
|
-
script.setAttribute('type', 'text/javascript');
|
|
212
|
-
script.setAttribute('aChecker', 'ACE');
|
|
213
|
-
script.setAttribute('src', scriptUrl);
|
|
214
|
-
script.addEventListener('load', function () {
|
|
215
|
-
resolve();
|
|
216
|
-
});
|
|
217
|
-
let heads = document.getElementsByTagName('head');
|
|
218
|
-
if (heads.length > 0) { heads[0].appendChild(script); }
|
|
219
|
-
else if (document.body) { document.body.appendChild(script); }
|
|
220
|
-
else { Promise.reject("Invalid document"); }
|
|
221
|
-
})
|
|
222
|
-
}
|
|
223
|
-
} catch (e) {
|
|
224
|
-
return Promise.reject(e);
|
|
225
|
-
}
|
|
226
|
-
}, docHandle, aChecker.Config.rulePack + "/ace.js");
|
|
227
|
-
return aChecker.loadLocalEngine();
|
|
228
|
-
} else if (isSelenium(content)) {
|
|
229
|
-
aChecker.DEBUG && console.log("[INFO] aChecker.loadEngine detected Selenium");
|
|
230
|
-
try {
|
|
231
|
-
let browser = content;
|
|
232
|
-
// Selenium
|
|
233
|
-
let scriptStr =
|
|
234
|
-
`let cb = arguments[arguments.length - 1];
|
|
235
|
-
try {
|
|
236
|
-
if ('undefined' === typeof(ace)) {
|
|
237
|
-
let script = document.createElement('script');
|
|
238
|
-
script.setAttribute('type', 'text/javascript');
|
|
239
|
-
script.setAttribute('aChecker', 'ACE');
|
|
240
|
-
script.setAttribute('src', '${aChecker.Config.rulePack + "/ace.js"}');
|
|
241
|
-
script.addEventListener('load', function() {
|
|
242
|
-
cb();
|
|
243
95
|
});
|
|
244
|
-
|
|
245
|
-
if (heads.length > 0) { heads[0].appendChild(script); }
|
|
246
|
-
else { document.body.appendChild(script); }
|
|
247
|
-
} else {
|
|
248
|
-
cb();
|
|
249
|
-
}
|
|
250
|
-
} catch (e) {
|
|
251
|
-
cb(e);
|
|
96
|
+
});
|
|
252
97
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
});
|
|
268
|
-
} catch (e) {
|
|
269
|
-
console.log(e);
|
|
98
|
+
try {
|
|
99
|
+
// If cucumber is the platform...
|
|
100
|
+
var AfterAll = require('cucumber').AfterAll;
|
|
101
|
+
AfterAll(function (done) {
|
|
102
|
+
var rulePack = Config.ruleServer + "/archives/" + Config.ruleArchive + "/js";
|
|
103
|
+
initialize().then(function () { return ACReportManager_1.ACReportManager.metricsLogger.sendLogsV2(function () { return ACBrowserManager_1.ACBrowserManager.close().then(done); }, rulePack); });
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
catch (e) {
|
|
107
|
+
if (typeof (after) !== "undefined") {
|
|
108
|
+
after(function (done) {
|
|
109
|
+
if (Config) {
|
|
110
|
+
var rulePack_1 = Config.ruleServer + "/archives/" + Config.ruleArchive + "/js";
|
|
111
|
+
initialize().then(function () { return ACReportManager_1.ACReportManager.metricsLogger.sendLogsV2(function () { return ACBrowserManager_1.ACBrowserManager.close().then(done); }, rulePack_1); });
|
|
270
112
|
}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
if (ace) {
|
|
274
|
-
return Promise.resolve();
|
|
275
|
-
} else {
|
|
276
|
-
return aChecker.loadLocalEngine();
|
|
113
|
+
else {
|
|
114
|
+
done();
|
|
277
115
|
}
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
}
|
|
290
|
-
data = data.body;
|
|
291
|
-
let engineDir = path.join(__dirname, "engine");
|
|
292
|
-
if (!fs.existsSync(engineDir)) {
|
|
293
|
-
fs.mkdirSync(engineDir);
|
|
294
|
-
}
|
|
295
|
-
let cacheDir = path.join(engineDir, "cache");
|
|
296
|
-
if (!fs.existsSync(cacheDir)) {
|
|
297
|
-
fs.mkdirSync(cacheDir);
|
|
298
|
-
}
|
|
299
|
-
fs.writeFile(path.join(engineDir, "ace-node.js"), data, function (err) {
|
|
300
|
-
try {
|
|
301
|
-
err && console.log(err);
|
|
302
|
-
ace = require("./engine/ace-node");
|
|
303
|
-
} catch (e) {
|
|
304
|
-
console.log(e);
|
|
305
|
-
return reject(e);
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
process.on('beforeExit', function () {
|
|
120
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
121
|
+
var rulePack_2;
|
|
122
|
+
return __generator(this, function (_a) {
|
|
123
|
+
if (Config) {
|
|
124
|
+
rulePack_2 = Config.ruleServer + "/archives/" + Config.ruleArchive + "/js";
|
|
125
|
+
initialize().then(function () { return ACReportManager_1.ACReportManager.metricsLogger.sendLogsV2(null, rulePack_2); });
|
|
126
|
+
ACBrowserManager_1.ACBrowserManager.close();
|
|
306
127
|
}
|
|
307
|
-
|
|
128
|
+
return [2 /*return*/];
|
|
308
129
|
});
|
|
309
130
|
});
|
|
310
131
|
});
|
|
311
|
-
};
|
|
312
|
-
|
|
313
|
-
/**
|
|
314
|
-
* This function is responsible performing a scan based on the context that is provided, following are
|
|
315
|
-
* the supported context type:
|
|
316
|
-
* Single node (HTMLElement)
|
|
317
|
-
* Local file path (String)
|
|
318
|
-
* URL (String)
|
|
319
|
-
* document node
|
|
320
|
-
* data stream for html content (String)
|
|
321
|
-
*
|
|
322
|
-
* Future Items
|
|
323
|
-
* Multiple node (Array of HTMLElements) ---> FUTURE
|
|
324
|
-
*
|
|
325
|
-
* @param {(String|HTMLElement|DocumentNode)} content - Provide the context to scan, which includes the items from above.
|
|
326
|
-
* @param {String} label - Provide a label for the scan that is being performed
|
|
327
|
-
* @param {Function} callback - Provide callback function which will be executed once the results are extracted.
|
|
328
|
-
*
|
|
329
|
-
* @return N/A - This function will not return any thing, as it is full asyn so scan will be performed and the call back
|
|
330
|
-
* function which was provided will be called which will perform the verification or anything that is needed.
|
|
331
|
-
*
|
|
332
|
-
* PUBLIC API
|
|
333
|
-
*
|
|
334
|
-
* @memberOf this
|
|
335
|
-
*/
|
|
336
|
-
aChecker.getCompliance = function (content, label, callback) {
|
|
337
|
-
if (callback) {
|
|
338
|
-
aChecker.getComplianceHelper(content, label)
|
|
339
|
-
.then((result) => {
|
|
340
|
-
callback(result.report, result.webdriver);
|
|
341
|
-
});
|
|
342
|
-
} else {
|
|
343
|
-
return aChecker.getComplianceHelper(content, label);
|
|
344
|
-
}
|
|
345
132
|
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
133
|
+
}
|
|
134
|
+
function areValidPolicy(valPolicies, curPol) {
|
|
135
|
+
var isValPol = false;
|
|
136
|
+
var errorPolicy = "";
|
|
137
|
+
for (var i = 0; i < curPol.length; ++i) {
|
|
138
|
+
if (valPolicies.indexOf(curPol[i]) === -1) {
|
|
139
|
+
errorPolicy += "" + curPol[i] + ",";
|
|
353
140
|
}
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
141
|
+
else {
|
|
142
|
+
isValPol = true;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
if (errorPolicy.length > 0) {
|
|
146
|
+
errorPolicy = errorPolicy.substr(0, errorPolicy.length - 1);
|
|
147
|
+
console.log("[WARN] InvalidPolicies: Invalid policies \"" + errorPolicy + "\". Valid policy ids are: " + valPolicies);
|
|
148
|
+
}
|
|
149
|
+
if (!isValPol) {
|
|
150
|
+
var errStr = "[ERROR] ValidPoliciesMissing: No valid policy has been provided. Valid policy ids for the specified archive are: " + valPolicies;
|
|
151
|
+
console.error(errStr);
|
|
152
|
+
throw new Error(errStr);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
function getComplianceHelper(content, label) {
|
|
156
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
358
157
|
// Since we need to handle multiple variation of possible ways to scan items, we need to handle
|
|
359
158
|
// each one differently as each one requires specific actions/setup.
|
|
360
159
|
// Handle the following:
|
|
@@ -363,1759 +162,360 @@ try {
|
|
|
363
162
|
// Local file (String)
|
|
364
163
|
// URL (String)
|
|
365
164
|
// document
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
} else if (isSelenium(content) || isPuppeteer(content)) {
|
|
382
|
-
|
|
383
|
-
}
|
|
384
|
-
// Handle Array of nodes
|
|
385
|
-
else if (content instanceof Array) {
|
|
386
|
-
// TODO: Supporting Array of nodes, possible future enhancenment
|
|
387
|
-
}
|
|
388
|
-
// Handle single node (HTMLElement)
|
|
389
|
-
else if (content.nodeType === 1) {
|
|
390
|
-
// In the case this is a node, there is nothing special that needs to be done at this time,
|
|
391
|
-
// the engine will be able to handle this. Adding this block here as we may need to add some filtering
|
|
392
|
-
// of rules or rule sets for this case depending on if a special ruleset needs to be created or not.
|
|
393
|
-
content = content;
|
|
394
|
-
}
|
|
395
|
-
// handle scanning document
|
|
396
|
-
else if (content.nodeType === 9) {
|
|
397
|
-
// In the case this is a document element, simply send the document object to the engine for now
|
|
398
|
-
// we will need to do some filtering to remove any karma related aspects, which requires to do a
|
|
399
|
-
// document clone, and then string the karma scripts that are added and then send this document
|
|
400
|
-
// to the engine.
|
|
401
|
-
// TODO: Investigate best approach to perform filtering
|
|
402
|
-
content = content;
|
|
403
|
-
}
|
|
404
|
-
return content;
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
let parsed = await getParsed(content);
|
|
408
|
-
if (parsed === null) return null;
|
|
409
|
-
await aChecker.loadEngine(parsed);
|
|
410
|
-
// In the case that the label is null or undefined, throw an error using the karma API
|
|
411
|
-
// console.error with the message of the error.
|
|
412
|
-
if (label === null || typeof label === "undefined" || label === undefined) {
|
|
413
|
-
|
|
414
|
-
// Variable Decleration
|
|
415
|
-
let testcaseWhichIsMissingRequiredLabel = null;
|
|
416
|
-
let generalErrorMessageLabelNotUnique = "\n[Error] labelNotProvided: Label must be provided when calling aChecker.getCompliance.";
|
|
417
|
-
|
|
418
|
-
// Get the caller of the aChecker.getCompliance function which will be the testcase that is calling this function
|
|
419
|
-
// This way we can make it the error more descriptive and would help the user identify where the issues is.
|
|
420
|
-
// We have to build and throw an Error() object and then using the try/catch to catch this error and then extract the
|
|
421
|
-
// stack and parse it to get the 2nd element in the stack which will be the caller of this function which will be the
|
|
422
|
-
// testcase which called this function.
|
|
423
|
-
try {
|
|
424
|
-
// Throw Error() object
|
|
425
|
-
throw new Error();
|
|
426
|
-
} catch (exception) {
|
|
427
|
-
// Extract the stack trace from the error object and parse it to get the single one caller up which will be the 2nd index
|
|
428
|
-
testcaseWhichIsMissingRequiredLabel = exception.stack.split("\n")[1];
|
|
429
|
-
|
|
430
|
-
// Call the Karma error API, to send message to the Karma server that there was an error on the client side
|
|
431
|
-
console.error("Label was not provided at: " + testcaseWhichIsMissingRequiredLabel + generalErrorMessageLabelNotUnique);
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
// Check to make sure that the label that is provided is unique with all the other ones
|
|
436
|
-
// that we have gone through.
|
|
437
|
-
let labelUnique = aChecker.isLabelUnique(label);
|
|
438
|
-
|
|
439
|
-
// In the case that the label is not unique
|
|
440
|
-
if (!labelUnique) {
|
|
441
|
-
// Variable Decleration dependencies/tools-rules-html/v2/a11y/test/g471/Table-DataNoSummaryARIA.html
|
|
442
|
-
let testcaseDoesNotUseUniqueLabel = null;
|
|
443
|
-
let generalErrorMessageLabelNotUnique = "\n[Error] labelNotUnique: Label provided to aChecker.getCompliance should be unique across all testcases in a single accessibility-checker session.";
|
|
444
|
-
|
|
445
|
-
// Get the caller of the aChecker.getCompliance function which will be the testcase that is calling this function
|
|
446
|
-
// This way we can make it the error more descriptive and would help the user identify where the issues is.
|
|
447
|
-
// We have to build and throw an Error() object and then using the try/catch to catch this error and then extract the
|
|
448
|
-
// stack and parse it to get the 2nd element in the stack which will be the caller of this function which will be the
|
|
449
|
-
// testcase which called this function.
|
|
450
|
-
try {
|
|
451
|
-
// Throw Error() object
|
|
452
|
-
throw new Error();
|
|
453
|
-
} catch (exception) {
|
|
454
|
-
// Extract the stack trace from the error object and parse it to get the single one caller up which will be the 2nd index
|
|
455
|
-
testcaseDoesNotUseUniqueLabel = exception.stack.split("\n")[1];
|
|
456
|
-
|
|
457
|
-
// Call the Karma error API, to send message to the Karma server that there was an error on the client side
|
|
458
|
-
console.error("Label \"" + label + "\" provided at: " + testcaseDoesNotUseUniqueLabel + " is not unique." + generalErrorMessageLabelNotUnique);
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
// Get the Data when the scan is started
|
|
463
|
-
// Start time will be in milliseconds elapsed since 1 January 1970 00:00:00 UTC up until now.
|
|
464
|
-
let policies = aChecker.Config.policies;
|
|
465
|
-
let curPol = null;
|
|
466
|
-
if (policies) {
|
|
467
|
-
curPol = JSON.parse(JSON.stringify(policies));
|
|
468
|
-
}
|
|
469
|
-
if (isSelenium(parsed)) {
|
|
470
|
-
aChecker.DEBUG && console.log("getComplianceHelper:Selenium");
|
|
471
|
-
return await aChecker.getComplianceHelperSelenium(label, parsed, curPol);
|
|
472
|
-
} else if (isPuppeteer(parsed)) {
|
|
473
|
-
aChecker.DEBUG && console.log("getComplianceHelper:Puppeteer");
|
|
474
|
-
return await aChecker.getComplianceHelperPuppeteer(label, parsed, curPol);
|
|
475
|
-
} else {
|
|
476
|
-
aChecker.DEBUG && console.log("getComplianceHelper:Local");
|
|
477
|
-
return await aChecker.getComplianceHelperLocal(label, parsed, curPol);
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
aChecker.getComplianceHelperSelenium = async (label, parsed, curPol) => {
|
|
482
|
-
try {
|
|
483
|
-
let startScan = Date.now();
|
|
484
|
-
// NOTE: Engine should already be loaded
|
|
485
|
-
let browser = parsed;
|
|
486
|
-
// Selenium
|
|
487
|
-
let scriptStr =
|
|
488
|
-
`let cb = arguments[arguments.length - 1];
|
|
489
|
-
try {
|
|
490
|
-
let policies = ${JSON.stringify(aChecker.Config.policies)};
|
|
491
|
-
|
|
492
|
-
let checker = new window.ace.Checker();
|
|
493
|
-
setTimeout(function() {
|
|
494
|
-
checker.check(document, policies).then(function(report) {
|
|
495
|
-
for (const result of report.results) {
|
|
496
|
-
delete result.node;
|
|
497
|
-
}
|
|
498
|
-
cb(report);
|
|
499
|
-
})
|
|
500
|
-
},0)
|
|
501
|
-
} catch (e) {
|
|
502
|
-
cb(e);
|
|
503
|
-
}`
|
|
504
|
-
let manage = browser.manage();
|
|
505
|
-
if (manage.timeouts) {
|
|
506
|
-
manage.timeouts().setScriptTimeout(60000);
|
|
507
|
-
} else if (manage.setTimeouts) {
|
|
508
|
-
manage.setTimeouts({
|
|
509
|
-
"script": 60000
|
|
510
|
-
})
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
let report = await browser.executeAsyncScript(scriptStr);
|
|
514
|
-
const getPolicies = "return new window.ace.Checker().rulesetIds;";
|
|
515
|
-
if (curPol != null && !aChecker.Config.checkPolicy) {
|
|
516
|
-
aChecker.Config.checkPolicy = true;
|
|
517
|
-
const valPolicies = await browser.executeScript(getPolicies);
|
|
518
|
-
areValidPolicy(valPolicies, curPol);
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
// If there is something to report...
|
|
522
|
-
if (report.results) {
|
|
523
|
-
// Add URL to the result object
|
|
524
|
-
const url = await browser.getCurrentUrl();
|
|
525
|
-
report.summary = report.summary || {}
|
|
526
|
-
report.summary.URL = url;
|
|
527
|
-
report.counts = {}
|
|
528
|
-
let origReport = JSON.parse(JSON.stringify(report));
|
|
529
|
-
origReport = aChecker.buildReport(origReport, url, label, startScan);
|
|
530
|
-
|
|
531
|
-
// Filter the violations based on the reporLevels
|
|
532
|
-
report = aChecker.filterViolations(report);
|
|
533
|
-
|
|
534
|
-
// Add the count object, to data a recount after the filtering of violations is done.
|
|
535
|
-
report = aChecker.updateViolationCount(report);
|
|
536
|
-
|
|
537
|
-
// Add the violation count to global summary object
|
|
538
|
-
aChecker.addToSummaryCount(report.counts);
|
|
539
|
-
|
|
540
|
-
// Build the report object for this scan, to follow a specific format. Refer to the
|
|
541
|
-
// function prolog for more information on the object creation.
|
|
542
|
-
report = aChecker.buildReport(report, url, label, startScan);
|
|
543
|
-
|
|
544
|
-
// Add the scan results to global karma result object which can be accessed when users testcase
|
|
545
|
-
// finishes, user can also access it to alter it for any reason.
|
|
546
|
-
aChecker.addResultsToGlobal(report);
|
|
547
|
-
|
|
548
|
-
// Need to call a karma API to send the results of a single scan to the accessibility-checker reporter so that they can be
|
|
549
|
-
// saved to a file by the server side reporter.
|
|
550
|
-
aChecker.sendResultsToReporter(origReport, report, "Selenium");
|
|
551
|
-
|
|
552
|
-
if (aChecker.Config.captureScreenshots && browser.takeScreenshot) {
|
|
553
|
-
const image = await browser.takeScreenshot();
|
|
554
|
-
let screenshotResult = {
|
|
555
|
-
image: image,
|
|
556
|
-
label: label,
|
|
557
|
-
scanID: report.scanID
|
|
558
|
-
};
|
|
559
|
-
|
|
560
|
-
aChecker.sendScreenShotToReporter(screenshotResult);
|
|
561
|
-
}
|
|
562
|
-
}
|
|
563
|
-
return {
|
|
564
|
-
"report": report,
|
|
565
|
-
"webdriver": parsed
|
|
566
|
-
}
|
|
567
|
-
} catch (err) {
|
|
568
|
-
console.error(err);
|
|
569
|
-
return Promise.reject(err);
|
|
570
|
-
};
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
aChecker.getComplianceHelperPuppeteer = async (label, parsed, curPol) => {
|
|
574
|
-
try {
|
|
575
|
-
const startScan = Date.now();
|
|
576
|
-
// NOTE: Engine should already be loaded
|
|
577
|
-
const page = parsed;
|
|
578
|
-
const winHandle = await page.evaluateHandle("window");
|
|
579
|
-
let report = await page.evaluate((window, policies) => {
|
|
580
|
-
let checker = new window.ace.Checker();
|
|
581
|
-
return new Promise((resolve, reject) => {
|
|
582
|
-
setTimeout(function () {
|
|
583
|
-
checker.check(document, policies).then(function (report) {
|
|
584
|
-
for (const result of report.results) {
|
|
585
|
-
delete result.node;
|
|
586
|
-
}
|
|
587
|
-
resolve(report);
|
|
588
|
-
})
|
|
589
|
-
}, 0)
|
|
590
|
-
})
|
|
591
|
-
}, winHandle, aChecker.Config.policies);
|
|
592
|
-
if (curPol != null && !aChecker.Config.checkPolicy) {
|
|
593
|
-
const valPolicies = await page.evaluate("new window.ace.Checker().rulesetIds");
|
|
594
|
-
aChecker.Config.checkPolicy = true;
|
|
595
|
-
areValidPolicy(valPolicies, curPol);
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
// If there is something to report...
|
|
599
|
-
if (report.results) {
|
|
600
|
-
let url = await page.evaluate("document.location.href");
|
|
601
|
-
report.summary = report.summary || {}
|
|
602
|
-
report.summary.URL = url;
|
|
603
|
-
report.counts = {}
|
|
604
|
-
|
|
605
|
-
let origReport = JSON.parse(JSON.stringify(report));
|
|
606
|
-
origReport = aChecker.buildReport(origReport, url, label, startScan);
|
|
607
|
-
|
|
608
|
-
// Filter the violations based on the reporLevels
|
|
609
|
-
report = aChecker.filterViolations(report);
|
|
610
|
-
|
|
611
|
-
// Add the count object, to data a recount after the filtering of violations is done.
|
|
612
|
-
report = aChecker.updateViolationCount(report);
|
|
613
|
-
|
|
614
|
-
// Add the violation count to global summary object
|
|
615
|
-
aChecker.addToSummaryCount(report.counts);
|
|
616
|
-
|
|
617
|
-
// Build the report object for this scan, to follow a specific format. Refer to the
|
|
618
|
-
// function prolog for more information on the object creation.
|
|
619
|
-
report = aChecker.buildReport(report, url, label, startScan);
|
|
620
|
-
|
|
621
|
-
// Add the scan results to global karma result object which can be accessed when users testcase
|
|
622
|
-
// finishes, user can also access it to alter it for any reason.
|
|
623
|
-
aChecker.addResultsToGlobal(report);
|
|
624
|
-
|
|
625
|
-
// Need to call a karma API to send the results of a single scan to the accessibility-checker reporter so that they can be
|
|
626
|
-
// saved to a file by the server side reporter.
|
|
627
|
-
aChecker.sendResultsToReporter(origReport, report, "Puppeteer");
|
|
628
|
-
|
|
629
|
-
if (aChecker.Config.captureScreenshots) {
|
|
630
|
-
let image = await page.screenshot({
|
|
631
|
-
fullPage: true,
|
|
632
|
-
encoding: "base64"
|
|
633
|
-
});
|
|
634
|
-
let screenshotResult = {
|
|
635
|
-
image: image,
|
|
636
|
-
label: label,
|
|
637
|
-
scanID: report.scanID
|
|
638
|
-
};
|
|
639
|
-
|
|
640
|
-
aChecker.sendScreenShotToReporter(screenshotResult);
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
page.aceBusy = false;
|
|
644
|
-
|
|
645
|
-
return {
|
|
646
|
-
"report": report,
|
|
647
|
-
"puppeteer": parsed
|
|
648
|
-
};
|
|
649
|
-
} catch (err) {
|
|
650
|
-
console.error(err);
|
|
651
|
-
return Promise.reject(err);
|
|
652
|
-
};
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
aChecker.getComplianceHelperLocal = async (label, parsed, curPol) => {
|
|
656
|
-
try {
|
|
657
|
-
let startScan = Date.now();
|
|
658
|
-
let checker = new ace.Checker();
|
|
659
|
-
let report = await checker.check(parsed, aChecker.Config.policies)
|
|
660
|
-
.then(function (report) {
|
|
661
|
-
for (const result of report.results) {
|
|
662
|
-
delete result.node;
|
|
165
|
+
function getParsed(content) {
|
|
166
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
167
|
+
var isURLRegex;
|
|
168
|
+
return __generator(this, function (_a) {
|
|
169
|
+
if (!content)
|
|
170
|
+
return [2 /*return*/, null];
|
|
171
|
+
// Handle local file and URL's
|
|
172
|
+
if (typeof content === "string") {
|
|
173
|
+
isURLRegex = /^(ftp|http|https):\/\//;
|
|
174
|
+
if (isURLRegex.test(content)) {
|
|
175
|
+
URL = content;
|
|
176
|
+
}
|
|
177
|
+
// Since this is a string, we consider this as either URL or local file
|
|
178
|
+
// so build an iframe based on this and get the frame doc and then scan this.
|
|
179
|
+
return [2 /*return*/, ACBrowserManager_1.ACBrowserManager.buildIframeAndGetDoc(content)];
|
|
663
180
|
}
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
report = aChecker.updateViolationCount(report);
|
|
688
|
-
|
|
689
|
-
// Add the violation count to global summary object
|
|
690
|
-
aChecker.addToSummaryCount(report.counts);
|
|
691
|
-
|
|
692
|
-
// Build the report object for this scan, to follow a specific format. Refer to the
|
|
693
|
-
// function prolog for more information on the object creation.
|
|
694
|
-
report = aChecker.buildReport(report, URL, label, startScan);
|
|
695
|
-
|
|
696
|
-
// Add the scan results to global karma result object which can be accessed when users testcase
|
|
697
|
-
// finishes, user can also access it to alter it for any reason.
|
|
698
|
-
aChecker.addResultsToGlobal(report);
|
|
699
|
-
|
|
700
|
-
// Need to call a karma API to send the results of a single scan to the accessibility-checker reporter so that they can be
|
|
701
|
-
// saved to a file by the server side reporter.
|
|
702
|
-
aChecker.sendResultsToReporter(origReport, report, "Native");
|
|
703
|
-
}
|
|
704
|
-
|
|
705
|
-
return {
|
|
706
|
-
"report": report
|
|
707
|
-
};
|
|
708
|
-
} catch (err) {
|
|
709
|
-
console.error(err);
|
|
710
|
-
return Promise.reject(err);
|
|
711
|
-
};
|
|
712
|
-
}
|
|
713
|
-
|
|
714
|
-
/**
|
|
715
|
-
* This function is responsible for checking if the provided label is unique or not.
|
|
716
|
-
*
|
|
717
|
-
* @param {String} label - Provide the label which should be checked if it exists or not
|
|
718
|
-
*
|
|
719
|
-
* @return {boolean} labelExists - return false if the label is not unique, otherwise return true
|
|
720
|
-
*
|
|
721
|
-
* PRIVATE METHOD
|
|
722
|
-
*
|
|
723
|
-
* @memberOf this
|
|
724
|
-
*/
|
|
725
|
-
aChecker.isLabelUnique = function (label) {
|
|
726
|
-
aChecker.DEBUG && console.log("START 'aChecker.isLabelUnique' function");
|
|
727
|
-
|
|
728
|
-
// Variable Decleration
|
|
729
|
-
let labelExists = false;
|
|
730
|
-
|
|
731
|
-
aChecker.DEBUG && console.log("Checking if label: " + label + " is unique.");
|
|
732
|
-
|
|
733
|
-
// Check if the label that is provided was already used or not, by simply calling the some API on the array
|
|
734
|
-
// and passing it a callback function which checks if the label exists in the global paceScanSummary object.
|
|
735
|
-
labelExists = aChecker.scanSummary.pageScanSummary.some(function (scanSummary) {
|
|
736
|
-
return scanSummary.label === label;
|
|
737
|
-
});
|
|
738
|
-
|
|
739
|
-
aChecker.DEBUG && console.log("END 'aChecker.isLabelUnique' function");
|
|
740
|
-
|
|
741
|
-
return !labelExists;
|
|
742
|
-
};
|
|
743
|
-
|
|
744
|
-
/**
|
|
745
|
-
* This function is responsible for sending the scan results to the karma server accessibility-checker reporter. The
|
|
746
|
-
* accessibility-checker reporter is responsible for writing the results to a file. The reporter will also keep track of
|
|
747
|
-
* the summary results, on the server side.
|
|
748
|
-
*
|
|
749
|
-
* @param {Object} results - Provide the full results object which is to be reported/saved to file.
|
|
750
|
-
* refer to return in function "aChecker.buildReport" prolog
|
|
751
|
-
*
|
|
752
|
-
* @return N/A
|
|
753
|
-
*
|
|
754
|
-
* PRIVATE METHOD
|
|
755
|
-
*
|
|
756
|
-
* @memberOf this
|
|
757
|
-
*/
|
|
758
|
-
aChecker.sendResultsToReporter = function (unFilteredResults, results, profile) {
|
|
759
|
-
aChecker.DEBUG && console.log("sendResultsToReporter:", aChecker.Config.outputFormat);
|
|
760
|
-
if (aChecker.Config.outputFormat.indexOf("json") != -1) {
|
|
761
|
-
reporterJSON.report(results);
|
|
762
|
-
}
|
|
763
|
-
if (aChecker.Config.outputFormat.includes("csv")) {
|
|
764
|
-
reporterCSV.report(results);
|
|
765
|
-
}
|
|
766
|
-
if (aChecker.Config.outputFormat.indexOf("html") != -1) {
|
|
767
|
-
reporterHTML.report(unFilteredResults);
|
|
768
|
-
}
|
|
769
|
-
// Only perform the profiling if profiling was not disabled on purpose
|
|
770
|
-
if (!aChecker.Config.label || aChecker.Config.label.indexOf("IBMa-Node-TeSt") === -1) {
|
|
771
|
-
// Meter the usage here
|
|
772
|
-
metricsLogger.profileV2(results.summary.scanTime, profile);
|
|
773
|
-
}
|
|
774
|
-
};
|
|
775
|
-
|
|
776
|
-
aChecker.sendScreenShotToReporter = function (screenshotResult) {
|
|
777
|
-
};
|
|
778
|
-
|
|
779
|
-
try {
|
|
780
|
-
// If cucumber is the platform...
|
|
781
|
-
let {AfterAll} = require('cucumber');
|
|
782
|
-
AfterAll(function (done) {
|
|
783
|
-
initialize().then(() => metricsLogger.sendLogsV2(() => aChecker.close().then(done), aChecker.Config.rulePack));
|
|
784
|
-
});
|
|
785
|
-
} catch (e) {
|
|
786
|
-
if (typeof (after) !== "undefined") {
|
|
787
|
-
after(function (done) {
|
|
788
|
-
initialize().then(() => metricsLogger.sendLogsV2(() => aChecker.close().then(done), aChecker.Config.rulePack));
|
|
789
|
-
});
|
|
790
|
-
} else {
|
|
791
|
-
process.on('beforeExit', async function () {
|
|
792
|
-
initialize().then(() => metricsLogger.sendLogsV2(null, aChecker.Config.rulePack));
|
|
793
|
-
aChecker.close();
|
|
794
|
-
});
|
|
795
|
-
}
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
/**
|
|
799
|
-
* This function is responsible for building the results object in a specific format which will be provided back to
|
|
800
|
-
* the user to do any thing they want to do with it. (compare, print it, save to db, etc...)
|
|
801
|
-
*
|
|
802
|
-
* Note: This function converts it to match with the following format outlined at:
|
|
803
|
-
* https://github.com/IBMa/equal-access/tree/master/karma-accessibility-checker
|
|
804
|
-
*
|
|
805
|
-
* @param {Object} results - The results object which we need to build the report based on, following is the format the
|
|
806
|
-
* object needs to follow:
|
|
807
|
-
* {
|
|
808
|
-
* "report": {
|
|
809
|
-
* "numChecked": 227,
|
|
810
|
-
* "numTrigger": 1,
|
|
811
|
-
* "ruleTime": 5,
|
|
812
|
-
* "totalTime": 8,
|
|
813
|
-
* "issues": [
|
|
814
|
-
* {
|
|
815
|
-
* "severityCode": "eISHigh",
|
|
816
|
-
* "messageCode": "rpt.g377.elemUniqueId",
|
|
817
|
-
* "ruleId": "377",
|
|
818
|
-
* "help": "idhi_accessibility_check_g377.html",
|
|
819
|
-
* "msgArgs": [
|
|
820
|
-
* "div",
|
|
821
|
-
* "firstDiv"
|
|
822
|
-
* ],
|
|
823
|
-
* "xpath": "/html[1]/body[1]/div[2]/div[2]",
|
|
824
|
-
* "snippet": "<div id=\"firstDiv\">",
|
|
825
|
-
* "bounds": {
|
|
826
|
-
* "left": 10,
|
|
827
|
-
* "top": 181,
|
|
828
|
-
* "height": 0,
|
|
829
|
-
* "width": 1249
|
|
830
|
-
* },
|
|
831
|
-
* "level": "violation"
|
|
832
|
-
* }
|
|
833
|
-
* ],
|
|
834
|
-
* "docTitle": "Helo World"
|
|
835
|
-
* },
|
|
836
|
-
* "counts": {
|
|
837
|
-
* "violation": 1,
|
|
838
|
-
* "potentialviolation": 0,
|
|
839
|
-
* "recommendation": 0,
|
|
840
|
-
* "potentialrecommendation": 0,
|
|
841
|
-
* "manual": 0
|
|
842
|
-
* },
|
|
843
|
-
* "issueMessages": {
|
|
844
|
-
* "messages": {
|
|
845
|
-
* "rpt.g377.elemUniqueId": "The {0} element has the id \"{1}\" that is either empty or already in use."
|
|
846
|
-
* },
|
|
847
|
-
* "lang": "en-us"
|
|
848
|
-
* }
|
|
849
|
-
* }
|
|
850
|
-
*
|
|
851
|
-
* @param {String} URL - The URL which the report is being built for
|
|
852
|
-
* @param {String} label - A label to identify what this report is going to be for, in the case not using URL or local files.
|
|
853
|
-
* @param {String} startScan - The start time of the scan.
|
|
854
|
-
*
|
|
855
|
-
* @return {Object} results - return the formatted results based in the following format:
|
|
856
|
-
*
|
|
857
|
-
* {
|
|
858
|
-
* "scanID": "ef3aec68-f073-4f9c-b372-421ae00bd55d",
|
|
859
|
-
* "toolID": "karma-ibma-v1.0.0",
|
|
860
|
-
* "summary": {
|
|
861
|
-
* "counts": {
|
|
862
|
-
* "violation": 5,
|
|
863
|
-
* "potentialviolation": 0,
|
|
864
|
-
* "recommendation": 5,
|
|
865
|
-
* "potentialrecommendation": 0,
|
|
866
|
-
* "manual": 1
|
|
867
|
-
* },
|
|
868
|
-
* "scanTime": 80,
|
|
869
|
-
* "policies": [
|
|
870
|
-
* "CI162_5_2_DCP080115"
|
|
871
|
-
* ],
|
|
872
|
-
* "reportLevels": [
|
|
873
|
-
* "violation",
|
|
874
|
-
* "potentialviolation",
|
|
875
|
-
* "recommendation",
|
|
876
|
-
* "potentialrecommendation",
|
|
877
|
-
* "manual"
|
|
878
|
-
* ],
|
|
879
|
-
* "startScan": "2016-06-06T00:52:41.603Z"
|
|
880
|
-
* },
|
|
881
|
-
* "URL": "",
|
|
882
|
-
* "label": "unitTestContent",
|
|
883
|
-
* "screenshot": "<placeholder>",
|
|
884
|
-
* "issueMessages": {
|
|
885
|
-
* "messages": {
|
|
886
|
-
* "rpt.g377.elemUniqueId": "The {0} element has the id \"{1}\" that is either empty or already in use."
|
|
887
|
-
* },
|
|
888
|
-
* "lang": "en-us"
|
|
889
|
-
* },
|
|
890
|
-
* "reports": [
|
|
891
|
-
* {
|
|
892
|
-
* "frameIdx": "0",
|
|
893
|
-
* "frameTitle": "Frame 0",
|
|
894
|
-
* "issues": [
|
|
895
|
-
* {
|
|
896
|
-
* "severity": "Low",
|
|
897
|
-
* "message": "If style sheets are ignored or unsupported, ensure that pages are still readable and usable.",
|
|
898
|
-
* "messageCode": "rpt.g1.styleTrigger",
|
|
899
|
-
* "ruleId": "1",
|
|
900
|
-
* "help": "idhi_accessibility_check_g1.html",
|
|
901
|
-
* "msgArgs": [],
|
|
902
|
-
* "bounds": {
|
|
903
|
-
* "left": 0,
|
|
904
|
-
* "top": 0,
|
|
905
|
-
* "height": 0,
|
|
906
|
-
* "width": 0
|
|
907
|
-
* },
|
|
908
|
-
* "level": "manual",
|
|
909
|
-
* "xpath": "/html[1]/head[1]/style[1]",
|
|
910
|
-
* "snippet": "<style type=\"text/css\">"
|
|
911
|
-
* }
|
|
912
|
-
* ....
|
|
913
|
-
* ]
|
|
914
|
-
* },
|
|
915
|
-
* {
|
|
916
|
-
* "frameIdx": "1",
|
|
917
|
-
* "frameTitle": "Frame 1",
|
|
918
|
-
* "issues": [
|
|
919
|
-
* {
|
|
920
|
-
* "severity": "High",
|
|
921
|
-
* "message": "The table element with WAI-ARIA presentation role has structural element(s) and/or attribute(s) td.",
|
|
922
|
-
* "messageCode": "rpt.g471.tableStructure",
|
|
923
|
-
* "ruleId": "471",
|
|
924
|
-
* "help": "idhi_accessibility_check_g471.html",
|
|
925
|
-
* "msgArgs": [
|
|
926
|
-
* "table",
|
|
927
|
-
* "td"
|
|
928
|
-
* ],
|
|
929
|
-
* "bounds": {
|
|
930
|
-
* "left": 10,
|
|
931
|
-
* "top": 990,
|
|
932
|
-
* "height": 219,
|
|
933
|
-
* "width": 335
|
|
934
|
-
* },
|
|
935
|
-
* "level": "violation",
|
|
936
|
-
* "xpath": "/html[1]/body[1]/div[2]/table[3]",
|
|
937
|
-
* "snippet": "<table id=\"layout_table3\" role=\"presentation\">"
|
|
938
|
-
* }
|
|
939
|
-
* ....
|
|
940
|
-
* ]
|
|
941
|
-
* }
|
|
942
|
-
* ]
|
|
943
|
-
* }
|
|
944
|
-
*
|
|
945
|
-
* PRIVATE METHOD
|
|
946
|
-
*
|
|
947
|
-
* @memberOf this
|
|
948
|
-
*/
|
|
949
|
-
aChecker.buildReport = function (report, URL, label, startScan) {
|
|
950
|
-
// Build the scan summary object which will be added to the build report
|
|
951
|
-
// Note: This summary is only for this single scan.
|
|
952
|
-
report.summary = {
|
|
953
|
-
counts: report.counts,
|
|
954
|
-
scanTime: report.totalTime,
|
|
955
|
-
ruleArchive: aChecker.Config.ruleArchive,
|
|
956
|
-
policies: aChecker.Config.policies,
|
|
957
|
-
reportLevels: aChecker.Config.reportLevels,
|
|
958
|
-
startScan: startScan
|
|
959
|
-
};
|
|
960
|
-
|
|
961
|
-
// Add scanID (UUID) to the individual pages
|
|
962
|
-
report.scanID = aChecker.Config.scanID;
|
|
963
|
-
|
|
964
|
-
// Add toolID to the individual pages
|
|
965
|
-
report.toolID = aChecker.Config.toolID;
|
|
966
|
-
|
|
967
|
-
// Add the URL to the object it it is defined
|
|
968
|
-
if (URL !== null && typeof URL !== "undefined") {
|
|
969
|
-
report.summary.URL = URL;
|
|
970
|
-
}
|
|
971
|
-
|
|
972
|
-
// Add the label to the result object, label should always be
|
|
973
|
-
// defined no matter what as it is required to be provided by the user.
|
|
974
|
-
report.label = label;
|
|
975
|
-
|
|
976
|
-
// Add the screenshot base64 object to the results object
|
|
977
|
-
// TODO: Find a way to actually extract the screenshot, since karma
|
|
978
|
-
// allows the use of any browesr, some browser do not allow taking screenshot
|
|
979
|
-
// so would have to alalyze which browser allow it and take it for only those.
|
|
980
|
-
// PhantonJS, any selenium drived browser.
|
|
981
|
-
//results.screenshot = "<placeholder>";
|
|
982
|
-
|
|
983
|
-
// Clean up the results object
|
|
984
|
-
delete report.counts;
|
|
985
|
-
delete report.ruleTime;
|
|
986
|
-
delete report.totalTime;
|
|
987
|
-
|
|
988
|
-
if (aChecker.Config.disableIgnore === undefined || aChecker.Config.disableIgnore == false || aChecker.Config.disableIgnore === null) {
|
|
989
|
-
// set ignore:true for previously seen violations
|
|
990
|
-
// retrieve baseline
|
|
991
|
-
let baselineReport = aChecker.getBaseline(label);
|
|
992
|
-
|
|
993
|
-
// set ignore:true for previously seen violations and set ignore to false if no ignore fields exist yet
|
|
994
|
-
if (baselineReport) {
|
|
995
|
-
report = aChecker.ignoreExtraBaselineViolations(report, baselineReport);
|
|
996
|
-
}
|
|
997
|
-
else { //add ignored field
|
|
998
|
-
report.summary.counts.ignored = 0;
|
|
999
|
-
}
|
|
1000
|
-
}
|
|
1001
|
-
|
|
1002
|
-
let lvlIdx = {
|
|
1003
|
-
"violation": 1,
|
|
1004
|
-
"potentialviolation": 2,
|
|
1005
|
-
"recommendation": 3,
|
|
1006
|
-
"potentialrecommendation": 4,
|
|
1007
|
-
"manual": 5,
|
|
1008
|
-
"pass": 6
|
|
1009
|
-
};
|
|
1010
|
-
|
|
1011
|
-
report.results.sort(function (a, b) {
|
|
1012
|
-
let aLvl = lvlIdx[a.level];
|
|
1013
|
-
let bLvl = lvlIdx[b.level];
|
|
1014
|
-
if (!aLvl) aLvl = 7;
|
|
1015
|
-
if (!bLvl) bLvl = 7;
|
|
1016
|
-
return aLvl != bLvl && aLvl - bLvl ||
|
|
1017
|
-
b.ruleId != a.ruleId && b.ruleId - a.ruleId ||
|
|
1018
|
-
b.path.dom - a.path.dom;
|
|
1019
|
-
});
|
|
1020
|
-
|
|
1021
|
-
return report;
|
|
1022
|
-
};
|
|
1023
|
-
|
|
1024
|
-
/**
|
|
1025
|
-
* This function is responsible for indexing the results into global spaces based on label.
|
|
1026
|
-
*
|
|
1027
|
-
* @param {Object} results - Results object which will be provided to the user/wroten to the file.
|
|
1028
|
-
* Refer to aChecker.buildReport function's return to figure out what the object
|
|
1029
|
-
* will look like.
|
|
1030
|
-
*
|
|
1031
|
-
* @return - N/A - Global object is updated with the results
|
|
1032
|
-
*
|
|
1033
|
-
* PRIVATE METHOD
|
|
1034
|
-
*
|
|
1035
|
-
* @memberOf this
|
|
1036
|
-
*/
|
|
1037
|
-
aChecker.addResultsToGlobal = function (results) {
|
|
1038
|
-
|
|
1039
|
-
// Build the single page summary object to follow the following format:
|
|
1040
|
-
// "label": "dependencies/tools-rules-html/v2/a11y/test/g471/Table-DataNoSummaryARIA.html",
|
|
1041
|
-
// "counts": {
|
|
1042
|
-
// "violation": 1,
|
|
1043
|
-
// "potentialviolation": 0,
|
|
1044
|
-
// "recommendation": 0,
|
|
1045
|
-
// "potentialrecommendation": 0,
|
|
1046
|
-
// "manual": 0
|
|
1047
|
-
// }
|
|
1048
|
-
let pageSummaryObject = {
|
|
1049
|
-
label: results.label,
|
|
1050
|
-
counts: results.summary.counts
|
|
1051
|
-
};
|
|
1052
|
-
|
|
1053
|
-
// Add the summary count for this scan to the pageScanSummary object which is in the global space
|
|
1054
|
-
// Index this by the label.
|
|
1055
|
-
aChecker.scanSummary.pageScanSummary.push(pageSummaryObject);
|
|
1056
|
-
|
|
1057
|
-
// Add the scan results to global space
|
|
1058
|
-
aChecker.scanResults[results.label] = results;
|
|
1059
|
-
};
|
|
1060
|
-
|
|
1061
|
-
let browserP;
|
|
1062
|
-
|
|
1063
|
-
aChecker.getBrowserChrome = async (force) => {
|
|
1064
|
-
if (force || !browserP) {
|
|
1065
|
-
return browserP = puppeteer.launch({headless: aChecker.Config.headless, ignoreHTTPSErrors: aChecker.Config.ignoreHTTPSErrors || false});
|
|
1066
|
-
} else {
|
|
1067
|
-
return browserP;
|
|
1068
|
-
}
|
|
1069
|
-
}
|
|
1070
|
-
|
|
1071
|
-
aChecker.close = async () => {
|
|
1072
|
-
if (browserP) {
|
|
1073
|
-
let browser = await browserP;
|
|
1074
|
-
await browser.close();
|
|
1075
|
-
browserP = null;
|
|
1076
|
-
pages = [];
|
|
1077
|
-
}
|
|
1078
|
-
}
|
|
1079
|
-
|
|
1080
|
-
/**
|
|
1081
|
-
* This function is responsible for building an iframe object with the provided URL or local file.
|
|
1082
|
-
*
|
|
1083
|
-
* @param {String} URLorLocalFile - Provide a URL or local file to scan.
|
|
1084
|
-
*
|
|
1085
|
-
* @return {Object} content - return an object which contains the iframeDoc and also the URL or
|
|
1086
|
-
* local file name.
|
|
1087
|
-
*
|
|
1088
|
-
* PRIVATE METHOD
|
|
1089
|
-
*
|
|
1090
|
-
* @memberOf this
|
|
1091
|
-
*/
|
|
1092
|
-
let numInits = 0;
|
|
1093
|
-
let pages = [];
|
|
1094
|
-
aChecker.buildIframeAndGetDoc = async function (URLorLocalFileorContent) {
|
|
1095
|
-
const MAX_TABS = aChecker.Config.maxTabs;
|
|
1096
|
-
const browser = await aChecker.getBrowserChrome();
|
|
1097
|
-
|
|
1098
|
-
// Clear out any pages that are already closed
|
|
1099
|
-
pages = pages.map((page) => !page.isClosed() ? page : null);
|
|
1100
|
-
|
|
1101
|
-
// If there's an existing, ready page, use it
|
|
1102
|
-
let availPage;
|
|
1103
|
-
for (const page of pages) {
|
|
1104
|
-
if (!availPage) {
|
|
1105
|
-
if (!page.aceBusy) {
|
|
1106
|
-
availPage = page;
|
|
1107
|
-
page.aceBusy = true;
|
|
1108
|
-
}
|
|
1109
|
-
}
|
|
1110
|
-
}
|
|
1111
|
-
|
|
1112
|
-
if (!availPage) {
|
|
1113
|
-
// All pages are busy. Should we create a new one?
|
|
1114
|
-
if (pages.length+numInits >= MAX_TABS) {
|
|
1115
|
-
// Too many pages, restart
|
|
1116
|
-
return new Promise((resolve, reject) => {
|
|
1117
|
-
setTimeout(async () => {
|
|
1118
|
-
resolve(await aChecker.buildIframeAndGetDoc(URLorLocalFileorContent));
|
|
1119
|
-
}, 500);
|
|
1120
|
-
});
|
|
1121
|
-
} else {
|
|
1122
|
-
// Let's create a new page
|
|
1123
|
-
++numInits;
|
|
1124
|
-
|
|
1125
|
-
let newPage = await browser.newPage();
|
|
1126
|
-
newPage.on('console', msg => {
|
|
1127
|
-
for (let i = 0; i < msg.args.length; ++i)
|
|
1128
|
-
console.log(`${i}: ${msg.args[i]}`);
|
|
181
|
+
else if (ACEngineManager_1.ACEngineManager.isSelenium(content) || ACEngineManager_1.ACEngineManager.isPuppeteer(content) || ACEngineManager_1.ACEngineManager.isPlaywright(content)) {
|
|
182
|
+
}
|
|
183
|
+
// Handle Array of nodes
|
|
184
|
+
else if (content instanceof Array) {
|
|
185
|
+
// TODO: Supporting Array of nodes, possible future enhancenment
|
|
186
|
+
}
|
|
187
|
+
// Handle single node (HTMLElement)
|
|
188
|
+
else if (content.nodeType === 1) {
|
|
189
|
+
// In the case this is a node, there is nothing special that needs to be done at this time,
|
|
190
|
+
// the engine will be able to handle this. Adding this block here as we may need to add some filtering
|
|
191
|
+
// of rules or rule sets for this case depending on if a special ruleset needs to be created or not.
|
|
192
|
+
content = content;
|
|
193
|
+
}
|
|
194
|
+
// handle scanning document
|
|
195
|
+
else if (content.nodeType === 9) {
|
|
196
|
+
// In the case this is a document element, simply send the document object to the engine for now
|
|
197
|
+
// we will need to do some filtering to remove any karma related aspects, which requires to do a
|
|
198
|
+
// document clone, and then string the karma scripts that are added and then send this document
|
|
199
|
+
// to the engine.
|
|
200
|
+
// TODO: Investigate best approach to perform filtering
|
|
201
|
+
content = content;
|
|
202
|
+
}
|
|
203
|
+
return [2 /*return*/, content];
|
|
1129
204
|
});
|
|
1130
|
-
newPage.aceBusy = true;
|
|
1131
|
-
availPage = newPage;
|
|
1132
|
-
pages.push(newPage);
|
|
1133
|
-
--numInits;
|
|
1134
|
-
}
|
|
1135
|
-
}
|
|
1136
|
-
|
|
1137
|
-
let err = null,
|
|
1138
|
-
retVal = null;
|
|
1139
|
-
async function nav() {
|
|
1140
|
-
try {
|
|
1141
|
-
if (URLorLocalFileorContent.toLowerCase().includes("<html")) {
|
|
1142
|
-
// await page.goto(`data:text/html,encodeURIComponent(${URLorLocalFileorContent})`, { waitUntil: 'networkidle0' });
|
|
1143
|
-
let urlStr = "data:text/html;charset=utf-8," + encodeURIComponent(URLorLocalFileorContent);
|
|
1144
|
-
await availPage.goto(urlStr);
|
|
1145
|
-
} else {
|
|
1146
|
-
await availPage.goto(URLorLocalFileorContent);
|
|
1147
|
-
}
|
|
1148
|
-
} catch (e) {
|
|
1149
|
-
err = `${e.message} ${URLorLocalFileorContent}`;
|
|
1150
|
-
console.error(err);
|
|
1151
|
-
return null;
|
|
1152
|
-
}
|
|
1153
|
-
return availPage;
|
|
1154
|
-
}
|
|
1155
|
-
try {
|
|
1156
|
-
retVal = await nav();
|
|
1157
|
-
} catch (e) {
|
|
1158
|
-
}
|
|
1159
|
-
if (!retVal) {
|
|
1160
|
-
// Page bad or unable to navigate, start over
|
|
1161
|
-
page.close();
|
|
1162
|
-
return new Promise((resolve, reject) => {
|
|
1163
|
-
setTimeout(async () => {
|
|
1164
|
-
resolve(await aChecker.buildIframeAndGetDoc(URLorLocalFileorContent));
|
|
1165
|
-
}, 0);
|
|
1166
205
|
});
|
|
1167
206
|
}
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
*
|
|
1179
|
-
* TODO: Possibly we can add this to the engine, so that the results are not provided by the engine
|
|
1180
|
-
* when user has provided the reportLevels object.
|
|
1181
|
-
*
|
|
1182
|
-
* @param {Object} results - Provide the violation results, which follow the following format:
|
|
1183
|
-
* {
|
|
1184
|
-
* "report": {
|
|
1185
|
-
* "numChecked": 227,
|
|
1186
|
-
* "numTrigger": 1,
|
|
1187
|
-
* "ruleTime": 5,
|
|
1188
|
-
* "totalTime": 8,
|
|
1189
|
-
* "issues": [
|
|
1190
|
-
* {
|
|
1191
|
-
* "severityCode": "eISHigh",
|
|
1192
|
-
* "messageCode": "rpt.g377.elemUniqueId",
|
|
1193
|
-
* "ruleId": "377",
|
|
1194
|
-
* "help": "idhi_accessibility_check_g377.html",
|
|
1195
|
-
* "msgArgs": [
|
|
1196
|
-
* "div",
|
|
1197
|
-
* "firstDiv"
|
|
1198
|
-
* ],
|
|
1199
|
-
* "xpath": "/html[1]/body[1]/div[2]/div[2]",
|
|
1200
|
-
* "snippet": "<div id=\"firstDiv\">",
|
|
1201
|
-
* "bounds": {
|
|
1202
|
-
* "left": 10,
|
|
1203
|
-
* "top": 181,
|
|
1204
|
-
* "height": 0,
|
|
1205
|
-
* "width": 1249
|
|
1206
|
-
* },
|
|
1207
|
-
* "level": "violation"
|
|
1208
|
-
* }
|
|
1209
|
-
* ],
|
|
1210
|
-
* "docTitle": "Helo World"
|
|
1211
|
-
* },
|
|
1212
|
-
* "counts": {
|
|
1213
|
-
* "level.violation": 1,
|
|
1214
|
-
* "level.potentialviolation": 0,
|
|
1215
|
-
* "level.recommendation": 0,
|
|
1216
|
-
* "level.potentialrecommendation": 0,
|
|
1217
|
-
* "level.manual": 0
|
|
1218
|
-
* },
|
|
1219
|
-
* "issueMessages": {
|
|
1220
|
-
* "messages": {
|
|
1221
|
-
* "rpt.g377.elemUniqueId": "The {0} element has the id \"{1}\" that is either empty or already in use."
|
|
1222
|
-
* },
|
|
1223
|
-
* "lang": "en-us"
|
|
1224
|
-
* }
|
|
1225
|
-
* }
|
|
1226
|
-
*
|
|
1227
|
-
* @return {Object} results - return results object which only contains the violation that were requested,
|
|
1228
|
-
* follows the following format:
|
|
1229
|
-
* {
|
|
1230
|
-
* "report": {
|
|
1231
|
-
* "numChecked": 227,
|
|
1232
|
-
* "numTrigger": 1,
|
|
1233
|
-
* "ruleTime": 5,
|
|
1234
|
-
* "totalTime": 8,
|
|
1235
|
-
* "issues": [
|
|
1236
|
-
* {
|
|
1237
|
-
* "severityCode": "eISHigh",
|
|
1238
|
-
* "messageCode": "rpt.g377.elemUniqueId",
|
|
1239
|
-
* "ruleId": "377",
|
|
1240
|
-
* "help": "idhi_accessibility_check_g377.html",
|
|
1241
|
-
* "msgArgs": [
|
|
1242
|
-
* "div",
|
|
1243
|
-
* "firstDiv"
|
|
1244
|
-
* ],
|
|
1245
|
-
* "xpath": "/html[1]/body[1]/div[2]/div[2]",
|
|
1246
|
-
* "snippet": "<div id=\"firstDiv\">",
|
|
1247
|
-
* "bounds": {
|
|
1248
|
-
* "left": 10,
|
|
1249
|
-
* "top": 181,
|
|
1250
|
-
* "height": 0,
|
|
1251
|
-
* "width": 1249
|
|
1252
|
-
* },
|
|
1253
|
-
* "level": "violation"
|
|
1254
|
-
* }
|
|
1255
|
-
* ],
|
|
1256
|
-
* "docTitle": "Helo World"
|
|
1257
|
-
* },
|
|
1258
|
-
* "counts": {
|
|
1259
|
-
* "level.violation": 1,
|
|
1260
|
-
* "level.potentialviolation": 0,
|
|
1261
|
-
* "level.recommendation": 0,
|
|
1262
|
-
* "level.potentialrecommendation": 0,
|
|
1263
|
-
* "level.manual": 0
|
|
1264
|
-
* },
|
|
1265
|
-
* "issueMessages": {
|
|
1266
|
-
* "messages": {
|
|
1267
|
-
* "rpt.g377.elemUniqueId": "The {0} element has the id \"{1}\" that is either empty or already in use."
|
|
1268
|
-
* },
|
|
1269
|
-
* "lang": "en-us"
|
|
1270
|
-
* }
|
|
1271
|
-
* }
|
|
1272
|
-
*
|
|
1273
|
-
* The return object is pretty much filtered failures (results.report.fail), wrapped around another object with extra frameIdx value.
|
|
1274
|
-
*
|
|
1275
|
-
* PRIVATE METHOD
|
|
1276
|
-
*
|
|
1277
|
-
* @memberOf this
|
|
1278
|
-
*/
|
|
1279
|
-
aChecker.filterViolations = function (report) {
|
|
1280
|
-
|
|
1281
|
-
// Variable Decleration
|
|
1282
|
-
let reportLevels = aChecker.Config.reportLevels;
|
|
1283
|
-
let pageResults = report.results;
|
|
1284
|
-
for (let iDis = 0; aChecker.Config.disable && iDis < aChecker.Config.disable.length; ++iDis) {
|
|
1285
|
-
aChecker.Config.disable[iDis] = "" + aChecker.Config.disable[iDis];
|
|
1286
|
-
}
|
|
1287
|
-
// Loop over all the violations and filter them, if the violation level does not match with, what user has
|
|
1288
|
-
// requested to be reported. Also handle hidden at this point right now.
|
|
1289
|
-
// TODO: Posible to filter the results directly in the engine, to avoid the need to do all this in each of the tools.
|
|
1290
|
-
for (let i = 0; i < pageResults.length; ++i) {
|
|
1291
|
-
|
|
1292
|
-
// Set the default ignore value to false if disableIgnore field in config file is not true
|
|
1293
|
-
if (aChecker.Config.disableIgnore === undefined || aChecker.Config.disableIgnore == false || aChecker.Config.disableIgnore === null){
|
|
1294
|
-
pageResults[i].ignored = false;
|
|
1295
|
-
}
|
|
1296
|
-
if (aChecker.Config.disable && aChecker.Config.disable.indexOf(pageResults[i].ruleId) !== -1) {
|
|
1297
|
-
pageResults.splice(i--, 1);
|
|
1298
|
-
continue;
|
|
1299
|
-
}
|
|
1300
|
-
// Remove violation which are not in the reportLevels
|
|
1301
|
-
if (reportLevels) {
|
|
1302
|
-
// Fetch the level from the results
|
|
1303
|
-
let reportLevel = pageResults[i].value;
|
|
1304
|
-
if (reportLevel[1] === "PASS") {
|
|
1305
|
-
reportLevel = "pass";
|
|
1306
|
-
} else if ((reportLevel[0] === "VIOLATION" || reportLevel[0] === "RECOMMENDATION") && reportLevel[1] === "MANUAL") {
|
|
1307
|
-
reportLevel = "manual";
|
|
1308
|
-
} else if (reportLevel[0] === "VIOLATION") {
|
|
1309
|
-
if (reportLevel[1] === "FAIL") {
|
|
1310
|
-
reportLevel = "violation";
|
|
1311
|
-
} else if (reportLevel[1] === "POTENTIAL") {
|
|
1312
|
-
reportLevel = "potentialviolation";
|
|
207
|
+
var URL, parsed, testcaseWhichIsMissingRequiredLabel, generalErrorMessageLabelNotUnique, labelUnique, testcaseDoesNotUseUniqueLabel, generalErrorMessageLabelNotUnique, policies, curPol;
|
|
208
|
+
return __generator(this, function (_a) {
|
|
209
|
+
switch (_a.label) {
|
|
210
|
+
case 0: return [4 /*yield*/, initialize()];
|
|
211
|
+
case 1:
|
|
212
|
+
_a.sent();
|
|
213
|
+
Config.DEBUG && console.log("START 'aChecker.getCompliance' function");
|
|
214
|
+
if (!content) {
|
|
215
|
+
console.error("aChecker: Unable to get compliance of null or undefined object");
|
|
216
|
+
return [2 /*return*/, null];
|
|
1313
217
|
}
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
218
|
+
return [4 /*yield*/, getParsed(content)];
|
|
219
|
+
case 2:
|
|
220
|
+
parsed = _a.sent();
|
|
221
|
+
if (parsed === null)
|
|
222
|
+
return [2 /*return*/, null];
|
|
223
|
+
return [4 /*yield*/, ACEngineManager_1.ACEngineManager.loadEngine(parsed)];
|
|
224
|
+
case 3:
|
|
225
|
+
_a.sent();
|
|
226
|
+
// In the case that the label is null or undefined, throw an error using the karma API
|
|
227
|
+
// console.error with the message of the error.
|
|
228
|
+
if (label === null || typeof label === "undefined" || label === undefined) {
|
|
229
|
+
testcaseWhichIsMissingRequiredLabel = null;
|
|
230
|
+
generalErrorMessageLabelNotUnique = "\n[Error] labelNotProvided: Label must be provided when calling aChecker.getCompliance.";
|
|
231
|
+
// Get the caller of the aChecker.getCompliance function which will be the testcase that is calling this function
|
|
232
|
+
// This way we can make it the error more descriptive and would help the user identify where the issues is.
|
|
233
|
+
// We have to build and throw an Error() object and then using the try/catch to catch this error and then extract the
|
|
234
|
+
// stack and parse it to get the 2nd element in the stack which will be the caller of this function which will be the
|
|
235
|
+
// testcase which called this function.
|
|
236
|
+
try {
|
|
237
|
+
// Throw Error() object
|
|
238
|
+
throw new Error();
|
|
239
|
+
}
|
|
240
|
+
catch (exception) {
|
|
241
|
+
// Extract the stack trace from the error object and parse it to get the single one caller up which will be the 2nd index
|
|
242
|
+
testcaseWhichIsMissingRequiredLabel = exception.stack.split("\n")[1];
|
|
243
|
+
// Call the Karma error API, to send message to the Karma server that there was an error on the client side
|
|
244
|
+
console.error("Label was not provided at: " + testcaseWhichIsMissingRequiredLabel + generalErrorMessageLabelNotUnique);
|
|
245
|
+
}
|
|
1319
246
|
}
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
247
|
+
labelUnique = ACReportManager_1.ACReportManager.isLabelUnique(label);
|
|
248
|
+
// In the case that the label is not unique
|
|
249
|
+
if (!labelUnique) {
|
|
250
|
+
testcaseDoesNotUseUniqueLabel = null;
|
|
251
|
+
generalErrorMessageLabelNotUnique = "\n[Error] labelNotUnique: Label provided to aChecker.getCompliance should be unique across all testcases in a single accessibility-checker session.";
|
|
252
|
+
// Get the caller of the aChecker.getCompliance function which will be the testcase that is calling this function
|
|
253
|
+
// This way we can make it the error more descriptive and would help the user identify where the issues is.
|
|
254
|
+
// We have to build and throw an Error() object and then using the try/catch to catch this error and then extract the
|
|
255
|
+
// stack and parse it to get the 2nd element in the stack which will be the caller of this function which will be the
|
|
256
|
+
// testcase which called this function.
|
|
257
|
+
try {
|
|
258
|
+
// Throw Error() object
|
|
259
|
+
throw new Error();
|
|
260
|
+
}
|
|
261
|
+
catch (exception) {
|
|
262
|
+
// Extract the stack trace from the error object and parse it to get the single one caller up which will be the 2nd index
|
|
263
|
+
testcaseDoesNotUseUniqueLabel = exception.stack.split("\n")[1];
|
|
264
|
+
// Call the Karma error API, to send message to the Karma server that there was an error on the client side
|
|
265
|
+
console.error("Label \"" + label + "\" provided at: " + testcaseDoesNotUseUniqueLabel + " is not unique." + generalErrorMessageLabelNotUnique);
|
|
266
|
+
}
|
|
1329
267
|
}
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
}
|
|
1335
|
-
}
|
|
1336
|
-
|
|
1337
|
-
return report;
|
|
1338
|
-
};
|
|
1339
|
-
|
|
1340
|
-
/**
|
|
1341
|
-
* This function is responsible for iterating over all the issue elements and updating the counts object.
|
|
1342
|
-
*
|
|
1343
|
-
* @param {Object} pageResults - Provide the page results object, in the following format:
|
|
1344
|
-
* {
|
|
1345
|
-
* "report": {
|
|
1346
|
-
* "numChecked": 227,
|
|
1347
|
-
* "numTrigger": 1,
|
|
1348
|
-
* "ruleTime": 5,
|
|
1349
|
-
* "totalTime": 8,
|
|
1350
|
-
* "issues": [
|
|
1351
|
-
* {
|
|
1352
|
-
* "severityCode": "eISHigh",
|
|
1353
|
-
* "messageCode": "rpt.g377.elemUniqueId",
|
|
1354
|
-
* "ruleId": "377",
|
|
1355
|
-
* "help": "idhi_accessibility_check_g377.html",
|
|
1356
|
-
* "msgArgs": [
|
|
1357
|
-
* "div",
|
|
1358
|
-
* "firstDiv"
|
|
1359
|
-
* ],
|
|
1360
|
-
* "xpath": "/html[1]/body[1]/div[2]/div[2]",
|
|
1361
|
-
* "snippet": "<div id=\"firstDiv\">",
|
|
1362
|
-
* "bounds": {
|
|
1363
|
-
* "left": 10,
|
|
1364
|
-
* "top": 181,
|
|
1365
|
-
* "height": 0,
|
|
1366
|
-
* "width": 1249
|
|
1367
|
-
* },
|
|
1368
|
-
* "level": "violation"
|
|
1369
|
-
* }
|
|
1370
|
-
* ],
|
|
1371
|
-
* "docTitle": "Helo World"
|
|
1372
|
-
* },
|
|
1373
|
-
* "counts": {
|
|
1374
|
-
* "level.violation": 1,
|
|
1375
|
-
* "level.potentialviolation": 0,
|
|
1376
|
-
* "level.recommendation": 0,
|
|
1377
|
-
* "level.potentialrecommendation": 0,
|
|
1378
|
-
* "level.manual": 0
|
|
1379
|
-
* },
|
|
1380
|
-
* "issueMessages": {
|
|
1381
|
-
* "messages": {
|
|
1382
|
-
* "rpt.g377.elemUniqueId": "The {0} element has the id \"{1}\" that is either empty or already in use."
|
|
1383
|
-
* },
|
|
1384
|
-
* "lang": "en-us"
|
|
1385
|
-
* }
|
|
1386
|
-
* }
|
|
1387
|
-
* ......
|
|
1388
|
-
*
|
|
1389
|
-
* @return {Object} pageResults - return the results object with the count object updated
|
|
1390
|
-
* {
|
|
1391
|
-
* "report": {
|
|
1392
|
-
* "numChecked": 227,
|
|
1393
|
-
* "numTrigger": 1,
|
|
1394
|
-
* "ruleTime": 5,
|
|
1395
|
-
* "totalTime": 8,
|
|
1396
|
-
* "issues": [
|
|
1397
|
-
* {
|
|
1398
|
-
* "severityCode": "eISHigh",
|
|
1399
|
-
* "messageCode": "rpt.g377.elemUniqueId",
|
|
1400
|
-
* "ruleId": "377",
|
|
1401
|
-
* "help": "idhi_accessibility_check_g377.html",
|
|
1402
|
-
* "msgArgs": [
|
|
1403
|
-
* "div",
|
|
1404
|
-
* "firstDiv"
|
|
1405
|
-
* ],
|
|
1406
|
-
* "xpath": "/html[1]/body[1]/div[2]/div[2]",
|
|
1407
|
-
* "snippet": "<div id=\"firstDiv\">",
|
|
1408
|
-
* "bounds": {
|
|
1409
|
-
* "left": 10,
|
|
1410
|
-
* "top": 181,
|
|
1411
|
-
* "height": 0,
|
|
1412
|
-
* "width": 1249
|
|
1413
|
-
* },
|
|
1414
|
-
* "level": "violation"
|
|
1415
|
-
* }
|
|
1416
|
-
* ],
|
|
1417
|
-
* "docTitle": "Helo World"
|
|
1418
|
-
* },
|
|
1419
|
-
* "counts": {
|
|
1420
|
-
* "level.violation": 1,
|
|
1421
|
-
* "level.potentialviolation": 0,
|
|
1422
|
-
* "level.recommendation": 0,
|
|
1423
|
-
* "level.potentialrecommendation": 0,
|
|
1424
|
-
* "level.manual": 0
|
|
1425
|
-
* },
|
|
1426
|
-
* "issueMessages": {
|
|
1427
|
-
* "messages": {
|
|
1428
|
-
* "rpt.g377.elemUniqueId": "The {0} element has the id \"{1}\" that is either empty or already in use."
|
|
1429
|
-
* },
|
|
1430
|
-
* "lang": "en-us"
|
|
1431
|
-
* }
|
|
1432
|
-
* }
|
|
1433
|
-
*
|
|
1434
|
-
* PRIVATE METHOD
|
|
1435
|
-
*
|
|
1436
|
-
* @memberOf this
|
|
1437
|
-
*/
|
|
1438
|
-
aChecker.updateViolationCount = function (report) {
|
|
1439
|
-
|
|
1440
|
-
// Variable Decleration
|
|
1441
|
-
let reportLevels = aChecker.Config.reportLevels;
|
|
1442
|
-
|
|
1443
|
-
// Build violation count object which will contain the updated count based on filter which
|
|
1444
|
-
// which occured in filterViolations function.
|
|
1445
|
-
let violationCount = {};
|
|
1446
|
-
|
|
1447
|
-
// In the case that report levels are provided then populate the count object in
|
|
1448
|
-
// violationCount object with the levels which were provided in reportLevels
|
|
1449
|
-
// array/
|
|
1450
|
-
if (reportLevels) {
|
|
1451
|
-
|
|
1452
|
-
// Iterate over the report levels and populate the pageResultsWithCount counts
|
|
1453
|
-
// object
|
|
1454
|
-
reportLevels.forEach(function (levels) {
|
|
1455
|
-
violationCount[levels] = 0;
|
|
1456
|
-
});
|
|
1457
|
-
|
|
1458
|
-
}
|
|
1459
|
-
// Populate the pageResultsWithCount counts object with all the levels
|
|
1460
|
-
else {
|
|
1461
|
-
violationCount = {
|
|
1462
|
-
"violation": 0,
|
|
1463
|
-
"potentialviolation": 0,
|
|
1464
|
-
"recommendation": 0,
|
|
1465
|
-
"potentialrecommendation": 0,
|
|
1466
|
-
"manual": 0,
|
|
1467
|
-
"pass": 0
|
|
1468
|
-
};
|
|
1469
|
-
}
|
|
1470
|
-
|
|
1471
|
-
// Iterate over the page results
|
|
1472
|
-
for (const item of report.results) {
|
|
1473
|
-
if (item.level in violationCount) {
|
|
1474
|
-
++violationCount[item.level];
|
|
1475
|
-
}
|
|
1476
|
-
}
|
|
1477
|
-
|
|
1478
|
-
// Update the results count object with the new one which considers filtered results
|
|
1479
|
-
report.counts = violationCount;
|
|
1480
|
-
|
|
1481
|
-
return report;
|
|
1482
|
-
};
|
|
1483
|
-
|
|
1484
|
-
/**
|
|
1485
|
-
* This function is responsible for updating/creating the global violation summary for the engine karma run
|
|
1486
|
-
* for browser that it is running on. Will take the pageCount object which is part of the page object and
|
|
1487
|
-
* add extract the values for each of the levels and add them to the global object. This will provide an overall
|
|
1488
|
-
* summary of violations for all testcases run and all scans done.
|
|
1489
|
-
*
|
|
1490
|
-
* @param {Object} pageCount - Provide the page count object, in the following format:
|
|
1491
|
-
*
|
|
1492
|
-
* @return N/A - Global summary object is updated with the counts
|
|
1493
|
-
*
|
|
1494
|
-
* PRIVATE METHOD
|
|
1495
|
-
*
|
|
1496
|
-
* @memberOf this
|
|
1497
|
-
*/
|
|
1498
|
-
aChecker.addToSummaryCount = function (pageCount) {
|
|
1499
|
-
|
|
1500
|
-
// Variable Decleration
|
|
1501
|
-
let ACScanSummary = aChecker.scanSummary.counts || {};
|
|
1502
|
-
let addedToSummary = false;
|
|
1503
|
-
|
|
1504
|
-
// In the case ACScanSummary is empty, simply assign pageCount to ACScanSummary
|
|
1505
|
-
if (Object.keys(ACScanSummary).length === 0) {
|
|
1506
|
-
|
|
1507
|
-
// Set pageCount as the summary count
|
|
1508
|
-
ACScanSummary = pageCount;
|
|
1509
|
-
|
|
1510
|
-
addedToSummary = true;
|
|
1511
|
-
}
|
|
1512
|
-
|
|
1513
|
-
// In the case that this is not first scan, handle adding up the summary
|
|
1514
|
-
if (!addedToSummary) {
|
|
1515
|
-
// Go through the pageCount object and for each of the levels, extract the value
|
|
1516
|
-
// and add it to the accessibility-checker violation summary object.
|
|
1517
|
-
// This will keep track of an overall summary of the violations for all testscases, that
|
|
1518
|
-
// were run for a single karma run.
|
|
1519
|
-
for (let level in pageCount) {
|
|
1520
|
-
ACScanSummary[level] += pageCount[level];
|
|
1521
|
-
}
|
|
1522
|
-
}
|
|
1523
|
-
|
|
1524
|
-
// Assign the new violation summary back to the global object
|
|
1525
|
-
aChecker.scanSummary.counts = ACScanSummary;
|
|
1526
|
-
};
|
|
1527
|
-
|
|
1528
|
-
/**
|
|
1529
|
-
* This function is responsible for comparing the scan results with baseline or checking that there are
|
|
1530
|
-
* no violations which fall into the failsLevels levels. In the case a baseline is found then baseline will
|
|
1531
|
-
* be used to perform the check, in the case no baseline is provided then we comply with only failing if
|
|
1532
|
-
* there is a sinble violation which falls into failLevels.
|
|
1533
|
-
*
|
|
1534
|
-
* @param {Object} actual - the actual results object provided by the user, this object should follow the
|
|
1535
|
-
* same format as outlined in the return of aChecker.buildReport function.
|
|
1536
|
-
*
|
|
1537
|
-
* @return {int} - return 0 in the case actual matches baseline or no violations fall into failsLevels,
|
|
1538
|
-
* return 1 in the case actual results does not match baseline results,
|
|
1539
|
-
* return 2 in the case that there is a failure based on failLevels (this means no baseline found).
|
|
1540
|
-
* return -1 in the case that there is an exception that occured in the results object which came from the scan engine.
|
|
1541
|
-
*
|
|
1542
|
-
* PUBLIC API
|
|
1543
|
-
*
|
|
1544
|
-
* @memberOf this
|
|
1545
|
-
*/
|
|
1546
|
-
aChecker.assertCompliance = function (actualResults) {
|
|
1547
|
-
|
|
1548
|
-
// In the case that the details object contains Error object, this means that the scan engine through an
|
|
1549
|
-
// exception, therefore we should not compare results just fail instead.
|
|
1550
|
-
if (actualResults.details instanceof Error) {
|
|
1551
|
-
return -1;
|
|
1552
|
-
}
|
|
1553
|
-
|
|
1554
|
-
// Get the label directly from the results object, the same label has to match
|
|
1555
|
-
// the baseline object which is available in the global space.
|
|
1556
|
-
let label = actualResults.label;
|
|
1557
|
-
|
|
1558
|
-
// Fetch the baseline object based on the label provided
|
|
1559
|
-
let expected = aChecker.getBaseline(label);
|
|
1560
|
-
|
|
1561
|
-
// In the case there are no baseline found then run a different assertion algo,
|
|
1562
|
-
// when there is baseline compare the baselines in the case there is no baseline then
|
|
1563
|
-
// check to make sure there are no violations that are listed in the fails on.
|
|
1564
|
-
if (expected !== null && typeof (expected) !== "undefined") {
|
|
1565
|
-
// Run the diff algo to get the list of differences
|
|
1566
|
-
let differences = aChecker.diffResultsWithExpected(actualResults, expected, true);
|
|
1567
|
-
|
|
1568
|
-
//console.log(JSON.stringify(differences, null, ' '));
|
|
1569
|
-
|
|
1570
|
-
// In the case that there are no differences then that means it passed
|
|
1571
|
-
if (differences === null || typeof (differences) === "undefined") {
|
|
1572
|
-
return 0;
|
|
1573
|
-
} else {
|
|
1574
|
-
// Re-sort results and check again
|
|
1575
|
-
let modActual = JSON.parse(JSON.stringify(actualResults.results));
|
|
1576
|
-
modActual.sort((a, b) => {
|
|
1577
|
-
let cc = b.category.localeCompare(a.category);
|
|
1578
|
-
if (cc != 0) return cc;
|
|
1579
|
-
let pc = b.path.dom.localeCompare(a.path.dom);
|
|
1580
|
-
if (pc !== 0) return pc;
|
|
1581
|
-
return b.ruleId.localeCompare(a.ruleId);
|
|
1582
|
-
})
|
|
1583
|
-
let modExpected = JSON.parse(JSON.stringify(expected.results));
|
|
1584
|
-
modExpected.sort((a, b) => {
|
|
1585
|
-
let cc = b.category.localeCompare(a.category);
|
|
1586
|
-
if (cc != 0) return cc;
|
|
1587
|
-
let pc = b.path.dom.localeCompare(a.path.dom);
|
|
1588
|
-
if (pc !== 0) return pc;
|
|
1589
|
-
return b.ruleId.localeCompare(a.ruleId);
|
|
1590
|
-
})
|
|
1591
|
-
let differences2 = aChecker.diffResultsWithExpected({
|
|
1592
|
-
results: modActual,
|
|
1593
|
-
summary: actualResults.summary
|
|
1594
|
-
}, {
|
|
1595
|
-
results: modExpected ,
|
|
1596
|
-
summary: expected.summary
|
|
1597
|
-
}, true);
|
|
1598
|
-
if (differences2 === null || typeof (differences2) === "undefined") {
|
|
1599
|
-
return 0;
|
|
1600
|
-
} else {
|
|
1601
|
-
// In the case that there are failures add the whole diff array to
|
|
1602
|
-
// global space indexed by the label so that user can access it.
|
|
1603
|
-
aChecker.diffResults[label] = differences;
|
|
1604
|
-
|
|
1605
|
-
return 1;
|
|
1606
|
-
}
|
|
1607
|
-
}
|
|
1608
|
-
} else {
|
|
1609
|
-
// In the case that there was no baseline data found compare the results based on
|
|
1610
|
-
// the failLevels array, which was defined by the user.
|
|
1611
|
-
let returnCode = aChecker.compareBasedOnFailLevels(actualResults);
|
|
1612
|
-
|
|
1613
|
-
// In the case there are no violations that match the fail on then return as success
|
|
1614
|
-
if (returnCode === 0) {
|
|
1615
|
-
return returnCode;
|
|
1616
|
-
} else {
|
|
1617
|
-
// In the case there are some violation that match in the fail on then return 2
|
|
1618
|
-
// to identify that there was a failure, and we used a 2nd method for compare.
|
|
1619
|
-
return 2;
|
|
1620
|
-
}
|
|
1621
|
-
}
|
|
1622
|
-
};
|
|
1623
|
-
|
|
1624
|
-
/**
|
|
1625
|
-
* This function is responsible for checking if any of the issues reported have any level that falls
|
|
1626
|
-
* into the failsLevel array.
|
|
1627
|
-
*
|
|
1628
|
-
* @param {Object} results - Provide the scan results, object which would be in the
|
|
1629
|
-
* the same format as outlined in the return of aChecker.buildReport function.
|
|
1630
|
-
*
|
|
1631
|
-
* @return {int} - return 1 in the case a single issue was found which is in the failsLevel array.
|
|
1632
|
-
* return -1 in the case that there is an exception that occured in the results object which came from the scan engine.
|
|
1633
|
-
*
|
|
1634
|
-
* PRIVATE METHOD
|
|
1635
|
-
*
|
|
1636
|
-
* @memberOf this
|
|
1637
|
-
*/
|
|
1638
|
-
aChecker.compareBasedOnFailLevels = function (report) {
|
|
1639
|
-
|
|
1640
|
-
// In the case that the details object contains Error object, this means that the scan engine through an
|
|
1641
|
-
// exception, therefore we should not compare results just fail instead.
|
|
1642
|
-
if (report.details instanceof Error) {
|
|
1643
|
-
return -1;
|
|
1644
|
-
}
|
|
1645
|
-
|
|
1646
|
-
// Variable Decleration
|
|
1647
|
-
let failLevels = aChecker.Config.failLevels;
|
|
1648
|
-
|
|
1649
|
-
// Loop over all the issues to check for any level that is in failLevels
|
|
1650
|
-
// console.log(report);
|
|
1651
|
-
for (const issue of report.results) {
|
|
1652
|
-
// In the case current level is in the failsLevel array them fail, with out checking further
|
|
1653
|
-
// currently we are not saving exactly which results failed, as all the issues are going to be saved to
|
|
1654
|
-
// results file.
|
|
1655
|
-
if (failLevels.indexOf(issue.level) > -1) {
|
|
1656
|
-
// return 1 as there was a fialure
|
|
1657
|
-
return 1;
|
|
1658
|
-
}
|
|
1659
|
-
}
|
|
1660
|
-
|
|
1661
|
-
// return 0 as there were no levels that fall into the failLevels
|
|
1662
|
-
return 0;
|
|
1663
|
-
};
|
|
1664
|
-
|
|
1665
|
-
/**
|
|
1666
|
-
* This function is responsible for comparing actual with expected and returning all the differences as an array.
|
|
1667
|
-
*
|
|
1668
|
-
* @param {Object} actual - Provide the actual object to be used for compare
|
|
1669
|
-
* @param {Object} expected - Provide the expected object to be used for compare
|
|
1670
|
-
* @param {boolean} clean - Provide a boolean if both the actual and expected objects need to be cleaned
|
|
1671
|
-
* cleaning refers to converting the objects to match with a basic compliance
|
|
1672
|
-
* compare of xpath and ruleId.
|
|
1673
|
-
*
|
|
1674
|
-
* @return {Object} differences - return an array of diff objects that were found, following is the format of the object:
|
|
1675
|
-
* [
|
|
1676
|
-
* {
|
|
1677
|
-
* "kind": "E",
|
|
1678
|
-
* "path": [
|
|
1679
|
-
* "reports",
|
|
1680
|
-
* 0,
|
|
1681
|
-
* "issues",
|
|
1682
|
-
* 10,
|
|
1683
|
-
* "xpath"
|
|
1684
|
-
* ],
|
|
1685
|
-
* "lhs": "/html[1]/body[1]/div[2]/table[5]",
|
|
1686
|
-
* "rhs": "/html[1]/body[1]/div[2]/table[5]d",
|
|
1687
|
-
* },
|
|
1688
|
-
* {
|
|
1689
|
-
* "kind": "E",
|
|
1690
|
-
* "path": [
|
|
1691
|
-
* "label"
|
|
1692
|
-
* ],
|
|
1693
|
-
* "lhs": "Table-layoutMultiple",
|
|
1694
|
-
* "rhs": "dependencies/tools-rules-html/v2/a11y/test/g471/Table-layoutMultiple.html",
|
|
1695
|
-
* }
|
|
1696
|
-
* ]
|
|
1697
|
-
*
|
|
1698
|
-
* PUBLIC API
|
|
1699
|
-
*
|
|
1700
|
-
* @memberOf this
|
|
1701
|
-
*/
|
|
1702
|
-
aChecker.diffResultsWithExpected = function (actual, expected, clean) {
|
|
1703
|
-
|
|
1704
|
-
// In the case clean is set to true then run the cleanComplianceObjectBeforeCompare function on
|
|
1705
|
-
// both the actual and expected objects passed in. This is to make sure that the objcet follow a
|
|
1706
|
-
// simalar structure before compareing the objects.
|
|
1707
|
-
if (clean) {
|
|
1708
|
-
// Clean actual and expected objects
|
|
1709
|
-
actual = aChecker.cleanComplianceObjectBeforeCompare(actual);
|
|
1710
|
-
expected = aChecker.cleanComplianceObjectBeforeCompare(expected);
|
|
1711
|
-
}
|
|
1712
|
-
|
|
1713
|
-
// Run Deep diff function to compare the actual and expected values.
|
|
1714
|
-
let differences = DeepDiff.diff(actual, expected);
|
|
1715
|
-
|
|
1716
|
-
// Return the results of the diff, which will include the differences between the objects
|
|
1717
|
-
return differences;
|
|
1718
|
-
};
|
|
1719
|
-
|
|
1720
|
-
/**
|
|
1721
|
-
* This function is responsible for cleaning up the compliance baseline or actual results, based on
|
|
1722
|
-
* a pre-defined set of criterias, such as the following:
|
|
1723
|
-
* 1. No need to compare summary object
|
|
1724
|
-
* 2. Only need to compare the ruleId and xpath in for each of the issues
|
|
1725
|
-
*
|
|
1726
|
-
* @param {Object} objectToClean - Provide either an baseline or actual results object which would be in the
|
|
1727
|
-
* the same format as outlined in the return of aChecker.buildReport function.
|
|
1728
|
-
*
|
|
1729
|
-
* @return {Object} objectToClean - return an object that was cleaned to only contain the information that is
|
|
1730
|
-
* needed for compare. Following is a sample of how the cleaned object will look like:
|
|
1731
|
-
* {
|
|
1732
|
-
* "label": "unitTestContent",
|
|
1733
|
-
* "reports": [
|
|
1734
|
-
* {
|
|
1735
|
-
* "frameIdx": "0",
|
|
1736
|
-
* "frameTitle": "Frame 0",
|
|
1737
|
-
* "issues": [
|
|
1738
|
-
* {
|
|
1739
|
-
* "ruleId": "1",
|
|
1740
|
-
* "xpath": "/html[1]/head[1]/style[1]"
|
|
1741
|
-
* }
|
|
1742
|
-
* ....
|
|
1743
|
-
* ]
|
|
1744
|
-
* },
|
|
1745
|
-
* {
|
|
1746
|
-
* "frameIdx": "1",
|
|
1747
|
-
* "frameTitle": "Frame 1",
|
|
1748
|
-
* "issues": [
|
|
1749
|
-
* {
|
|
1750
|
-
* "ruleId": "471",
|
|
1751
|
-
* "xpath": "/html[1]/body[1]/div[2]/table[3]"
|
|
1752
|
-
* }
|
|
1753
|
-
* ....
|
|
1754
|
-
* ]
|
|
1755
|
-
* }
|
|
1756
|
-
* ]
|
|
1757
|
-
* }
|
|
1758
|
-
*
|
|
1759
|
-
* PRIVATE METHOD
|
|
1760
|
-
*
|
|
1761
|
-
* @memberOf this
|
|
1762
|
-
*/
|
|
1763
|
-
aChecker.cleanComplianceObjectBeforeCompare = function (objectToClean) {
|
|
1764
|
-
// Clone the object so that we do not reference the original or else it causes the original
|
|
1765
|
-
// results object or baseline object to get updated, which we do not want as users are allowed
|
|
1766
|
-
// access to the raw results object and baseline object.
|
|
1767
|
-
// Convert the object into string and then parse it as a JSON object which will lose its reference
|
|
1768
|
-
objectToClean = JSON.parse(JSON.stringify(objectToClean));
|
|
1769
|
-
|
|
1770
|
-
// Remove the summary object, scanID, toolID, issueMessage
|
|
1771
|
-
delete objectToClean.summary;
|
|
1772
|
-
delete objectToClean.nls;
|
|
1773
|
-
delete objectToClean.scanID;
|
|
1774
|
-
delete objectToClean.toolID;
|
|
1775
|
-
delete objectToClean.issueMessages;
|
|
1776
|
-
delete objectToClean.numExecuted;
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
// Loop over all the issues and remove the keys that are not needed for the compare
|
|
1780
|
-
// Only leave the ruleId and xpath keys for compare.
|
|
1781
|
-
for (let idx = 0; idx < objectToClean.results.length; ++idx) {
|
|
1782
|
-
const issue = objectToClean.results[idx];
|
|
1783
|
-
if (issue.level === "pass") {
|
|
1784
|
-
objectToClean.results.splice(idx--, 1);
|
|
1785
|
-
} else {
|
|
1786
|
-
issue.xpath = issue.path.dom;
|
|
1787
|
-
// Loop over all the keys in a single issue object and remove all the
|
|
1788
|
-
// keys that are not needed for compare
|
|
1789
|
-
Object.keys(issue).forEach(function (key) {
|
|
1790
|
-
// Remove all the keys which are not in the baselineIssueList
|
|
1791
|
-
if (aChecker.baselineIssueList.indexOf(key) === -1) {
|
|
1792
|
-
delete issue[key];
|
|
268
|
+
policies = Config.policies;
|
|
269
|
+
curPol = null;
|
|
270
|
+
if (policies) {
|
|
271
|
+
curPol = JSON.parse(JSON.stringify(policies));
|
|
1793
272
|
}
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
* PUBLIC API
|
|
1813
|
-
*
|
|
1814
|
-
* @memberOf this
|
|
1815
|
-
*/
|
|
1816
|
-
aChecker.getBaseline = function (label) {
|
|
1817
|
-
try {
|
|
1818
|
-
return require(path.join(path.join(process.cwd(), aChecker.Config.baselineFolder), label));
|
|
1819
|
-
} catch (e) {
|
|
1820
|
-
return null;
|
|
1821
|
-
}
|
|
1822
|
-
};
|
|
1823
|
-
|
|
1824
|
-
/**
|
|
1825
|
-
* This function is responsible for getting the diff results based on label for a scan that was already performed.
|
|
1826
|
-
*
|
|
1827
|
-
* @param {String} label - Provide a lable for which to get the diff results for.
|
|
1828
|
-
*
|
|
1829
|
-
* @return {Object} - return the diff results object from global space based on label provided, the object will be
|
|
1830
|
-
* in the same format as outlined in the return of aChecker.diffResultsWithExpected function.
|
|
1831
|
-
*
|
|
1832
|
-
* PUBLIC API
|
|
1833
|
-
*
|
|
1834
|
-
* @memberOf this
|
|
1835
|
-
*/
|
|
1836
|
-
aChecker.getDiffResults = function (label) {
|
|
1837
|
-
return aChecker.diffResults && aChecker.diffResults[label];
|
|
1838
|
-
};
|
|
1839
|
-
|
|
1840
|
-
/**
|
|
1841
|
-
* This function is responsible for printing the scan results to console.
|
|
1842
|
-
*
|
|
1843
|
-
* @param {Object} results - Provide the results from the scan.
|
|
1844
|
-
*
|
|
1845
|
-
* @return {String} resultsString - String representation of the results/violations.
|
|
1846
|
-
*
|
|
1847
|
-
* PUBLIC API
|
|
1848
|
-
*
|
|
1849
|
-
* @memberOf this
|
|
1850
|
-
*/
|
|
1851
|
-
aChecker.stringifyResults = function (report) {
|
|
1852
|
-
// console.log(report);
|
|
1853
|
-
// Variable Decleration
|
|
1854
|
-
let resultsString = `Scan: ${report.label}\n`;
|
|
1855
|
-
|
|
1856
|
-
// Loop over the reports and build the string version of the the issues within each report
|
|
1857
|
-
report.results && report.results.forEach(function (issue) {
|
|
1858
|
-
if (aChecker.Config.reportLevels.includes(issue.level)) {
|
|
1859
|
-
// Build string of the issues with only level, messageCode, xpath and snippet.
|
|
1860
|
-
resultsString += "- Message: " + issue.message +
|
|
1861
|
-
"\n Level: " + issue.level +
|
|
1862
|
-
"\n XPath: " + issue.path.dom +
|
|
1863
|
-
"\n Snippet: " + issue.snippet +
|
|
1864
|
-
"\n Help: " + aChecker.getHelpURL(issue.ruleId) +
|
|
1865
|
-
"\n";
|
|
273
|
+
if (!ACEngineManager_1.ACEngineManager.isSelenium(parsed)) return [3 /*break*/, 5];
|
|
274
|
+
Config.DEBUG && console.log("getComplianceHelper:Selenium");
|
|
275
|
+
return [4 /*yield*/, getComplianceHelperSelenium(label, parsed, curPol)];
|
|
276
|
+
case 4: return [2 /*return*/, _a.sent()];
|
|
277
|
+
case 5:
|
|
278
|
+
if (!ACEngineManager_1.ACEngineManager.isPuppeteer(parsed)) return [3 /*break*/, 7];
|
|
279
|
+
Config.DEBUG && console.log("getComplianceHelper:Puppeteer");
|
|
280
|
+
return [4 /*yield*/, getComplianceHelperPuppeteer(label, parsed, curPol)];
|
|
281
|
+
case 6: return [2 /*return*/, _a.sent()];
|
|
282
|
+
case 7:
|
|
283
|
+
if (!ACEngineManager_1.ACEngineManager.isPlaywright(parsed)) return [3 /*break*/, 9];
|
|
284
|
+
Config.DEBUG && console.log("getComplianceHelper:Playwright");
|
|
285
|
+
return [4 /*yield*/, getComplianceHelperPuppeteer(label, parsed, curPol)];
|
|
286
|
+
case 8: return [2 /*return*/, _a.sent()];
|
|
287
|
+
case 9:
|
|
288
|
+
Config.DEBUG && console.log("getComplianceHelper:Local");
|
|
289
|
+
return [4 /*yield*/, getComplianceHelperLocal(label, parsed, curPol)];
|
|
290
|
+
case 10: return [2 /*return*/, _a.sent()];
|
|
1866
291
|
}
|
|
1867
292
|
});
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
return new ace.Checker().engine.getHelp(ruleId);
|
|
1885
|
-
};
|
|
1886
|
-
|
|
1887
|
-
aChecker.getRulesets = function () {
|
|
1888
|
-
return new ace.Checker().rulesets;
|
|
1889
|
-
};
|
|
1890
|
-
|
|
1891
|
-
aChecker.ruleIdToLegacyId = {
|
|
1892
|
-
"RPT_List_Misuse": "3",
|
|
1893
|
-
"RPT_Marquee_Trigger": "5",
|
|
1894
|
-
"RPT_Headers_FewWords": "7",
|
|
1895
|
-
"WCAG20_Input_ExplicitLabelImage": "10",
|
|
1896
|
-
"RPT_Img_UsemapValid": "11",
|
|
1897
|
-
"WCAG20_Object_HasText": "20",
|
|
1898
|
-
"WCAG20_Applet_HasAlt": "21",
|
|
1899
|
-
"RPT_Media_AudioTrigger": "24",
|
|
1900
|
-
"RPT_Blockquote_HasCite": "25",
|
|
1901
|
-
"RPT_Meta_Refresh": "33",
|
|
1902
|
-
"WCAG20_Frame_HasTitle": "39",
|
|
1903
|
-
"WCAG20_Input_ExplicitLabel": "41",
|
|
1904
|
-
"RPT_Media_AltBrief": "99",
|
|
1905
|
-
"WCAG20_A_TargetAndText": "112",
|
|
1906
|
-
"WCAG20_Area_HasAlt": "240",
|
|
1907
|
-
"RPT_Media_ImgColorUsage": "245",
|
|
1908
|
-
"WCAG20_Meta_RedirectZero": "254",
|
|
1909
|
-
"RPT_Elem_Deprecated": "256",
|
|
1910
|
-
"RPT_Blockquote_WrapsTextQuote": "263",
|
|
1911
|
-
"RPT_Elem_EventMouseAndKey": "269",
|
|
1912
|
-
"WCAG20_Doc_HasTitle": "273",
|
|
1913
|
-
"RPT_Block_ShouldBeHeading": "322",
|
|
1914
|
-
"WCAG20_Form_HasSubmit": "324",
|
|
1915
|
-
"RPT_Elem_UniqueId": "377",
|
|
1916
|
-
"RPT_Font_ColorInForm": "394",
|
|
1917
|
-
"RPT_Label_UniqueFor": "398",
|
|
1918
|
-
"RPT_Img_AltCommonMisuse": "453",
|
|
1919
|
-
"RPT_Img_LongDescription2": "454",
|
|
1920
|
-
"WCAG20_Img_HasAlt": "455",
|
|
1921
|
-
"RPT_Style_BackgroundImage": "456",
|
|
1922
|
-
"RPT_Pre_ASCIIArt": "458",
|
|
1923
|
-
"RPT_Media_VideoReferenceTrigger": "511",
|
|
1924
|
-
"RPT_Media_AudioVideoAltFilename": "460",
|
|
1925
|
-
"RPT_Style_ColorSemantics1": "466",
|
|
1926
|
-
"WCAG20_Select_HasOptGroup": "467",
|
|
1927
|
-
"RPT_List_UseMarkup": "468",
|
|
1928
|
-
"RPT_Script_OnclickHTML1": "470",
|
|
1929
|
-
"WCAG20_Table_Structure": "471",
|
|
1930
|
-
"WCAG20_Img_AltTriggerNonDecorative": "473",
|
|
1931
|
-
"WCAG20_Blink_AlwaysTrigger": "478",
|
|
1932
|
-
"RPT_Blink_CSSTrigger1": "479",
|
|
1933
|
-
"RPT_Html_SkipNav": "481",
|
|
1934
|
-
"RPT_Title_Valid": "484",
|
|
1935
|
-
"RPT_Header_HasContent": "488",
|
|
1936
|
-
"WCAG20_Html_HasLang": "490",
|
|
1937
|
-
"WCAG20_Form_TargetAndText": "491",
|
|
1938
|
-
"WCAG20_A_HasText": "495",
|
|
1939
|
-
"WCAG20_Fieldset_HasLegend": "497",
|
|
1940
|
-
"RPT_Media_VideoObjectTrigger": "501",
|
|
1941
|
-
"RPT_Text_SensoryReference": "502",
|
|
1942
|
-
"RPT_Embed_AutoStart": "503",
|
|
1943
|
-
"RPT_Style_HinderFocus1": "506",
|
|
1944
|
-
"WCAG20_Elem_Lang_Valid": "507",
|
|
1945
|
-
"WCAG20_Img_LinkTextNotRedundant": "1000",
|
|
1946
|
-
"RPT_Style_ExternalStyleSheet": "1073",
|
|
1947
|
-
"RPT_Header_Trigger": "1002",
|
|
1948
|
-
"RPT_Script_OnclickHTML2": "1007",
|
|
1949
|
-
"WCAG20_Table_CapSummRedundant": "1011",
|
|
1950
|
-
"WCAG20_Input_LabelBefore": "1017",
|
|
1951
|
-
"WCAG20_Input_LabelAfter": "1018",
|
|
1952
|
-
"WCAG20_Embed_HasNoEmbed": "1020",
|
|
1953
|
-
"WCAG20_Table_Scope_Valid": "1025",
|
|
1954
|
-
"WCAG20_Img_TitleEmptyWhenAltNull": "1027",
|
|
1955
|
-
"WCAG20_Input_InFieldSet": "1028",
|
|
1956
|
-
"WCAG20_Input_RadioChkInFieldSet": "1029",
|
|
1957
|
-
"WCAG20_Select_NoChangeAction": "1035",
|
|
1958
|
-
"WCAG20_Input_HasOnchange": "1050",
|
|
1959
|
-
"RPT_Embed_HasAlt": "1051",
|
|
1960
|
-
"Valerie_Noembed_HasContent": "1052",
|
|
1961
|
-
"Valerie_Caption_HasContent": "1053",
|
|
1962
|
-
"Valerie_Caption_InTable": "1054",
|
|
1963
|
-
"Valerie_Label_HasContent": "1055",
|
|
1964
|
-
"Valerie_Elem_DirValid": "1056",
|
|
1965
|
-
"Valerie_Frame_SrcHtml": "1057",
|
|
1966
|
-
"Valerie_Table_DataCellRelationships": "1059",
|
|
1967
|
-
"RPT_Table_LayoutTrigger": "1060",
|
|
1968
|
-
"RPT_Table_DataHeadingsAria": "1061",
|
|
1969
|
-
"WCAG20_Label_RefValid": "1062",
|
|
1970
|
-
"WCAG20_Elem_UniqueAccessKey": "1063",
|
|
1971
|
-
"WCAG20_Script_FocusBlurs": "1064",
|
|
1972
|
-
"HAAC_Img_UsemapAlt": "1067",
|
|
1973
|
-
"WCAG20_Text_Emoticons": "1068",
|
|
1974
|
-
"WCAG20_Style_BeforeAfter": "1069",
|
|
1975
|
-
"WCAG20_Text_LetterSpacing": "1070",
|
|
1976
|
-
"Rpt_Aria_ValidRole": "1074",
|
|
1977
|
-
"Rpt_Aria_ValidPropertyValue": "1076",
|
|
1978
|
-
"Rpt_Aria_ValidIdRef": "1077",
|
|
1979
|
-
"Rpt_Aria_RequiredProperties": "1079",
|
|
1980
|
-
"Rpt_Aria_EmptyPropertyValue": "1082",
|
|
1981
|
-
"Rpt_Aria_ValidProperty": "1083",
|
|
1982
|
-
"Rpt_Aria_InvalidTabindexForActivedescendant": "1084",
|
|
1983
|
-
"Rpt_Aria_MissingFocusableChild": "1086",
|
|
1984
|
-
"Rpt_Aria_MissingKeyboardHandler": "1087",
|
|
1985
|
-
"WCAG20_Img_PresentationImgHasNonNullAlt": "1090",
|
|
1986
|
-
"Rpt_Aria_MultipleSearchLandmarks": "1097",
|
|
1987
|
-
"Rpt_Aria_MultipleApplicationLandmarks": "1099",
|
|
1988
|
-
"Rpt_Aria_ApplicationLandmarkLabel": "1100",
|
|
1989
|
-
"Rpt_Aria_MultipleDocumentRoles": "1101",
|
|
1990
|
-
"WCAG20_Label_TargetInvisible": "1112",
|
|
1991
|
-
"HAAC_Video_HasNoTrack": "1117",
|
|
1992
|
-
"HAAC_Audio_Video_Trigger": "1119",
|
|
1993
|
-
"HAAC_Input_HasRequired": "1124",
|
|
1994
|
-
"HAAC_Aria_ImgAlt": "1128",
|
|
1995
|
-
"HAAC_BackgroundImg_HasTextOrTitle": "1132",
|
|
1996
|
-
"HAAC_Accesskey_NeedLabel": "1140",
|
|
1997
|
-
"HAAC_Aria_Or_HTML5_Attr": "1141",
|
|
1998
|
-
"HAAC_Canvas": "1143",
|
|
1999
|
-
"HAAC_Figure_label": "1144",
|
|
2000
|
-
"HAAC_Input_Placeholder": "1145",
|
|
2001
|
-
"HAAC_Aria_Native_Host_Sematics": "1146",
|
|
2002
|
-
"RPT_Form_ChangeEmpty": "1147",
|
|
2003
|
-
"IBMA_Color_Contrast_WCAG2AA": "1148",
|
|
2004
|
-
"IBMA_Color_Contrast_WCAG2AA_PV": "1149",
|
|
2005
|
-
"WCAG20_Body_FirstASkips_Native_Host_Sematics": "1150",
|
|
2006
|
-
"WCAG20_Body_FirstAContainsSkipText_Native_Host_Sematics": "1151",
|
|
2007
|
-
"Rpt_Aria_RequiredChildren_Native_Host_Sematics": "1152",
|
|
2008
|
-
"Rpt_Aria_RequiredParent_Native_Host_Sematics": "1153",
|
|
2009
|
-
"Rpt_Aria_EventHandlerMissingRole_Native_Host_Sematics": "1154",
|
|
2010
|
-
"Rpt_Aria_WidgetLabels_Implicit": "1156",
|
|
2011
|
-
"Rpt_Aria_OrphanedContent_Native_Host_Sematics": "1157",
|
|
2012
|
-
"Rpt_Aria_RegionLabel_Implicit": "1158",
|
|
2013
|
-
"Rpt_Aria_MultipleMainsVisibleLabel_Implicit": "1159",
|
|
2014
|
-
"Rpt_Aria_MultipleBannerLandmarks_Implicit": "1160",
|
|
2015
|
-
"Rpt_Aria_MultipleComplementaryLandmarks_Implicit": "1161",
|
|
2016
|
-
"Rpt_Aria_MultipleContentinfoLandmarks_Implicit": "1162",
|
|
2017
|
-
"Rpt_Aria_MultipleFormLandmarks_Implicit": "1163",
|
|
2018
|
-
"Rpt_Aria_MultipleNavigationLandmarks_Implicit": "1164",
|
|
2019
|
-
"Rpt_Aria_ComplementaryLandmarkLabel_Implicit": "1165",
|
|
2020
|
-
"Rpt_Aria_MultipleArticleRoles_Implicit": "1166",
|
|
2021
|
-
"Rpt_Aria_ArticleRoleLabel_Implicit": "1167",
|
|
2022
|
-
"Rpt_Aria_MultipleGroupRoles_Implicit": "1168",
|
|
2023
|
-
"Rpt_Aria_GroupRoleLabel_Implicit": "1169",
|
|
2024
|
-
"Rpt_Aria_MultipleContentinfoInSiblingSet_Implicit": "1170",
|
|
2025
|
-
"Rpt_Aria_OneBannerInSiblingSet_Implicit": "1172",
|
|
2026
|
-
"Rpt_Aria_ContentinfoWithNoMain_Implicit": "1173",
|
|
2027
|
-
"Rpt_Aria_ComplementaryRequiredLabel_Implicit": "1174",
|
|
2028
|
-
"Rpt_Aria_MultipleRegionsUniqueLabel_Implicit": "1176",
|
|
2029
|
-
"IBMA_Focus_Tabbable": "1177",
|
|
2030
|
-
"IBMA_Focus_MultiTab": "1178",
|
|
2031
|
-
"WCAG20_Table_SummaryAria3": "1179",
|
|
2032
|
-
"RPT_Style_Trigger2": "1180",
|
|
2033
|
-
"Rpt_Aria_MultipleMainsRequireLabel_Implicit_2": "1182",
|
|
2034
|
-
"HAAC_Media_DocumentTrigger2": "1183",
|
|
2035
|
-
"HAAC_Aria_ErrorMessage": "1184",
|
|
2036
|
-
"HAAC_List_Group_ListItem": "1185",
|
|
2037
|
-
"HAAC_ActiveDescendantCheck": "1186",
|
|
2038
|
-
"HAAC_Application_Role_Text": "1187",
|
|
2039
|
-
"Rpt_Aria_MultipleToolbarUniqueLabel": "1188",
|
|
2040
|
-
"HAAC_Combobox_ARIA_11_Guideline": "1193",
|
|
2041
|
-
"HAAC_Combobox_Must_Have_Text_Input": "1194",
|
|
2042
|
-
"HAAC_Combobox_DOM_Focus": "1195",
|
|
2043
|
-
"HAAC_Combobox_Autocomplete": "1196",
|
|
2044
|
-
"HAAC_Combobox_Autocomplete_Invalid": "1197",
|
|
2045
|
-
"HAAC_Combobox_Expanded": "1198",
|
|
2046
|
-
"HAAC_Combobox_Popup": "1199",
|
|
2047
|
-
"WCAG21_Style_Viewport": "1200",
|
|
2048
|
-
"WCAG21_Label_Accessible": "1202",
|
|
2049
|
-
"WCAG21_Input_Autocomplete": "1203",
|
|
2050
|
-
"WCAG20_Input_VisibleLabel": "1204"
|
|
2051
|
-
}
|
|
2052
|
-
|
|
2053
|
-
aChecker.ignoreExtraBaselineViolations = function (actualReport, baselineReport) {
|
|
2054
|
-
let result = null;
|
|
2055
|
-
let existingRuleIDs = [];
|
|
2056
|
-
// Using for loop to make is sync code
|
|
2057
|
-
let ignoredCount = 0;
|
|
2058
|
-
let changedCounts = actualReport.summary.counts;
|
|
2059
|
-
|
|
2060
|
-
let currentActualReport = actualReport.results;
|
|
2061
|
-
const currentBaselineReport = baselineReport;
|
|
2062
|
-
// a report exists in the baseline for the iframe
|
|
2063
|
-
if (currentBaselineReport && currentBaselineReport.length === 1) {
|
|
2064
|
-
let legacyBaseline = !!currentBaselineReport[0].issues;
|
|
2065
|
-
for (const issue of currentActualReport) {
|
|
2066
|
-
let currentRuleID = issue.ruleId;
|
|
2067
|
-
let currentLevel = issue.level;
|
|
2068
|
-
let currentXPATH = issue.path.dom;
|
|
2069
|
-
//check if the issue exists in baseline already
|
|
2070
|
-
let result =
|
|
2071
|
-
legacyBaseline && currentBaselineReport[0].issues.filter(issue => issue.ruleId in aChecker.ruleIdToLegacyId && aChecker.ruleIdToLegacyId[issue.ruleId] === currentRuleID && issue.level === currentLevel && issue.xpath === currentXPATH)
|
|
2072
|
-
|| !legacyBaseline && currentBaselineReport.results.filter(issue => issue.ruleId === currentRuleID && issue.level === currentLevel && issue.dom.path === currentXPATH);
|
|
2073
|
-
if (result && result.length !== 0) {
|
|
2074
|
-
//violation exists in baseline, add ignore:true
|
|
2075
|
-
issue.ignored = true;
|
|
2076
|
-
ignoredCount++;
|
|
2077
|
-
if (issue.level === "violation") {
|
|
2078
|
-
changedCounts.violation--;
|
|
2079
|
-
}
|
|
2080
|
-
if (issue.level === "potentialviolation") {
|
|
2081
|
-
changedCounts.potentialviolation--;
|
|
2082
|
-
}
|
|
2083
|
-
if (issue.level === "recommendation") {
|
|
2084
|
-
changedCounts.recommendation--;
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
exports.getComplianceHelper = getComplianceHelper;
|
|
296
|
+
function getComplianceHelperSelenium(label, parsed, curPol) {
|
|
297
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
298
|
+
var startScan, browser, scriptStr, manage, report, getPolicies, valPolicies, finalReport, url, origReport, counts, image, screenshotResult, err_1;
|
|
299
|
+
return __generator(this, function (_a) {
|
|
300
|
+
switch (_a.label) {
|
|
301
|
+
case 0:
|
|
302
|
+
_a.trys.push([0, 7, , 8]);
|
|
303
|
+
startScan = Date.now();
|
|
304
|
+
browser = parsed;
|
|
305
|
+
scriptStr = "let cb = arguments[arguments.length - 1];\ntry {\nlet policies = " + JSON.stringify(Config.policies) + ";\n\nlet checker = new window.ace.Checker();\nsetTimeout(function() {\n checker.check(document, policies).then(function(report) {\n for (const result of report.results) {\n delete result.node;\n }\n cb(report);\n })\n},0)\n} catch (e) {\ncb(e);\n}";
|
|
306
|
+
manage = browser.manage();
|
|
307
|
+
if (manage.timeouts) {
|
|
308
|
+
manage.timeouts().setScriptTimeout(60000);
|
|
2085
309
|
}
|
|
2086
|
-
if (
|
|
2087
|
-
|
|
310
|
+
else if (manage.setTimeouts) {
|
|
311
|
+
manage.setTimeouts({
|
|
312
|
+
"script": 60000
|
|
313
|
+
});
|
|
2088
314
|
}
|
|
2089
|
-
|
|
2090
|
-
|
|
315
|
+
return [4 /*yield*/, browser.executeAsyncScript(scriptStr)];
|
|
316
|
+
case 1:
|
|
317
|
+
report = _a.sent();
|
|
318
|
+
report = ACReportManager_1.ACReportManager.setLevels(report);
|
|
319
|
+
getPolicies = "return new window.ace.Checker().rulesetIds;";
|
|
320
|
+
if (!(curPol != null && !checkPolicy)) return [3 /*break*/, 3];
|
|
321
|
+
checkPolicy = true;
|
|
322
|
+
return [4 /*yield*/, browser.executeScript(getPolicies)];
|
|
323
|
+
case 2:
|
|
324
|
+
valPolicies = _a.sent();
|
|
325
|
+
areValidPolicy(valPolicies, curPol);
|
|
326
|
+
_a.label = 3;
|
|
327
|
+
case 3:
|
|
328
|
+
finalReport = void 0;
|
|
329
|
+
if (!report.results) return [3 /*break*/, 6];
|
|
330
|
+
return [4 /*yield*/, browser.getCurrentUrl()];
|
|
331
|
+
case 4:
|
|
332
|
+
url = _a.sent();
|
|
333
|
+
origReport = JSON.parse(JSON.stringify(report));
|
|
334
|
+
origReport = ACReportManager_1.ACReportManager.buildReport(origReport, {}, url, label, startScan);
|
|
335
|
+
// Filter the violations based on the reportLevels
|
|
336
|
+
report = ACReportManager_1.ACReportManager.filterViolations(report);
|
|
337
|
+
counts = ACReportManager_1.ACReportManager.getCounts(report);
|
|
338
|
+
// Add the violation count to global summary object
|
|
339
|
+
ACReportManager_1.ACReportManager.addToSummaryCount(counts);
|
|
340
|
+
// Build the report object for this scan, to follow a specific format. Refer to the
|
|
341
|
+
// function prolog for more information on the object creation.
|
|
342
|
+
finalReport = ACReportManager_1.ACReportManager.buildReport(report, counts, url, label, startScan);
|
|
343
|
+
// Add the scan results to global karma result object which can be accessed when users testcase
|
|
344
|
+
// finishes, user can also access it to alter it for any reason.
|
|
345
|
+
ACReportManager_1.ACReportManager.addResultsToGlobal(finalReport);
|
|
346
|
+
// Need to call a karma API to send the results of a single scan to the accessibility-checker reporter so that they can be
|
|
347
|
+
// saved to a file by the server side reporter.
|
|
348
|
+
ACReportManager_1.ACReportManager.sendResultsToReporter(origReport, finalReport, "Selenium");
|
|
349
|
+
if (!(Config.captureScreenshots && browser.takeScreenshot)) return [3 /*break*/, 6];
|
|
350
|
+
return [4 /*yield*/, browser.takeScreenshot()];
|
|
351
|
+
case 5:
|
|
352
|
+
image = _a.sent();
|
|
353
|
+
screenshotResult = {
|
|
354
|
+
image: image,
|
|
355
|
+
label: label,
|
|
356
|
+
scanID: finalReport.scanID
|
|
357
|
+
};
|
|
358
|
+
ACReportManager_1.ACReportManager.sendScreenShotToReporter(screenshotResult);
|
|
359
|
+
_a.label = 6;
|
|
360
|
+
case 6: return [2 /*return*/, {
|
|
361
|
+
"report": finalReport,
|
|
362
|
+
"webdriver": parsed
|
|
363
|
+
}];
|
|
364
|
+
case 7:
|
|
365
|
+
err_1 = _a.sent();
|
|
366
|
+
console.error(err_1);
|
|
367
|
+
return [2 /*return*/, Promise.reject(err_1)];
|
|
368
|
+
case 8:
|
|
369
|
+
;
|
|
370
|
+
return [2 /*return*/];
|
|
371
|
+
}
|
|
372
|
+
});
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
function getComplianceHelperPuppeteer(label, parsed, curPol) {
|
|
376
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
377
|
+
var startScan, page, report, valPolicies, finalReport, url, origReport, counts, image, screenshotResult, err_2;
|
|
378
|
+
return __generator(this, function (_a) {
|
|
379
|
+
switch (_a.label) {
|
|
380
|
+
case 0:
|
|
381
|
+
_a.trys.push([0, 7, , 8]);
|
|
382
|
+
startScan = Date.now();
|
|
383
|
+
page = parsed;
|
|
384
|
+
return [4 /*yield*/, page.evaluate(function (policies) {
|
|
385
|
+
var checker = new window.ace.Checker();
|
|
386
|
+
return new Promise(function (resolve, reject) {
|
|
387
|
+
setTimeout(function () {
|
|
388
|
+
checker.check(document, policies).then(function (report) {
|
|
389
|
+
for (var _i = 0, _a = report.results; _i < _a.length; _i++) {
|
|
390
|
+
var result = _a[_i];
|
|
391
|
+
delete result.node;
|
|
392
|
+
}
|
|
393
|
+
resolve(report);
|
|
394
|
+
});
|
|
395
|
+
}, 0);
|
|
396
|
+
});
|
|
397
|
+
}, Config.policies)];
|
|
398
|
+
case 1:
|
|
399
|
+
report = _a.sent();
|
|
400
|
+
report = ACReportManager_1.ACReportManager.setLevels(report);
|
|
401
|
+
if (!(curPol != null && !checkPolicy)) return [3 /*break*/, 3];
|
|
402
|
+
return [4 /*yield*/, page.evaluate("new window.ace.Checker().rulesetIds")];
|
|
403
|
+
case 2:
|
|
404
|
+
valPolicies = _a.sent();
|
|
405
|
+
checkPolicy = true;
|
|
406
|
+
areValidPolicy(valPolicies, curPol);
|
|
407
|
+
_a.label = 3;
|
|
408
|
+
case 3:
|
|
409
|
+
finalReport = void 0;
|
|
410
|
+
if (!report.results) return [3 /*break*/, 6];
|
|
411
|
+
return [4 /*yield*/, page.evaluate("document.location.href")];
|
|
412
|
+
case 4:
|
|
413
|
+
url = _a.sent();
|
|
414
|
+
origReport = JSON.parse(JSON.stringify(report));
|
|
415
|
+
origReport = ACReportManager_1.ACReportManager.buildReport(origReport, {}, url, label, startScan);
|
|
416
|
+
// Filter the violations based on the reporLevels
|
|
417
|
+
report = ACReportManager_1.ACReportManager.filterViolations(report);
|
|
418
|
+
counts = ACReportManager_1.ACReportManager.getCounts(report);
|
|
419
|
+
// Add the violation count to global summary object
|
|
420
|
+
ACReportManager_1.ACReportManager.addToSummaryCount(counts);
|
|
421
|
+
// Build the report object for this scan, to follow a specific format. Refer to the
|
|
422
|
+
// function prolog for more information on the object creation.
|
|
423
|
+
finalReport = ACReportManager_1.ACReportManager.buildReport(report, counts, url, label, startScan);
|
|
424
|
+
// Add the scan results to global karma result object which can be accessed when users testcase
|
|
425
|
+
// finishes, user can also access it to alter it for any reason.
|
|
426
|
+
ACReportManager_1.ACReportManager.addResultsToGlobal(finalReport);
|
|
427
|
+
// Need to call a karma API to send the results of a single scan to the accessibility-checker reporter so that they can be
|
|
428
|
+
// saved to a file by the server side reporter.
|
|
429
|
+
ACReportManager_1.ACReportManager.sendResultsToReporter(origReport, finalReport, "Puppeteer");
|
|
430
|
+
if (!Config.captureScreenshots) return [3 /*break*/, 6];
|
|
431
|
+
return [4 /*yield*/, page.screenshot({
|
|
432
|
+
fullPage: true,
|
|
433
|
+
encoding: "base64"
|
|
434
|
+
})];
|
|
435
|
+
case 5:
|
|
436
|
+
image = _a.sent();
|
|
437
|
+
screenshotResult = {
|
|
438
|
+
image: image,
|
|
439
|
+
label: label,
|
|
440
|
+
scanID: Config.scanID
|
|
441
|
+
};
|
|
442
|
+
ACReportManager_1.ACReportManager.sendScreenShotToReporter(screenshotResult);
|
|
443
|
+
_a.label = 6;
|
|
444
|
+
case 6:
|
|
445
|
+
page.aceBusy = false;
|
|
446
|
+
return [2 /*return*/, {
|
|
447
|
+
"report": finalReport,
|
|
448
|
+
"puppeteer": parsed
|
|
449
|
+
}];
|
|
450
|
+
case 7:
|
|
451
|
+
err_2 = _a.sent();
|
|
452
|
+
console.error(err_2);
|
|
453
|
+
return [2 /*return*/, Promise.reject(err_2)];
|
|
454
|
+
case 8:
|
|
455
|
+
;
|
|
456
|
+
return [2 /*return*/];
|
|
457
|
+
}
|
|
458
|
+
});
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
function getComplianceHelperLocal(label, parsed, curPol) {
|
|
462
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
463
|
+
var startScan, checker, report, valPolicies, finalReport, url, origReport, counts, err_3;
|
|
464
|
+
return __generator(this, function (_a) {
|
|
465
|
+
switch (_a.label) {
|
|
466
|
+
case 0:
|
|
467
|
+
_a.trys.push([0, 2, , 3]);
|
|
468
|
+
startScan = Date.now();
|
|
469
|
+
checker = ACEngineManager_1.ACEngineManager.getChecker();
|
|
470
|
+
return [4 /*yield*/, checker.check(parsed, Config.policies)
|
|
471
|
+
.then(function (report) {
|
|
472
|
+
for (var _i = 0, _a = report.results; _i < _a.length; _i++) {
|
|
473
|
+
var result = _a[_i];
|
|
474
|
+
delete result.node;
|
|
475
|
+
}
|
|
476
|
+
return report;
|
|
477
|
+
})];
|
|
478
|
+
case 1:
|
|
479
|
+
report = _a.sent();
|
|
480
|
+
report = ACReportManager_1.ACReportManager.setLevels(report);
|
|
481
|
+
if (curPol != null && !checkPolicy) {
|
|
482
|
+
valPolicies = checker.rulesetIds;
|
|
483
|
+
checkPolicy = true;
|
|
484
|
+
areValidPolicy(valPolicies, curPol);
|
|
2091
485
|
}
|
|
2092
|
-
|
|
2093
|
-
|
|
486
|
+
finalReport = void 0;
|
|
487
|
+
// If there is something to report...
|
|
488
|
+
if (report.results) {
|
|
489
|
+
url = parsed.location && parsed.location.href;
|
|
490
|
+
origReport = JSON.parse(JSON.stringify(report));
|
|
491
|
+
origReport = ACReportManager_1.ACReportManager.buildReport(origReport, {}, url, label, startScan);
|
|
492
|
+
// Filter the violations based on the reporLevels
|
|
493
|
+
report = ACReportManager_1.ACReportManager.filterViolations(report);
|
|
494
|
+
counts = ACReportManager_1.ACReportManager.getCounts(report);
|
|
495
|
+
// Add the violation count to global summary object
|
|
496
|
+
ACReportManager_1.ACReportManager.addToSummaryCount(counts);
|
|
497
|
+
// Build the report object for this scan, to follow a specific format. Refer to the
|
|
498
|
+
// function prolog for more information on the object creation.
|
|
499
|
+
finalReport = ACReportManager_1.ACReportManager.buildReport(report, counts, URL, label, startScan);
|
|
500
|
+
// Add the scan results to global karma result object which can be accessed when users testcase
|
|
501
|
+
// finishes, user can also access it to alter it for any reason.
|
|
502
|
+
ACReportManager_1.ACReportManager.addResultsToGlobal(finalReport);
|
|
503
|
+
// Need to call a karma API to send the results of a single scan to the accessibility-checker reporter so that they can be
|
|
504
|
+
// saved to a file by the server side reporter.
|
|
505
|
+
ACReportManager_1.ACReportManager.sendResultsToReporter(origReport, finalReport, "Native");
|
|
2094
506
|
}
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
507
|
+
return [2 /*return*/, {
|
|
508
|
+
"report": finalReport
|
|
509
|
+
}];
|
|
510
|
+
case 2:
|
|
511
|
+
err_3 = _a.sent();
|
|
512
|
+
console.error(err_3);
|
|
513
|
+
return [2 /*return*/, Promise.reject(err_3)];
|
|
514
|
+
case 3:
|
|
515
|
+
;
|
|
516
|
+
return [2 /*return*/];
|
|
2099
517
|
}
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
changedCounts.ignored = ignoredCount;
|
|
2105
|
-
actualReport.summary.counts = changedCounts
|
|
2106
|
-
return actualReport;
|
|
2107
|
-
}
|
|
2108
|
-
|
|
2109
|
-
})();
|
|
2110
|
-
module.exports = {
|
|
2111
|
-
getCompliance: aChecker.getCompliance,
|
|
2112
|
-
assertCompliance: aChecker.assertCompliance,
|
|
2113
|
-
getDiffResults: aChecker.getDiffResults,
|
|
2114
|
-
getBaseline: aChecker.getBaseline,
|
|
2115
|
-
diffResultsWithExpected: aChecker.diffResultsWithExpected,
|
|
2116
|
-
stringifyResults: aChecker.stringifyResults,
|
|
2117
|
-
getConfig: aChecker.getConfig,
|
|
2118
|
-
close: aChecker.close,
|
|
2119
|
-
ruleIdToLegacyId: aChecker.ruleIdToLegacyId,
|
|
2120
|
-
cleanComplianceObjectBeforeCompare: aChecker.cleanComplianceObjectBeforeCompare
|
|
2121
|
-
}
|
|
518
|
+
});
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
//# sourceMappingURL=ACHelper.js.map
|