testaro 67.0.0 → 68.0.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/LICENSE +4 -16
- package/README.md +10 -2
- package/UPGRADES.md +1 -1
- package/dirWatch.js +2 -3
- package/ed11y/editoria11y.min.js +109 -690
- package/ed11y/editoria11y210.min.js +747 -0
- package/netWatch.js +6 -6
- package/package.json +1 -1
- package/procs/aslint.js +2 -2
- package/procs/catalog.js +190 -0
- package/procs/{dateOf.js → dateTime.js} +6 -4
- package/procs/doActs.js +1227 -0
- package/procs/doTestAct.js +63 -29
- package/procs/error.js +53 -0
- package/procs/job.js +64 -38
- package/procs/launch.js +596 -0
- package/procs/nu.js +3 -18
- package/procs/shoot.js +18 -2
- package/procs/testaro.js +102 -125
- package/procs/xPath.js +62 -0
- package/run.js +42 -1938
- package/scratch/README.md +9 -0
- package/testaro/adbID.js +3 -3
- package/testaro/allCaps.js +4 -5
- package/testaro/allHidden.js +19 -18
- package/testaro/allSlanted.js +4 -5
- package/testaro/altScheme.js +3 -3
- package/testaro/attVal.js +19 -35
- package/testaro/autocomplete.js +65 -62
- package/testaro/bulk.js +21 -20
- package/testaro/buttonMenu.js +112 -33
- package/testaro/captionLoc.js +3 -3
- package/testaro/datalistRef.js +4 -5
- package/testaro/distortion.js +3 -3
- package/testaro/docType.js +6 -9
- package/testaro/dupAtt.js +12 -25
- package/testaro/elements.js +4 -3
- package/testaro/embAc.js +4 -2
- package/testaro/focAll.js +6 -13
- package/testaro/focAndOp.js +3 -3
- package/testaro/focInd.js +3 -3
- package/testaro/focVis.js +4 -3
- package/testaro/headEl.js +5 -12
- package/testaro/headingAmb.js +45 -88
- package/testaro/hovInd.js +5 -5
- package/testaro/hover.js +44 -8
- package/testaro/hr.js +4 -4
- package/testaro/imageLink.js +3 -3
- package/testaro/labClash.js +3 -3
- package/testaro/legendLoc.js +3 -3
- package/testaro/lineHeight.js +3 -3
- package/testaro/linkAmb.js +25 -17
- package/testaro/linkExt.js +5 -5
- package/testaro/linkOldAtt.js +4 -3
- package/testaro/linkTo.js +4 -3
- package/testaro/linkUl.js +4 -5
- package/testaro/miniText.js +4 -3
- package/testaro/motion.js +3 -22
- package/testaro/nonTable.js +4 -5
- package/testaro/optRoleSel.js +3 -3
- package/testaro/phOnly.js +3 -3
- package/testaro/pseudoP.js +5 -5
- package/testaro/radioSet.js +4 -5
- package/testaro/role.js +4 -5
- package/testaro/secHeading.js +4 -5
- package/testaro/shoot0.js +3 -2
- package/testaro/shoot1.js +3 -2
- package/testaro/styleDiff.js +5 -12
- package/testaro/tabNav.js +30 -118
- package/testaro/targetSmall.js +30 -15
- package/testaro/textNodes.js +3 -1
- package/testaro/textSem.js +4 -5
- package/testaro/title.js +4 -2
- package/testaro/titledEl.js +3 -3
- package/testaro/zIndex.js +3 -3
- package/tests/alfa.js +28 -54
- package/tests/aslint.js +20 -53
- package/tests/axe.js +76 -13
- package/tests/ed11y.js +69 -141
- package/tests/htmlcs.js +69 -38
- package/tests/ibm.js +54 -9
- package/tests/nuVal.js +65 -12
- package/tests/nuVnu.js +76 -26
- package/tests/qualWeb.js +89 -44
- package/tests/testaro.js +288 -273
- package/tests/wave.js +142 -117
- package/tests/wax.js +61 -42
- package/procs/getLocatorData.js +0 -192
- package/procs/identify.js +0 -250
- package/procs/isInlineLink.js +0 -42
- package/procs/screenShot.js +0 -32
- package/procs/standardize.js +0 -524
- package/procs/target.js +0 -90
- package/procs/tellServer.js +0 -43
- package/scripts/dumpAlts.js +0 -28
package/netWatch.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
2
|
© 2022–2025 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
|
-
© 2025 Jonathan Robert Pool.
|
|
3
|
+
© 2025–2026 Jonathan Robert Pool.
|
|
4
4
|
|
|
5
5
|
Licensed under the MIT License. See LICENSE file at the project root or
|
|
6
6
|
https://opensource.org/license/mit/ for details.
|
|
@@ -24,6 +24,8 @@ const httpClient = require('http');
|
|
|
24
24
|
const httpsClient = require('https');
|
|
25
25
|
// Module to perform jobs.
|
|
26
26
|
const {doJob} = require('./run');
|
|
27
|
+
// Module to process dates and times.
|
|
28
|
+
const {nowString} = require('./procs/dateTime');
|
|
27
29
|
|
|
28
30
|
// CONSTANTS
|
|
29
31
|
|
|
@@ -34,8 +36,6 @@ const auths = netWatchURLIDs.map(id => process.env[`NETWATCH_URL_${id}_AUTH`]);
|
|
|
34
36
|
|
|
35
37
|
// FUNCTIONS
|
|
36
38
|
|
|
37
|
-
// Returns a string representing the date and time.
|
|
38
|
-
const nowString = () => (new Date()).toISOString().slice(2, 16);
|
|
39
39
|
// Waits.
|
|
40
40
|
const wait = ms => {
|
|
41
41
|
return new Promise(resolve => {
|
|
@@ -144,13 +144,13 @@ exports.netWatch = async (isForever, intervalInSeconds, isCertTolerant = true) =
|
|
|
144
144
|
// Check it for validity.
|
|
145
145
|
const jobInvalidity = isValidJob(contentObj);
|
|
146
146
|
// If it is invalid:
|
|
147
|
-
if (jobInvalidity) {
|
|
147
|
+
if (! jobInvalidity.isValid) {
|
|
148
148
|
// Report this to the server.
|
|
149
149
|
serveObject({
|
|
150
150
|
message: `invalidJob`,
|
|
151
|
-
jobInvalidity
|
|
151
|
+
error: jobInvalidity.error
|
|
152
152
|
}, response);
|
|
153
|
-
console.log(`${logStart}invalid job (${jobInvalidity})`);
|
|
153
|
+
console.log(`${logStart}invalid job (${jobInvalidity.error})`);
|
|
154
154
|
resolve(true);
|
|
155
155
|
}
|
|
156
156
|
// Otherwise, i.e. if it is valid:
|
package/package.json
CHANGED
package/procs/aslint.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/*
|
|
2
2
|
© 2023 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
|
+
© 2026 Jonathan Robert Pool.
|
|
3
4
|
|
|
4
|
-
Licensed under the MIT License. See LICENSE file at the project root or
|
|
5
|
-
https://opensource.org/license/mit/ for details.
|
|
5
|
+
Licensed under the MIT License. See LICENSE file at the project root or https://opensource.org/license/mit/ for details.
|
|
6
6
|
|
|
7
7
|
SPDX-License-Identifier: MIT
|
|
8
8
|
*/
|
package/procs/catalog.js
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/*
|
|
2
|
+
© 2025–2026 Jonathan Robert Pool.
|
|
3
|
+
|
|
4
|
+
Licensed under the MIT License. See LICENSE file at the project root or https://opensource.org/license/mit/ for details.
|
|
5
|
+
|
|
6
|
+
SPDX-License-Identifier: MIT
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/*
|
|
10
|
+
catalog
|
|
11
|
+
Creates and returns a catalog of a target.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
// IMPORTS
|
|
15
|
+
|
|
16
|
+
// Module to close and launch browsers.
|
|
17
|
+
const {browserClose, launch} = require('./launch');
|
|
18
|
+
const {getXPathCatalogIndex} = require('./xPath');
|
|
19
|
+
|
|
20
|
+
// FUNCTIONS
|
|
21
|
+
|
|
22
|
+
// Creates and returns a catalog.
|
|
23
|
+
exports.getCatalog = async report => {
|
|
24
|
+
const {browserID} = report;
|
|
25
|
+
const targetURL = report.target?.url;
|
|
26
|
+
// If the report specifies a global browser ID and a global target URL:
|
|
27
|
+
if (browserID && targetURL) {
|
|
28
|
+
// Launch a browser, navigate to the target, and get the resulting page.
|
|
29
|
+
const page = await launch({
|
|
30
|
+
report,
|
|
31
|
+
actIndex: null,
|
|
32
|
+
tempBrowserID: browserID,
|
|
33
|
+
tempURL: targetURL
|
|
34
|
+
});
|
|
35
|
+
// If the launch and navigation succeeded:
|
|
36
|
+
if (page) {
|
|
37
|
+
// Create a catalog of the elements in the page.
|
|
38
|
+
const catalog = await page.evaluate(() => {
|
|
39
|
+
// Adds an element property to a catalog and returns its value.
|
|
40
|
+
const addToCatalog = (elementIndex, catalog, propertyName, value) => {
|
|
41
|
+
if (value) {
|
|
42
|
+
catalog[propertyName] ??= {};
|
|
43
|
+
catalog[propertyName][value] ??= [];
|
|
44
|
+
catalog[propertyName][value].push(elementIndex);
|
|
45
|
+
return value;
|
|
46
|
+
}
|
|
47
|
+
return '';
|
|
48
|
+
};
|
|
49
|
+
const elements = Array.from(document.querySelectorAll('*'));
|
|
50
|
+
// Initialize a catalog.
|
|
51
|
+
const cat = {
|
|
52
|
+
element: {},
|
|
53
|
+
tagName: {},
|
|
54
|
+
id: {},
|
|
55
|
+
startTag: {},
|
|
56
|
+
text: {},
|
|
57
|
+
boxID: {},
|
|
58
|
+
pathID: {}
|
|
59
|
+
};
|
|
60
|
+
// For each element in the page:
|
|
61
|
+
for (const index in elements) {
|
|
62
|
+
const element = elements[index];
|
|
63
|
+
// Index it by its properties in the catalog.
|
|
64
|
+
const tagName = addToCatalog(index, cat, 'tagName', element.tagName || '');
|
|
65
|
+
const id = addToCatalog(index, cat, 'id', element.id || '');
|
|
66
|
+
const startTag = addToCatalog(
|
|
67
|
+
index,
|
|
68
|
+
cat,
|
|
69
|
+
'startTag',
|
|
70
|
+
element.outerHTML?.replace(/^.*?</s, '<').replace(/>.*$/s, '>') ?? ''
|
|
71
|
+
);
|
|
72
|
+
const innerText = element.closest('head') ? '' : element.innerText;
|
|
73
|
+
const segments = innerText?.trim().split('\n');
|
|
74
|
+
const tidySegments = segments?.map(segment => segment.trim().replace(/\s+/g, ' ')) ?? [];
|
|
75
|
+
const neededSegments = tidySegments.filter(segment => segment.length);
|
|
76
|
+
neededSegments.splice(1, neededSegments.length - 2);
|
|
77
|
+
const text = addToCatalog(index, cat, 'text', neededSegments.join('◢‖◤'));
|
|
78
|
+
const domRect = element.getBoundingClientRect();
|
|
79
|
+
const boxID = addToCatalog(
|
|
80
|
+
index,
|
|
81
|
+
cat,
|
|
82
|
+
'boxID',
|
|
83
|
+
domRect
|
|
84
|
+
? ['x', 'y', 'width', 'height'].map(key => Math.round(domRect[key])).join(':')
|
|
85
|
+
: ''
|
|
86
|
+
);
|
|
87
|
+
const pathID = addToCatalog(index, cat, 'pathID', window.getXPath(element));
|
|
88
|
+
// Add an entry for it to the element data in the catalog.
|
|
89
|
+
cat.element[index] = {
|
|
90
|
+
tagName,
|
|
91
|
+
id,
|
|
92
|
+
startTag,
|
|
93
|
+
textLinkable: false,
|
|
94
|
+
text,
|
|
95
|
+
boxID,
|
|
96
|
+
pathID
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
// For each text in the catalog:
|
|
100
|
+
Object.keys(cat.text).forEach(text => {
|
|
101
|
+
const textElementIndexes = cat.text[text];
|
|
102
|
+
// If every element that has it is in the same subtree, so is page-unique:
|
|
103
|
+
if (
|
|
104
|
+
textElementIndexes.slice(0, -1).every(
|
|
105
|
+
(elementIndex, index) => cat
|
|
106
|
+
.element[textElementIndexes[index + 1]]
|
|
107
|
+
.pathID
|
|
108
|
+
.startsWith(cat.element[elementIndex].pathID)
|
|
109
|
+
)
|
|
110
|
+
) {
|
|
111
|
+
// For each element that has it:
|
|
112
|
+
textElementIndexes.forEach(index => {
|
|
113
|
+
// If it is not in the head:
|
|
114
|
+
if (! cat.element[index].pathID.includes('/head[1]')) {
|
|
115
|
+
// Mark it as linkable in the element data in the catalog.
|
|
116
|
+
cat.element[index].textLinkable = true;
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
return cat;
|
|
122
|
+
});
|
|
123
|
+
// Close the browser and its context.
|
|
124
|
+
await browserClose(page);
|
|
125
|
+
// Return the catalog.
|
|
126
|
+
return catalog;
|
|
127
|
+
}
|
|
128
|
+
// Otherwise, i.e. if the launch or navigation failed, report and return this.
|
|
129
|
+
console.log('ERROR: Launch or navigation failure prevented catalog creation');
|
|
130
|
+
return {};
|
|
131
|
+
}
|
|
132
|
+
// Otherwise, i.e. if the report specification is incomplete, report and return this.
|
|
133
|
+
console.log('ERROR: Job omits browser ID or target URL, preventing catalog creation');
|
|
134
|
+
return {};
|
|
135
|
+
};
|
|
136
|
+
// Prunes an elements-only catalog.
|
|
137
|
+
exports.pruneCatalog = report => {
|
|
138
|
+
const {acts} = report;
|
|
139
|
+
const citedElementIndexes = new Set();
|
|
140
|
+
// For each act in the report:
|
|
141
|
+
acts.forEach(act => {
|
|
142
|
+
// If it is a test with a standard result:
|
|
143
|
+
if (act.type === 'test' && act.result?.standardResult) {
|
|
144
|
+
const {instances} = act.result.standardResult;
|
|
145
|
+
// For each instance of the standard result:
|
|
146
|
+
instances.forEach(instance => {
|
|
147
|
+
const {catalogIndex} = instance;
|
|
148
|
+
// If the instance has a catalog index:
|
|
149
|
+
if (catalogIndex) {
|
|
150
|
+
// Ensure the index is classified as cited.
|
|
151
|
+
citedElementIndexes.add(catalogIndex);
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
const prunedCatalog = {};
|
|
157
|
+
// For each element in the catalog:
|
|
158
|
+
const {catalog} = report;
|
|
159
|
+
Object.keys(catalog).forEach(elementIndex => {
|
|
160
|
+
// If it is cited by at least 1 instance:
|
|
161
|
+
if (citedElementIndexes.has(elementIndex)) {
|
|
162
|
+
// Add it to the pruned catalog.
|
|
163
|
+
prunedCatalog[elementIndex] = catalog[elementIndex];
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
// Replace the catalog with the pruned catalog.
|
|
167
|
+
report.catalog = prunedCatalog;
|
|
168
|
+
};
|
|
169
|
+
// Adds a catalog index or, if necessary, an XPath to a proto-instance.
|
|
170
|
+
exports.addCatalogIndex = async (protoInstance, locator, catalog) => {
|
|
171
|
+
// Get the XPath of the element referenced by the locator.
|
|
172
|
+
const xPath = await locator.evaluate(element => window.getXPath(element));
|
|
173
|
+
// If the acquisition succeeded:
|
|
174
|
+
if (xPath) {
|
|
175
|
+
// Get the catalog index of the element.
|
|
176
|
+
const catalogIndex = getXPathCatalogIndex(catalog, xPath);
|
|
177
|
+
// If the acquisition succeeded:
|
|
178
|
+
if (catalogIndex) {
|
|
179
|
+
// Add it to the proto-instance.
|
|
180
|
+
protoInstance.catalogIndex = catalogIndex;
|
|
181
|
+
}
|
|
182
|
+
// Otherwise, i.e. if the acquisition failed:
|
|
183
|
+
else {
|
|
184
|
+
// Add the XPath to the proto-instance.
|
|
185
|
+
protoInstance.pathID = xPath;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// Return the proto-instance with any modification.
|
|
189
|
+
return protoInstance;
|
|
190
|
+
};
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/*
|
|
2
2
|
© 2024 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
|
+
© 2026 Jonathan Robert Pool.
|
|
3
4
|
|
|
4
|
-
Licensed under the MIT License. See LICENSE file at the project root or
|
|
5
|
-
https://opensource.org/license/mit/ for details.
|
|
5
|
+
Licensed under the MIT License. See LICENSE file at the project root or https://opensource.org/license/mit/ for details.
|
|
6
6
|
|
|
7
7
|
SPDX-License-Identifier: MIT
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
/*
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
dateTime
|
|
12
|
+
Processes dates and times.
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
// Inserts a character periodically in a string.
|
|
@@ -32,3 +32,5 @@ exports.dateOf = timeStamp => {
|
|
|
32
32
|
return null;
|
|
33
33
|
}
|
|
34
34
|
};
|
|
35
|
+
// Returns a string representing the date and time.
|
|
36
|
+
exports.nowString = () => (new Date()).toISOString().slice(2, 16);
|