testaro 12.3.2 → 12.4.1
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 +7 -6
- package/actSpecs.js +6 -0
- package/package.json +2 -1
- package/run.js +6 -4
- package/tests/attVal.js +2 -2
- package/tests/dupAtt.js +54 -0
- package/validation/tests/jobs/allHidden.json +1 -1
- package/validation/tests/jobs/attVal.json +60 -0
- package/validation/tests/jobs/autocomplete.json +4 -4
- package/validation/tests/jobs/bulk.json +1 -1
- package/validation/tests/jobs/docType.json +1 -1
- package/validation/tests/jobs/dupAtt.json +51 -0
- package/validation/tests/jobs/elements.json +1 -1
- package/validation/tests/jobs/embAc.json +1 -1
- package/validation/tests/jobs/filter.json +1 -1
- package/validation/tests/jobs/focAll.json +1 -1
- package/validation/tests/jobs/focInd.json +1 -1
- package/validation/tests/jobs/focOp.json +1 -1
- package/validation/tests/jobs/focVis.json +1 -1
- package/validation/tests/jobs/hover.json +1 -1
- package/validation/tests/jobs/labClash.json +1 -1
- package/validation/tests/jobs/linkTo.json +1 -1
- package/validation/tests/jobs/linkUl.json +1 -1
- package/validation/tests/jobs/menuNav.json +1 -1
- package/validation/tests/jobs/miniText.json +1 -1
- package/validation/tests/jobs/motion.json +1 -1
- package/validation/tests/jobs/nonTable.json +1 -1
- package/validation/tests/jobs/radioSet.json +1 -1
- package/validation/tests/jobs/role.json +1 -1
- package/validation/tests/jobs/styleDiff.json +1 -1
- package/validation/tests/jobs/tabNav.json +1 -1
- package/validation/tests/jobs/textNodes.json +1 -1
- package/validation/tests/jobs/title.json +1 -1
- package/validation/tests/jobs/titledEl.json +1 -1
- package/validation/tests/jobs/zIndex.json +1 -1
- package/validation/tests/targets/attVal/bad.html +15 -0
- package/validation/tests/targets/attVal/good.html +15 -0
- package/validation/tests/targets/dupAtt/bad.html +19 -0
- package/validation/tests/targets/dupAtt/good.html +16 -0
- package/watch.js +14 -10
package/README.md
CHANGED
|
@@ -31,7 +31,9 @@ Testaro uses:
|
|
|
31
31
|
- [Playwright](https://playwright.dev/) to launch browsers, perform user actions in them, and perform tests
|
|
32
32
|
- [pixelmatch](https://www.npmjs.com/package/pixelmatch) to measure motion
|
|
33
33
|
|
|
34
|
-
Testaro includes some of its own accessibility tests.
|
|
34
|
+
Testaro includes some of its own accessibility tests. Some of them are derived from tests performed by the [BBC Accessibility Standards Checker](https://github.com/bbc/bbc-a11y).
|
|
35
|
+
|
|
36
|
+
In addition, Testaro performs tests of these tools:
|
|
35
37
|
- [accessibility-checker](https://www.npmjs.com/package/accessibility-checker) (the IBM Equal Access Accessibility Checker)
|
|
36
38
|
- [alfa](https://alfa.siteimprove.com/) (Siteimprove alfa)
|
|
37
39
|
- [axe-playwright](https://www.npmjs.com/package/axe-playwright) (Deque Axe-core)
|
|
@@ -42,8 +44,6 @@ Testaro includes some of its own accessibility tests. In addition, it performs t
|
|
|
42
44
|
- [Tenon](https://tenon.io/documentation/what-tenon-tests.php) (Level Access)
|
|
43
45
|
- [WAVE API](https://wave.webaim.org/api/) (WebAIM WAVE)
|
|
44
46
|
|
|
45
|
-
Some of the Testaro tests are derived from tests performed by the [BBC Accessibility Standards Checker](https://github.com/bbc/bbc-a11y).
|
|
46
|
-
|
|
47
47
|
As of this version, the counts of tests of the tools referenced above were:
|
|
48
48
|
- Alfa: 103
|
|
49
49
|
- Axe-core: 138
|
|
@@ -54,9 +54,8 @@ As of this version, the counts of tests of the tools referenced above were:
|
|
|
54
54
|
- QualWeb core: 121
|
|
55
55
|
- Tenon: 180
|
|
56
56
|
- WAVE: 110
|
|
57
|
-
-
|
|
58
|
-
-
|
|
59
|
-
- grand total: 1351
|
|
57
|
+
- Testaro: 29
|
|
58
|
+
- total: 1356
|
|
60
59
|
|
|
61
60
|
## Quasi-tests
|
|
62
61
|
|
|
@@ -537,6 +536,8 @@ The third item in each array, if there are 3 items in the array, is the criterio
|
|
|
537
536
|
|
|
538
537
|
A typical use for an `expect` property is checking the correctness of a Testaro test. Thus, the validation jobs in the `validation/tests/jobs` directory all contain `test` acts with `expect` properties. See the “Validation” section below.
|
|
539
538
|
|
|
539
|
+
When a `test` act has an `expect` property, the result for that act has an `expectations` property reporting whether the expectations were satisfied. The value of `expectations` is an array of objects, one object per expectation. Each object includes a `property` property identifying the expectation, and a `passed` property with `true` or `false` value reporting whether the expectation was satisfied. If applicable, it also has other properties identifying what was expected and what was actually reported.
|
|
540
|
+
|
|
540
541
|
## Execution
|
|
541
542
|
|
|
542
543
|
### Introduction
|
package/actSpecs.js
CHANGED
|
@@ -187,6 +187,12 @@ exports.actSpecs = {
|
|
|
187
187
|
rules: [false, 'array', 'areNumbers', 'rule numbers (e.g., 25), if not all']
|
|
188
188
|
}
|
|
189
189
|
],
|
|
190
|
+
dupAtt: [
|
|
191
|
+
'Perform a dupAtt test',
|
|
192
|
+
{
|
|
193
|
+
withItems: [true, 'boolean', '', 'itemize']
|
|
194
|
+
}
|
|
195
|
+
],
|
|
190
196
|
elements: [
|
|
191
197
|
'Perform an elements test',
|
|
192
198
|
{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "testaro",
|
|
3
|
-
"version": "12.
|
|
3
|
+
"version": "12.4.1",
|
|
4
4
|
"description": "Automation of accessibility testing",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
"accessibility-checker": "*",
|
|
36
36
|
"axe-playwright": "*",
|
|
37
37
|
"dotenv": "*",
|
|
38
|
+
"node-fetch": "*",
|
|
38
39
|
"pixelmatch": "*",
|
|
39
40
|
"playwright": "*"
|
|
40
41
|
},
|
package/run.js
CHANGED
|
@@ -39,6 +39,7 @@ const tests = {
|
|
|
39
39
|
bulk: 'count of visible elements',
|
|
40
40
|
continuum: 'Level Access Continuum, community edition',
|
|
41
41
|
docType: 'document without a doctype property',
|
|
42
|
+
dupAtt: 'elements with duplicate attributes',
|
|
42
43
|
elements: 'data on specified elements',
|
|
43
44
|
embAc: 'active elements embedded in links or buttons',
|
|
44
45
|
filter: 'filter styles on elements',
|
|
@@ -498,7 +499,7 @@ const isTrue = (object, specs) => {
|
|
|
498
499
|
}
|
|
499
500
|
// Otherwise, i.e. if the expectation is of a property value:
|
|
500
501
|
else if (specs.length === 3) {
|
|
501
|
-
//
|
|
502
|
+
// Return whether the expectation was fulfilled.
|
|
502
503
|
const relation = specs[1];
|
|
503
504
|
const criterion = specs[2];
|
|
504
505
|
let satisfied;
|
|
@@ -518,16 +519,17 @@ const isTrue = (object, specs) => {
|
|
|
518
519
|
satisfied = actual !== criterion;
|
|
519
520
|
}
|
|
520
521
|
else if (relation === 'i') {
|
|
521
|
-
satisfied = actual.includes(criterion);
|
|
522
|
+
satisfied = typeof actual === 'string' && actual.includes(criterion);
|
|
522
523
|
}
|
|
523
524
|
else if (relation === '!i') {
|
|
524
|
-
satisfied = ! actual.includes(criterion);
|
|
525
|
+
satisfied = typeof actual === 'string' && ! actual.includes(criterion);
|
|
525
526
|
}
|
|
526
527
|
return [actual, satisfied];
|
|
527
528
|
}
|
|
528
529
|
// Otherwise, i.e. if the specifications are invalid:
|
|
529
530
|
else {
|
|
530
|
-
//
|
|
531
|
+
// Return this.
|
|
532
|
+
return [null, false];
|
|
531
533
|
}
|
|
532
534
|
};
|
|
533
535
|
// Adds a wait error result to an act.
|
package/tests/attVal.js
CHANGED
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
exports.reporter = async (page, attributeName, areLicit, values, withItems) => {
|
|
6
6
|
// Identify the elements that have the specified attribute with illicit values.
|
|
7
7
|
const badAttributeData = await page.evaluate(
|
|
8
|
-
args => {
|
|
8
|
+
async args => {
|
|
9
9
|
const attributeName = args[0];
|
|
10
10
|
// Whether the values are the licit or the illicit ones.
|
|
11
11
|
const areLicit = args[1];
|
|
12
12
|
const values = args[2];
|
|
13
13
|
// Returns the text of an element.
|
|
14
|
-
const textOf =
|
|
14
|
+
const textOf = (element, limit) => {
|
|
15
15
|
let text = element.textContent;
|
|
16
16
|
text = text.trim() || element.innerHTML;
|
|
17
17
|
return text.replace(/\s+/sg, ' ').replace(/<>&/g, '').slice(0, limit);
|
package/tests/dupAtt.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/*
|
|
2
|
+
dupAtt.js
|
|
3
|
+
This test reports duplicate attributes in the source of a document.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// ########## IMPORTS
|
|
7
|
+
|
|
8
|
+
// Module to make HTTP requests.
|
|
9
|
+
const fetch = require('node-fetch');
|
|
10
|
+
// Module to process files.
|
|
11
|
+
const fs = require('fs/promises');
|
|
12
|
+
|
|
13
|
+
// ########## FUNCTIONS
|
|
14
|
+
|
|
15
|
+
// Reports failures.
|
|
16
|
+
exports.reporter = async (page, withItems) => {
|
|
17
|
+
// Initialize the data.
|
|
18
|
+
const data = {total: 0};
|
|
19
|
+
if (withItems) {
|
|
20
|
+
data.items = [];
|
|
21
|
+
}
|
|
22
|
+
// Get the page.
|
|
23
|
+
const url = page.url();
|
|
24
|
+
const scheme = url.replace(/:.+/, '');
|
|
25
|
+
let rawPage;
|
|
26
|
+
if (scheme === 'file') {
|
|
27
|
+
const filePath = url.slice(7);
|
|
28
|
+
rawPage = await fs.readFile(filePath, 'utf8');
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
rawPage = await fetch(url);
|
|
32
|
+
}
|
|
33
|
+
// Extract its elements, in a uniform format.
|
|
34
|
+
const elements = rawPage
|
|
35
|
+
.match(/<[^/<>]+>/g)
|
|
36
|
+
.map(element => element.slice(1, -1).trim().replace(/\s*=\s*/g, '='))
|
|
37
|
+
.map(element => element.replace(/\s+/g, ' '));
|
|
38
|
+
// For each element:
|
|
39
|
+
elements.forEach(element => {
|
|
40
|
+
// Identify its attributes.
|
|
41
|
+
const attributes = element.split(' ').slice(1).map(attVal => attVal.replace(/=.+/, ''));
|
|
42
|
+
// If any is duplicated:
|
|
43
|
+
const attSet = new Set(attributes);
|
|
44
|
+
if (attSet.size < attributes.length) {
|
|
45
|
+
// Add this to the data.
|
|
46
|
+
data.total++;
|
|
47
|
+
if (withItems) {
|
|
48
|
+
data.items.push(element);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
// Return the data.
|
|
53
|
+
return {result: data};
|
|
54
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "attVal",
|
|
3
|
+
"what": "validation of attVal test",
|
|
4
|
+
"strict": true,
|
|
5
|
+
"timeLimit": 20,
|
|
6
|
+
"acts": [
|
|
7
|
+
{
|
|
8
|
+
"type": "launch",
|
|
9
|
+
"which": "chromium",
|
|
10
|
+
"what": "usual browser"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"type": "url",
|
|
14
|
+
"which": "__targets__/attVal/good.html",
|
|
15
|
+
"what": "page with permitted attribute values"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"type": "test",
|
|
19
|
+
"which": "attVal",
|
|
20
|
+
"attributeName": "lang",
|
|
21
|
+
"areLicit": true,
|
|
22
|
+
"values": ["en-US", "de-CH"],
|
|
23
|
+
"what": "attribute values",
|
|
24
|
+
"withItems": true,
|
|
25
|
+
"expect": [
|
|
26
|
+
["total", "=", 0],
|
|
27
|
+
["items.1"]
|
|
28
|
+
]
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"type": "url",
|
|
32
|
+
"which": "__targets__/attVal/bad.html",
|
|
33
|
+
"what": "page with permitted attribute values"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"type": "test",
|
|
37
|
+
"which": "attVal",
|
|
38
|
+
"attributeName": "lang",
|
|
39
|
+
"areLicit": false,
|
|
40
|
+
"values": ["en", "de"],
|
|
41
|
+
"what": "attribute values",
|
|
42
|
+
"withItems": true,
|
|
43
|
+
"expect": [
|
|
44
|
+
["total", "=", 2],
|
|
45
|
+
["items.0.tagName", "=", "HTML"],
|
|
46
|
+
["items.0.attributeValue", "=", "en"],
|
|
47
|
+
["items.1.tagName", "=", "SPAN"],
|
|
48
|
+
["items.1.attributeValue", "=", "de"],
|
|
49
|
+
["items.1.textStart", "i", "Veloparkieren"]
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
"sources": {
|
|
54
|
+
"script": "",
|
|
55
|
+
"host": {},
|
|
56
|
+
"requester": ""
|
|
57
|
+
},
|
|
58
|
+
"creationTime": "2023-04-19T12:34:00",
|
|
59
|
+
"timeStamp": "00000"
|
|
60
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"id": "
|
|
2
|
+
"id": "autocomplete",
|
|
3
3
|
"what": "validation of autocomplete test",
|
|
4
4
|
"strict": true,
|
|
5
5
|
"timeLimit": 20,
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"what": "autocomplete attributes for name and email",
|
|
21
21
|
"withItems": true,
|
|
22
22
|
"expect": [
|
|
23
|
-
["
|
|
23
|
+
["total", "=", 0],
|
|
24
24
|
["items.1"]
|
|
25
25
|
]
|
|
26
26
|
},
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"what": "autocomplete attributes for name and email",
|
|
36
36
|
"withItems": true,
|
|
37
37
|
"expect": [
|
|
38
|
-
["
|
|
38
|
+
["total", "=", 4],
|
|
39
39
|
["items.1.0", "=", "family-name"],
|
|
40
40
|
["items.2.1", "=", "Your email address"]
|
|
41
41
|
]
|
|
@@ -46,6 +46,6 @@
|
|
|
46
46
|
"host": {},
|
|
47
47
|
"requester": ""
|
|
48
48
|
},
|
|
49
|
-
"creationTime": "
|
|
49
|
+
"creationTime": "2023-04-16T21:06:00",
|
|
50
50
|
"timeStamp": "00000"
|
|
51
51
|
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "dupAtt",
|
|
3
|
+
"what": "validation of dupAtt test",
|
|
4
|
+
"strict": true,
|
|
5
|
+
"timeLimit": 20,
|
|
6
|
+
"acts": [
|
|
7
|
+
{
|
|
8
|
+
"type": "launch",
|
|
9
|
+
"which": "chromium",
|
|
10
|
+
"what": "usual browser"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"type": "url",
|
|
14
|
+
"which": "__targets__/dupAtt/good.html",
|
|
15
|
+
"what": "page without duplicate attributes"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"type": "test",
|
|
19
|
+
"which": "dupAtt",
|
|
20
|
+
"what": "elements with duplicate attributes",
|
|
21
|
+
"withItems": true,
|
|
22
|
+
"expect": [
|
|
23
|
+
["total", "=", 0],
|
|
24
|
+
["items.1"]
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"type": "url",
|
|
29
|
+
"which": "__targets__/dupAtt/bad.html",
|
|
30
|
+
"what": "page with duplicate attributes"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"type": "test",
|
|
34
|
+
"which": "dupAtt",
|
|
35
|
+
"what": "elements with duplicate attributes",
|
|
36
|
+
"withItems": true,
|
|
37
|
+
"expect": [
|
|
38
|
+
["total", "=", 2],
|
|
39
|
+
["items.0", "=", "p class=\"narrow\" id=\"daParagraph\" class=\"wide\""],
|
|
40
|
+
["items.1", "i", "large"]
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
"sources": {
|
|
45
|
+
"script": "",
|
|
46
|
+
"host": {},
|
|
47
|
+
"requester": ""
|
|
48
|
+
},
|
|
49
|
+
"creationTime": "2023-04-18T11:02:00",
|
|
50
|
+
"timeStamp": "00000"
|
|
51
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>Page with illicit attribute values</title>
|
|
6
|
+
<meta name="description" content="tester">
|
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<main>
|
|
11
|
+
<h1>Page with illicit attribute values</h1>
|
|
12
|
+
<p><q><span lang="de">Veloparkieren nicht gestattet</span></q> is Swiss German, so it should be marked up with the <code>de-ch</code> language tag.</p>
|
|
13
|
+
</main>
|
|
14
|
+
</body>
|
|
15
|
+
</html>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en-US">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>Page with licit attribute values</title>
|
|
6
|
+
<meta name="description" content="tester">
|
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<main>
|
|
11
|
+
<h1>Page with illicit attribute values</h1>
|
|
12
|
+
<p><q><span>lang="de-CH">Veloparkieren nicht gestattet</span></q> is Swiss German, so it is marked up with the <code>de-CH</code> language tag.</p>
|
|
13
|
+
</main>
|
|
14
|
+
</body>
|
|
15
|
+
</html>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en-US">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>Page with duplicate attributes</title>
|
|
6
|
+
<meta name="description" content="tester">
|
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<main>
|
|
11
|
+
<h1>Page with duplicate attributes</h1>
|
|
12
|
+
<p class="narrow" id="daParagraph" class="wide">Submit</p>
|
|
13
|
+
<p><button
|
|
14
|
+
aria-label="large"
|
|
15
|
+
aria-label="small"
|
|
16
|
+
>A paragraph</button></p>
|
|
17
|
+
</main>
|
|
18
|
+
</body>
|
|
19
|
+
</html>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en-US">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>Page without duplicate attributes</title>
|
|
6
|
+
<meta name="description" content="tester">
|
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<main>
|
|
11
|
+
<h1>Page without duplicate attributes</h1>
|
|
12
|
+
<p class="narrow" id="okParagraph" lang="es-US">Buscar</p>
|
|
13
|
+
<p><button id="p" aria-label="A body of text">A paragraph</button></p>
|
|
14
|
+
</main>
|
|
15
|
+
</body>
|
|
16
|
+
</html>
|
package/watch.js
CHANGED
|
@@ -24,6 +24,8 @@ const reportDir = process.env.REPORTDIR;
|
|
|
24
24
|
|
|
25
25
|
// ########## FUNCTIONS
|
|
26
26
|
|
|
27
|
+
// Returns a string representing the date and time.
|
|
28
|
+
const nowString = () => (new Date()).toISOString().slice(0, 19);
|
|
27
29
|
// Checks for a directory job.
|
|
28
30
|
const checkDirJob = async watchee => {
|
|
29
31
|
try {
|
|
@@ -44,12 +46,12 @@ const checkDirJob = async watchee => {
|
|
|
44
46
|
}
|
|
45
47
|
}
|
|
46
48
|
else {
|
|
47
|
-
console.log(
|
|
49
|
+
console.log(`No job to do (${nowString()})`);
|
|
48
50
|
return {};
|
|
49
51
|
}
|
|
50
52
|
}
|
|
51
53
|
catch(error) {
|
|
52
|
-
console.log(
|
|
54
|
+
console.log('ERROR: Directory watching failed');
|
|
53
55
|
return {};
|
|
54
56
|
}
|
|
55
57
|
};
|
|
@@ -86,13 +88,13 @@ const checkNetJob = async watchee => {
|
|
|
86
88
|
request.end();
|
|
87
89
|
});
|
|
88
90
|
if (job.id) {
|
|
89
|
-
console.log(`Network job ${job.id} received`);
|
|
91
|
+
console.log(`Network job ${job.id} received (${nowString()})`);
|
|
90
92
|
}
|
|
91
93
|
else if (job.message) {
|
|
92
94
|
console.log(job.message);
|
|
93
95
|
}
|
|
94
96
|
else {
|
|
95
|
-
console.log(
|
|
97
|
+
console.log(`No network job to do (${nowString()})`);
|
|
96
98
|
}
|
|
97
99
|
return job;
|
|
98
100
|
};
|
|
@@ -155,7 +157,7 @@ const writeNetReport = async report => {
|
|
|
155
157
|
const reportJSON = JSON.stringify(report, null, 2);
|
|
156
158
|
request.write(reportJSON);
|
|
157
159
|
request.end();
|
|
158
|
-
console.log(`Report ${report.id} submitted`);
|
|
160
|
+
console.log(`Report ${report.id} submitted (${nowString()})`);
|
|
159
161
|
}
|
|
160
162
|
else {
|
|
161
163
|
console.log('ERROR: Report has no sources property');
|
|
@@ -217,7 +219,9 @@ exports.cycle = async (isDirWatch, isForever, interval, watchee = null) => {
|
|
|
217
219
|
let statusOK = true;
|
|
218
220
|
// Prevent a wait before the first iteration.
|
|
219
221
|
let empty = false;
|
|
220
|
-
console.log(
|
|
222
|
+
console.log(
|
|
223
|
+
`Watching started with intervals of ${interval} seconds when idle (${nowString()})`
|
|
224
|
+
);
|
|
221
225
|
while (statusOK) {
|
|
222
226
|
if (empty) {
|
|
223
227
|
await wait(intervalMS);
|
|
@@ -233,14 +237,14 @@ exports.cycle = async (isDirWatch, isForever, interval, watchee = null) => {
|
|
|
233
237
|
// If there was one:
|
|
234
238
|
if (job.id) {
|
|
235
239
|
// Run it, save a report, and if applicable send the report to the job source.
|
|
236
|
-
console.log(`Running job ${job.id}`);
|
|
240
|
+
console.log(`Running job ${job.id} (${nowString()})`);
|
|
237
241
|
await runJob(JSON.parse(JSON.stringify(job)), isDirWatch);
|
|
238
|
-
console.log(`Job ${job.id} finished`);
|
|
242
|
+
console.log(`Job ${job.id} finished (${nowString()})`);
|
|
239
243
|
// If a directory was watched:
|
|
240
244
|
if (isDirWatch) {
|
|
241
245
|
// Archive the job.
|
|
242
246
|
await archiveJob(job, watchee);
|
|
243
|
-
console.log(`Job ${job.id} archived`);
|
|
247
|
+
console.log(`Job ${job.id} archived (${nowString()})`);
|
|
244
248
|
}
|
|
245
249
|
// If watching was specified for only 1 job, quit.
|
|
246
250
|
statusOK = isForever;
|
|
@@ -253,5 +257,5 @@ exports.cycle = async (isDirWatch, isForever, interval, watchee = null) => {
|
|
|
253
257
|
empty = true;
|
|
254
258
|
}
|
|
255
259
|
}
|
|
256
|
-
console.log(
|
|
260
|
+
console.log(`Watching ended (${nowString()})`);
|
|
257
261
|
};
|