testaro 60.16.2 → 60.18.0
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/package.json +1 -1
- package/procs/testaro.js +3 -118
- package/testaro/allCaps.js +32 -36
- package/testaro/allSlanted.js +16 -21
- package/testaro/distortion.js +20 -22
- package/testaro/focAndOp.js +7 -8
- package/testaro/hover.js +1 -1
- package/testaro/hr.js +32 -0
- package/testaro/imageLink.js +19 -16
- package/testaro/legendLoc.js +18 -23
- package/testaro/linkExt.js +31 -0
- package/testaro/linkOldAtt.js +43 -0
- package/testaro/linkTo.js +37 -0
- package/testaro/linkUl.js +24 -30
- package/testaro/nonTable.js +39 -55
- package/testaro/optRoleSel.js +18 -15
- package/testaro/pseudoP.js +54 -0
- package/testaro/role.js +1 -1
- package/testaro/textSem.js +1 -1
- package/testaro/titledEl.js +34 -0
- package/tests/testaro.js +124 -175
- package/data/template.js +0 -39
- package/testaro/hr.json +0 -10
- package/testaro/linkExt.json +0 -10
- package/testaro/linkOldAtt.json +0 -10
- package/testaro/linkTitle.js +0 -46
- package/testaro/linkTo.json +0 -10
- package/testaro/pseudoP.json +0 -10
- package/testaro/titledEl.json +0 -10
package/tests/testaro.js
CHANGED
|
@@ -15,12 +15,8 @@
|
|
|
15
15
|
|
|
16
16
|
// IMPORTS
|
|
17
17
|
|
|
18
|
-
// Module to perform common operations.
|
|
19
|
-
const {init, getRuleResult} = require('../procs/testaro');
|
|
20
18
|
// Function to launch a browser.
|
|
21
19
|
const {launch} = require('../run');
|
|
22
|
-
// Module to handle files.
|
|
23
|
-
const fs = require('fs/promises');
|
|
24
20
|
|
|
25
21
|
// CONSTANTS
|
|
26
22
|
|
|
@@ -44,7 +40,7 @@ const allRules = [
|
|
|
44
40
|
id: 'allCaps',
|
|
45
41
|
what: 'leaf elements with entirely upper-case text longer than 7 characters',
|
|
46
42
|
launchRole: 'sharer',
|
|
47
|
-
timeOut:
|
|
43
|
+
timeOut: 5,
|
|
48
44
|
defaultOn: true
|
|
49
45
|
},
|
|
50
46
|
{
|
|
@@ -114,14 +110,14 @@ const allRules = [
|
|
|
114
110
|
id: 'distortion',
|
|
115
111
|
what: 'distorted text',
|
|
116
112
|
launchRole: 'sharer',
|
|
117
|
-
timeOut:
|
|
113
|
+
timeOut: 5,
|
|
118
114
|
defaultOn: true
|
|
119
115
|
},
|
|
120
116
|
{
|
|
121
117
|
id: 'docType',
|
|
122
118
|
what: 'document without a doctype property',
|
|
123
119
|
launchRole: 'sharer',
|
|
124
|
-
timeOut:
|
|
120
|
+
timeOut: 5,
|
|
125
121
|
defaultOn: true
|
|
126
122
|
},
|
|
127
123
|
{
|
|
@@ -170,7 +166,7 @@ const allRules = [
|
|
|
170
166
|
id: 'labClash',
|
|
171
167
|
what: 'labeling inconsistencies',
|
|
172
168
|
launchRole: 'sharer',
|
|
173
|
-
timeOut:
|
|
169
|
+
timeOut: 5,
|
|
174
170
|
defaultOn: true
|
|
175
171
|
},
|
|
176
172
|
{
|
|
@@ -184,14 +180,14 @@ const allRules = [
|
|
|
184
180
|
id: 'lineHeight',
|
|
185
181
|
what: 'text with a line height less than 1.5 times its font size',
|
|
186
182
|
launchRole: 'sharer',
|
|
187
|
-
timeOut:
|
|
183
|
+
timeOut: 5,
|
|
188
184
|
defaultOn: true
|
|
189
185
|
},
|
|
190
186
|
{
|
|
191
187
|
id: 'linkAmb',
|
|
192
188
|
what: 'links with identical texts but different destinations',
|
|
193
189
|
launchRole: 'sharer',
|
|
194
|
-
timeOut:
|
|
190
|
+
timeOut: 20,
|
|
195
191
|
defaultOn: true
|
|
196
192
|
},
|
|
197
193
|
{
|
|
@@ -208,13 +204,6 @@ const allRules = [
|
|
|
208
204
|
timeOut: 5,
|
|
209
205
|
defaultOn: true
|
|
210
206
|
},
|
|
211
|
-
{
|
|
212
|
-
id: 'linkTitle',
|
|
213
|
-
what: 'links with title attributes repeating text content',
|
|
214
|
-
launchRole: 'sharer',
|
|
215
|
-
timeOut: 10,
|
|
216
|
-
defaultOn: true
|
|
217
|
-
},
|
|
218
207
|
{
|
|
219
208
|
id: 'linkTo',
|
|
220
209
|
what: 'links without destinations',
|
|
@@ -226,7 +215,7 @@ const allRules = [
|
|
|
226
215
|
id: 'linkUl',
|
|
227
216
|
what: 'missing underlines on inline links',
|
|
228
217
|
launchRole: 'sharer',
|
|
229
|
-
timeOut:
|
|
218
|
+
timeOut: 5,
|
|
230
219
|
defaultOn: true
|
|
231
220
|
},
|
|
232
221
|
{
|
|
@@ -275,7 +264,7 @@ const allRules = [
|
|
|
275
264
|
id: 'role',
|
|
276
265
|
what: 'native-replacing explicit roles',
|
|
277
266
|
launchRole: 'sharer',
|
|
278
|
-
timeOut:
|
|
267
|
+
timeOut: 20,
|
|
279
268
|
defaultOn: true
|
|
280
269
|
},
|
|
281
270
|
{
|
|
@@ -303,7 +292,7 @@ const allRules = [
|
|
|
303
292
|
id: 'textSem',
|
|
304
293
|
what: 'semantically vague elements i, b, and/or small',
|
|
305
294
|
launchRole: 'sharer',
|
|
306
|
-
timeOut:
|
|
295
|
+
timeOut: 5,
|
|
307
296
|
defaultOn: true
|
|
308
297
|
},
|
|
309
298
|
{
|
|
@@ -387,7 +376,7 @@ const allRules = [
|
|
|
387
376
|
id: 'hover',
|
|
388
377
|
what: 'hover-caused content changes',
|
|
389
378
|
launchRole: 'waster',
|
|
390
|
-
timeOut:
|
|
379
|
+
timeOut: 20,
|
|
391
380
|
defaultOn: true
|
|
392
381
|
},
|
|
393
382
|
{
|
|
@@ -428,24 +417,6 @@ process.on('unhandledRejection', reason => {
|
|
|
428
417
|
|
|
429
418
|
// FUNCTIONS
|
|
430
419
|
|
|
431
|
-
// Conducts a JSON-defined test.
|
|
432
|
-
const jsonTest = async (ruleID, ruleArgs) => {
|
|
433
|
-
const [page, withItems] = ruleArgs;
|
|
434
|
-
// Get the rule definition.
|
|
435
|
-
const ruleJSON = await fs.readFile(`${__dirname}/../testaro/${ruleID}.json`, 'utf8');
|
|
436
|
-
const ruleObj = JSON.parse(ruleJSON);
|
|
437
|
-
// Initialize the locators and result.
|
|
438
|
-
const all = await init(100, page, ruleObj.selector);
|
|
439
|
-
all.locs = all.allLocs;
|
|
440
|
-
// Populate and return the result.
|
|
441
|
-
const whats = [
|
|
442
|
-
ruleObj.complaints.instance,
|
|
443
|
-
ruleObj.complaints.summary
|
|
444
|
-
];
|
|
445
|
-
return await getRuleResult(
|
|
446
|
-
withItems, all, ruleObj.ruleID, whats, ruleObj.ordinalSeverity, ruleObj.summaryTagName
|
|
447
|
-
);
|
|
448
|
-
};
|
|
449
420
|
// Waits.
|
|
450
421
|
const wait = ms => {
|
|
451
422
|
return new Promise(resolve => {
|
|
@@ -547,158 +518,136 @@ exports.reporter = async (page, report, actIndex) => {
|
|
|
547
518
|
};
|
|
548
519
|
browser.on('disconnected', disconnectHandler);
|
|
549
520
|
}
|
|
550
|
-
// Initialize an argument array for reporter
|
|
521
|
+
// Initialize an argument array for the reporter.
|
|
551
522
|
const ruleArgs = [page, withItems];
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
// If the time limit expires during the test:
|
|
575
|
-
const timer = new Promise(resolve => {
|
|
576
|
-
timeout = setTimeout(() => {
|
|
577
|
-
// Add data about the test, including its prevention, to the result.
|
|
578
|
-
const endTime = Date.now();
|
|
579
|
-
testTimes.push([rule, Math.round((endTime - startTime) / 1000)]);
|
|
580
|
-
data.rulePreventions.push(ruleID);
|
|
581
|
-
data.rulePreventionMessages[ruleID] = 'Timeout';
|
|
582
|
-
ruleResult.totals = [0, 0, 0, 0];
|
|
583
|
-
ruleResult.standardInstances = [];
|
|
584
|
-
console.log(`ERROR: Test of testaro rule ${ruleID} timed out`);
|
|
585
|
-
resolve({timedOut: true});
|
|
586
|
-
}, timeLimit);
|
|
587
|
-
});
|
|
588
|
-
// Perform the test, subject to the time limit.
|
|
589
|
-
const ruleReport = isJS
|
|
590
|
-
? require(`../testaro/${ruleID}`).reporter(... ruleArgs)
|
|
591
|
-
: jsonTest(ruleID, ruleArgs);
|
|
592
|
-
// Get the test result or a timeout result.
|
|
593
|
-
const ruleOrTimeoutReport = await Promise.race([timer, ruleReport]);
|
|
594
|
-
// If the test was completed:
|
|
595
|
-
if (! ruleOrTimeoutReport.timedOut) {
|
|
596
|
-
// Add data from the test to the result.
|
|
523
|
+
// If the rule has extra arguments:
|
|
524
|
+
if (argRules && argRules.includes(ruleID)) {
|
|
525
|
+
// Add them to the argument array.
|
|
526
|
+
ruleArgs.push(... args[ruleID]);
|
|
527
|
+
}
|
|
528
|
+
result[ruleID] ??= {};
|
|
529
|
+
const ruleResult = result[ruleID];
|
|
530
|
+
const {what} = rule;
|
|
531
|
+
ruleResult.what = what || '';
|
|
532
|
+
const startTime = Date.now();
|
|
533
|
+
let timeout;
|
|
534
|
+
let testRetries = 2;
|
|
535
|
+
let testSuccess = false;
|
|
536
|
+
// Until all permitted retries are exhausted or the test succeeds:
|
|
537
|
+
while (testRetries > 0 && ! testSuccess) {
|
|
538
|
+
try {
|
|
539
|
+
// Apply a time limit to the test.
|
|
540
|
+
const timeLimit = 1000 * timeoutMultiplier * rule.timeOut;
|
|
541
|
+
// If the time limit expires during the test:
|
|
542
|
+
const timer = new Promise(resolve => {
|
|
543
|
+
timeout = setTimeout(() => {
|
|
544
|
+
// Add data about the test, including its prevention, to the result.
|
|
597
545
|
const endTime = Date.now();
|
|
598
|
-
testTimes.push([
|
|
599
|
-
Object.keys(ruleOrTimeoutReport).forEach(key => {
|
|
600
|
-
ruleResult[key] = ruleOrTimeoutReport[key];
|
|
601
|
-
});
|
|
602
|
-
// If the test was prevented:
|
|
603
|
-
if (ruleResult.data?.prevented && ruleResult.data.error) {
|
|
604
|
-
// Add this to the result.
|
|
605
|
-
data.rulePreventions.push(ruleID);
|
|
606
|
-
data.rulePreventionMessages[ruleID] = ruleResult.data.error;
|
|
607
|
-
}
|
|
608
|
-
// If the result includes totals:
|
|
609
|
-
if (ruleResult.totals) {
|
|
610
|
-
// Round them.
|
|
611
|
-
ruleResult.totals = ruleResult.totals.map(total => Math.round(total));
|
|
612
|
-
}
|
|
613
|
-
// Prevent a retry of the test.
|
|
614
|
-
testSuccess = true;
|
|
615
|
-
// If testing is to stop after a failure and the page failed the test:
|
|
616
|
-
if (stopOnFail && ruleResult.totals && ruleResult.totals.some(total => total)) {
|
|
617
|
-
// Stop testing.
|
|
618
|
-
break;
|
|
619
|
-
}
|
|
620
|
-
}
|
|
621
|
-
// Otherwise, i.e. if the test timed out:
|
|
622
|
-
else {
|
|
623
|
-
// Report this.
|
|
546
|
+
testTimes.push([rule, Math.round((endTime - startTime) / 1000)]);
|
|
624
547
|
data.rulePreventions.push(ruleID);
|
|
625
548
|
data.rulePreventionMessages[ruleID] = 'Timeout';
|
|
626
|
-
|
|
549
|
+
ruleResult.totals = [0, 0, 0, 0];
|
|
550
|
+
ruleResult.standardInstances = [];
|
|
551
|
+
console.log(`ERROR: Test of testaro rule ${ruleID} timed out`);
|
|
552
|
+
resolve({timedOut: true});
|
|
553
|
+
}, timeLimit);
|
|
554
|
+
});
|
|
555
|
+
// Perform the test, subject to the time limit.
|
|
556
|
+
const ruleReport = require(`../testaro/${ruleID}`).reporter(... ruleArgs);
|
|
557
|
+
// Get the test result or a timeout result.
|
|
558
|
+
const ruleOrTimeoutReport = await Promise.race([timer, ruleReport]);
|
|
559
|
+
// If the test was completed:
|
|
560
|
+
if (! ruleOrTimeoutReport.timedOut) {
|
|
561
|
+
// Add data from the test to the result.
|
|
562
|
+
const endTime = Date.now();
|
|
563
|
+
testTimes.push([ruleID, Math.round((endTime - startTime) / 1000)]);
|
|
564
|
+
Object.keys(ruleOrTimeoutReport).forEach(key => {
|
|
565
|
+
ruleResult[key] = ruleOrTimeoutReport[key];
|
|
566
|
+
});
|
|
567
|
+
// If the test was prevented:
|
|
568
|
+
if (ruleResult.data?.prevented && ruleResult.data.error) {
|
|
569
|
+
// Add this to the result.
|
|
570
|
+
data.rulePreventions.push(ruleID);
|
|
571
|
+
data.rulePreventionMessages[ruleID] = ruleResult.data.error;
|
|
572
|
+
}
|
|
573
|
+
// If the result includes totals:
|
|
574
|
+
if (ruleResult.totals) {
|
|
575
|
+
// Round them.
|
|
576
|
+
ruleResult.totals = ruleResult.totals.map(total => Math.round(total));
|
|
577
|
+
}
|
|
578
|
+
// Prevent a retry of the test.
|
|
579
|
+
testSuccess = true;
|
|
580
|
+
// If testing is to stop after a failure and the page failed the test:
|
|
581
|
+
if (stopOnFail && ruleResult.totals && ruleResult.totals.some(total => total)) {
|
|
582
|
+
// Stop testing.
|
|
627
583
|
break;
|
|
628
584
|
}
|
|
629
585
|
}
|
|
630
|
-
//
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
586
|
+
// Otherwise, i.e. if the test timed out:
|
|
587
|
+
else {
|
|
588
|
+
// Report this.
|
|
589
|
+
data.rulePreventions.push(ruleID);
|
|
590
|
+
data.rulePreventionMessages[ruleID] = 'Timeout';
|
|
591
|
+
// Stop retrying the test.
|
|
592
|
+
break;
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
// If an error is thrown by the test:
|
|
596
|
+
catch(error) {
|
|
597
|
+
const isPageClosed = ['closed', 'Protocol error', 'Target page'].some(phrase =>
|
|
598
|
+
error.message.includes(phrase)
|
|
599
|
+
);
|
|
600
|
+
// If the page has closed and there are retries left:
|
|
601
|
+
if (isPageClosed && testRetries) {
|
|
602
|
+
// Report this and decrement the allowed retry count.
|
|
603
|
+
console.log(
|
|
604
|
+
`WARNING: Retry ${3 - testRetries--} of test ${ruleID} starting after page closed`
|
|
634
605
|
);
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
);
|
|
650
|
-
page = require('../run').page;
|
|
651
|
-
// If the page replacement failed:
|
|
652
|
-
if (! page) {
|
|
653
|
-
// Report this.
|
|
654
|
-
console.log(`ERROR: Browser relaunch to retry test ${ruleID} failed`);
|
|
655
|
-
data.rulePreventions.push(ruleID);
|
|
656
|
-
data.rulePreventionMessages[ruleID] = 'Retry failure due to browser relaunch failure';
|
|
657
|
-
// Stop retrying the test.
|
|
658
|
-
break;
|
|
659
|
-
}
|
|
660
|
-
// Update the rule arguments with the current page.
|
|
661
|
-
ruleArgs[0] = page;
|
|
662
|
-
}
|
|
663
|
-
// Otherwise, i.e. if the page is open or it is closed but no retries are left:
|
|
664
|
-
else {
|
|
665
|
-
// Treat the test as prevented.
|
|
606
|
+
await wait(2000);
|
|
607
|
+
// Replace the browser and the page in the run module and navigate to the target.
|
|
608
|
+
await launch(
|
|
609
|
+
report,
|
|
610
|
+
actIndex,
|
|
611
|
+
headEmulation,
|
|
612
|
+
report.browserID,
|
|
613
|
+
url
|
|
614
|
+
);
|
|
615
|
+
page = require('../run').page;
|
|
616
|
+
// If the page replacement failed:
|
|
617
|
+
if (! page) {
|
|
618
|
+
// Report this.
|
|
619
|
+
console.log(`ERROR: Browser relaunch to retry test ${ruleID} failed`);
|
|
666
620
|
data.rulePreventions.push(ruleID);
|
|
667
|
-
data.rulePreventionMessages[ruleID] =
|
|
668
|
-
|
|
669
|
-
// Do not retry the test even if retries are left.
|
|
621
|
+
data.rulePreventionMessages[ruleID] = 'Retry failure due to browser relaunch failure';
|
|
622
|
+
// Stop retrying the test.
|
|
670
623
|
break;
|
|
671
624
|
}
|
|
625
|
+
// Update the rule arguments with the current page.
|
|
626
|
+
ruleArgs[0] = page;
|
|
672
627
|
}
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
628
|
+
// Otherwise, i.e. if the page is open or it is closed but no retries are left:
|
|
629
|
+
else {
|
|
630
|
+
// Treat the test as prevented.
|
|
631
|
+
data.rulePreventions.push(ruleID);
|
|
632
|
+
data.rulePreventionMessages[ruleID] = error.message;
|
|
633
|
+
console.log(`ERROR: Test of testaro rule ${ruleID} prevented (${error.message})`);
|
|
634
|
+
// Do not retry the test even if retries are left.
|
|
635
|
+
break;
|
|
676
636
|
}
|
|
677
637
|
}
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
crashHandler = null;
|
|
682
|
-
}
|
|
683
|
-
if (browser && disconnectHandler) {
|
|
684
|
-
browser.off('disconnected', disconnectHandler);
|
|
685
|
-
disconnectHandler = null;
|
|
638
|
+
finally {
|
|
639
|
+
// Clear the timeout.
|
|
640
|
+
clearTimeout(timeout);
|
|
686
641
|
}
|
|
687
642
|
}
|
|
688
|
-
//
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
crashHandler = null;
|
|
697
|
-
}
|
|
698
|
-
if (browser && disconnectHandler) {
|
|
699
|
-
browser.off('disconnected', disconnectHandler);
|
|
700
|
-
disconnectHandler = null;
|
|
701
|
-
}
|
|
643
|
+
// Clear the error listeners.
|
|
644
|
+
if (page && ! page.isClosed() && crashHandler) {
|
|
645
|
+
page.off('crash', crashHandler);
|
|
646
|
+
crashHandler = null;
|
|
647
|
+
}
|
|
648
|
+
if (browser && disconnectHandler) {
|
|
649
|
+
browser.off('disconnected', disconnectHandler);
|
|
650
|
+
disconnectHandler = null;
|
|
702
651
|
}
|
|
703
652
|
// Force a garbage collection.
|
|
704
653
|
try {
|
package/data/template.js
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
© 2023 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
|
-
|
|
4
|
-
Licensed under the MIT License. See LICENSE file at the project root or
|
|
5
|
-
https://opensource.org/license/mit/ for details.
|
|
6
|
-
|
|
7
|
-
SPDX-License-Identifier: MIT
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
/*
|
|
11
|
-
template
|
|
12
|
-
This test reports ….
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
// ########## IMPORTS
|
|
16
|
-
|
|
17
|
-
// Module to perform common operations.
|
|
18
|
-
const {init, report} = require('../procs/testaro');
|
|
19
|
-
|
|
20
|
-
// ########## FUNCTIONS
|
|
21
|
-
|
|
22
|
-
// Runs the test and returns the result.
|
|
23
|
-
exports.reporter = async (page, withItems) => {
|
|
24
|
-
// Initialize the locators and result.
|
|
25
|
-
const all = await init(100, page, 'body a');
|
|
26
|
-
// For each locator:
|
|
27
|
-
for (const loc of all.allLocs) {
|
|
28
|
-
// Get whether its element violates the rule.
|
|
29
|
-
const isBad = await loc.evaluate(el => el.tabIndex !== 0);
|
|
30
|
-
// If it does:
|
|
31
|
-
if (isBad) {
|
|
32
|
-
// Add the locator to the array of violators.
|
|
33
|
-
all.locs.push(loc);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
// Populate and return the result.
|
|
37
|
-
const whats = ['Itemized description', 'Summary description'];
|
|
38
|
-
return await report(withItems, all, 'ruleID', whats, 0);
|
|
39
|
-
};
|
package/testaro/hr.json
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"ruleID": "hr",
|
|
3
|
-
"selector": "body hr",
|
|
4
|
-
"complaints": {
|
|
5
|
-
"instance": "Element instead of styling is used for vertical segmentation",
|
|
6
|
-
"summary": "Elements instead of styling are used for vertical segmentation"
|
|
7
|
-
},
|
|
8
|
-
"ordinalSeverity": 0,
|
|
9
|
-
"summaryTagName": "HR"
|
|
10
|
-
}
|
package/testaro/linkExt.json
DELETED
package/testaro/linkOldAtt.json
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"ruleID": "linkOldAtt",
|
|
3
|
-
"selector": "a[charset], a[coords], a[name], a[rev], a[shape]",
|
|
4
|
-
"complaints": {
|
|
5
|
-
"instance": "Element has a deprecated attribute",
|
|
6
|
-
"summary": "Links have deprecated attributes"
|
|
7
|
-
},
|
|
8
|
-
"ordinalSeverity": 1,
|
|
9
|
-
"summaryTagName": "A"
|
|
10
|
-
}
|
package/testaro/linkTitle.js
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
© 2023 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
|
-
© 2025 Jonathan Robert Pool.
|
|
4
|
-
|
|
5
|
-
Licensed under the MIT License. See LICENSE file at the project root or
|
|
6
|
-
https://opensource.org/license/mit/ for details.
|
|
7
|
-
|
|
8
|
-
SPDX-License-Identifier: MIT
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
/*
|
|
12
|
-
linkTitle
|
|
13
|
-
Related to Tenon rule 79.
|
|
14
|
-
This test reports links with title attributes whose values the link text contains.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
// ########## IMPORTS
|
|
18
|
-
|
|
19
|
-
// Module to perform common operations.
|
|
20
|
-
const {simplify} = require('../procs/testaro');
|
|
21
|
-
// Module to get locator data.
|
|
22
|
-
const {getLocatorData} = require('../procs/getLocatorData');
|
|
23
|
-
|
|
24
|
-
// ########## FUNCTIONS
|
|
25
|
-
|
|
26
|
-
// Runs the test and returns the result.
|
|
27
|
-
exports.reporter = async (page, withItems) => {
|
|
28
|
-
// Specify the rule.
|
|
29
|
-
const ruleData = {
|
|
30
|
-
ruleID: 'linkTitle',
|
|
31
|
-
selector: 'a[title]',
|
|
32
|
-
pruner: async loc => {
|
|
33
|
-
const elData = await getLocatorData(loc);
|
|
34
|
-
const title = await loc.getAttribute('title');
|
|
35
|
-
return elData.excerpt.toLowerCase().includes(title.toLowerCase());
|
|
36
|
-
},
|
|
37
|
-
complaints: {
|
|
38
|
-
instance: 'Link has a title attribute that repeats link text content',
|
|
39
|
-
summary: 'Links have title attributes that repeat link text contents'
|
|
40
|
-
},
|
|
41
|
-
ordinalSeverity: 0,
|
|
42
|
-
summaryTagName: 'A'
|
|
43
|
-
};
|
|
44
|
-
// Run the test and return the result.
|
|
45
|
-
return await simplify(page, withItems, ruleData);
|
|
46
|
-
};
|
package/testaro/linkTo.json
DELETED
package/testaro/pseudoP.json
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"ruleID": "pseudoP",
|
|
3
|
-
"selector": "body br + br",
|
|
4
|
-
"complaints": {
|
|
5
|
-
"instance": "br element follows another br element, likely acting as a pseudo-paragraph",
|
|
6
|
-
"summary": "br elements follow other br elements, likely acting as pseudo-paragraphs"
|
|
7
|
-
},
|
|
8
|
-
"ordinalSeverity": 0,
|
|
9
|
-
"summaryTagName": "BR"
|
|
10
|
-
}
|
package/testaro/titledEl.json
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"ruleID": "titledEl",
|
|
3
|
-
"selector": "[title]:not(button, iframe, input, link, select, textarea)",
|
|
4
|
-
"complaints": {
|
|
5
|
-
"instance": "Ineligible element has a title attribute",
|
|
6
|
-
"summary": "Ineligible elements have title attributes"
|
|
7
|
-
},
|
|
8
|
-
"ordinalSeverity": 2,
|
|
9
|
-
"summaryTagName": ""
|
|
10
|
-
}
|