@jrpool/kilotest 30.0.3 → 31.0.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/index.js +41 -4
- package/llms-full.txt +31 -14
- package/llms.txt +4 -1
- package/openapi.yaml +107 -36
- package/package.json +1 -1
- package/reportIssues/api.js +3 -2
- package/researchAgent.js +45 -5
- package/sitemap.xml +2 -0
- package/targets/api.js +3 -1
- package/testRecForm/api.js +48 -0
- package/util.js +16 -11
package/index.js
CHANGED
|
@@ -14,6 +14,7 @@ const {
|
|
|
14
14
|
getJobNames,
|
|
15
15
|
getJSON,
|
|
16
16
|
getLogPath,
|
|
17
|
+
getLogs,
|
|
17
18
|
getObject,
|
|
18
19
|
getPOSTData,
|
|
19
20
|
getReport,
|
|
@@ -22,6 +23,7 @@ const {
|
|
|
22
23
|
isHidden,
|
|
23
24
|
isTimeStamp,
|
|
24
25
|
isJobID,
|
|
26
|
+
isURL,
|
|
25
27
|
jobsPath,
|
|
26
28
|
logsPath,
|
|
27
29
|
reportsPath,
|
|
@@ -198,7 +200,7 @@ const requestHandler = async (request, response) => {
|
|
|
198
200
|
// Serve response headers, including one allowing requests from other applications.
|
|
199
201
|
response.setHeader('Access-Control-Allow-Origin', '*');
|
|
200
202
|
response.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
|
|
201
|
-
response.setHeader('Access-Control-Allow-Headers', 'Content-Type');
|
|
203
|
+
response.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
|
|
202
204
|
response.statusCode = 204;
|
|
203
205
|
response.end();
|
|
204
206
|
}
|
|
@@ -568,10 +570,10 @@ const requestHandler = async (request, response) => {
|
|
|
568
570
|
// Get the segments of the path after api.
|
|
569
571
|
const segments = pathTail.split('/');
|
|
570
572
|
// If the first segment is the ID of the Testaro agent and the agent is authenticated:
|
|
571
|
-
if (
|
|
572
|
-
const agentID =
|
|
573
|
+
if (segments[0] === testaroAgent && postData.agentPW === testaroAgentPW) {
|
|
574
|
+
const agentID = segments[0];
|
|
573
575
|
// Get the requested service from the path.
|
|
574
|
-
const service =
|
|
576
|
+
const service = segments[1];
|
|
575
577
|
// If the service is job assignment:
|
|
576
578
|
if (service === 'job') {
|
|
577
579
|
let clean = true;
|
|
@@ -678,6 +680,41 @@ const requestHandler = async (request, response) => {
|
|
|
678
680
|
);
|
|
679
681
|
}
|
|
680
682
|
}
|
|
683
|
+
// Otherwise, if the first segment is the test recommendation service:
|
|
684
|
+
else if (segments[0] === 'testRecForm') {
|
|
685
|
+
const {what, url, why} = postData;
|
|
686
|
+
const logs = await getLogs();
|
|
687
|
+
const whats = logs.map(log => log.what);
|
|
688
|
+
const urls = logs.map(log => log.url);
|
|
689
|
+
// If the payload is a valid test recommendation:
|
|
690
|
+
if (what && isURL(url) && why) {
|
|
691
|
+
// If an available report has the same URL or the same page description:
|
|
692
|
+
if (whats.includes(what) || urls.includes(url)) {
|
|
693
|
+
// Report this.
|
|
694
|
+
await serveError(
|
|
695
|
+
'ERROR: A report with the same page description or URL is already available',
|
|
696
|
+
response,
|
|
697
|
+
false
|
|
698
|
+
);
|
|
699
|
+
}
|
|
700
|
+
// Otherwise, i.e. if no report on the page is available:
|
|
701
|
+
else {
|
|
702
|
+
// Process the recommendation and get the response data.
|
|
703
|
+
const responseData = await require(path.join(__dirname, 'testRecForm', 'api'))
|
|
704
|
+
.response(what, url, why);
|
|
705
|
+
// Send them.
|
|
706
|
+
setHeaders('application/json', null, 'high');
|
|
707
|
+
response.end(JSON.stringify(responseData));
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
// Otherwise, i.e. if the request is invalid:
|
|
712
|
+
else {
|
|
713
|
+
// Report this.
|
|
714
|
+
await serveError(
|
|
715
|
+
{message: 'ERROR: Invalid API request'}, response, false
|
|
716
|
+
);
|
|
717
|
+
}
|
|
681
718
|
}
|
|
682
719
|
// Otherwise, if it is a tutorial comment:
|
|
683
720
|
else if (pageName === 'tutorialComment.html') {
|
package/llms-full.txt
CHANGED
|
@@ -13,6 +13,7 @@ An LLM cannot produce for an AI agent thorough, accurate, and inexpensive inform
|
|
|
13
13
|
- selects, as tools, an ensemble of 10 rule engines that implement tests for, in total, more than a thousand rules for front-end quality
|
|
14
14
|
- runs the tests of the rule engines
|
|
15
15
|
- combines the reports of the rule engines into a single integrated report
|
|
16
|
+
- consolidates the 1000+ rules having 10 different naming systems into 300+ “issues” with a uniform naming system
|
|
16
17
|
- extracts from the report statistics and details at the level of granularity required by an agent to fulfill any particular request
|
|
17
18
|
|
|
18
19
|
## How Kilotest integrates methods
|
|
@@ -30,11 +31,11 @@ LLMs that attempt to evaluate front-end quality with no delegation are likely to
|
|
|
30
31
|
|
|
31
32
|
## Kilotest versus other tools
|
|
32
33
|
|
|
33
|
-
In the marketplace for
|
|
34
|
+
In the marketplace for MCP servers that test for front-end quality, all tools other than Kilotest leverage at most 1 rule engine, most often `axe-core`. Kilotest leverages `axe-core` plus 9 other rule engines. This has these main effects:
|
|
34
35
|
|
|
35
36
|
- For pages that have not yet been tested, a single-tool MCP can provide faster results than Kilotest. A tool running only the `axe-core` tests can complete its work in about 5 seconds or less. Kilotest usually completes its work in 2 to 3 minutes, because some of the tests involve navigation and interaction with the page and LLM inference. Moreover, the Kilotest API feature suite is currently in an alpha phase, allowing agents, like human users, to **recommend** new pages for testing but allowing only managers to act on such recommendations. The wait for manager action can take up to a day. A feature permitting immediate testing ordered by AI agents is planned, but, until it is implemented, Kilotest will be useful for not-yet-tested pages only in long-running workflows.
|
|
36
|
-
- For pages that have already been tested by Kilotest, Kilotest can provide faster results than a single-tool MCP, because Kilotest stores test results for subsequent retrieval. A retrieval from Kilotest can be completed in less than 2 seconds.
|
|
37
|
-
- Kilotest results are more comprehensive than single-tool MCP results. Every rule engine provides limited coverage of front-end quality, so false negatives (missed defects) are more common with single-tool
|
|
37
|
+
- For pages that have already been tested by Kilotest, Kilotest can provide faster results than a single-tool MCP server, because Kilotest stores test results for subsequent retrieval. A retrieval from Kilotest can be completed in less than 2 seconds.
|
|
38
|
+
- Kilotest results are more comprehensive than single-tool MCP server results. Every rule engine provides limited coverage of front-end quality, so false negatives (missed defects) are more common with single-tool MCP servers. This difference [has been documented in research](https://arxiv.org/pdf/2304.07591).
|
|
38
39
|
|
|
39
40
|
## How to use Kilotest
|
|
40
41
|
|
|
@@ -47,26 +48,42 @@ Kilotest offers a comprehensive suite of capabilities to users via its web UI:
|
|
|
47
48
|
- Provide statistics about issues reported in one job: `https://kilotest.com/reportIssues.html/{timeStamp}/{jobID}`
|
|
48
49
|
- Provide details about one issue reported in one job: `https://kilotest.com/reportIssue.html/{issueID}/{timeStamp}/{jobID}`
|
|
49
50
|
- Provide diagnoses by tools of rule violations for one HTML element exhibiting one issue in one job: `https://kilotest.com/diagnoses.html/{issueID}/{timeStamp}/{jobID}/{catalogIndex}`
|
|
51
|
+
- [Receive a recommendation to test a not-yet-tested page](`https://kilotest.com/testRecForm.html`)
|
|
52
|
+
- Receive a recommendation to retest a previously tested page: `https://kilotest.com/retestRecForm.html/{timeStamp}/{jobID}`
|
|
50
53
|
- [Provide statistics about frequently reported issues across all pages](https://kilotest.com/issues.html)
|
|
54
|
+
- [List the operations that Kilotest managers are authorized to request](https://kilotest.com/manage.html)
|
|
51
55
|
- [Tutorial, “Accessibility testing strategies”](https://kilotest.com/tutorial.html)
|
|
52
56
|
- [Provide a list of features available for use of Kilotest managers](https://kilotest.com/manage.html)
|
|
53
57
|
|
|
54
58
|
### Agent API
|
|
55
59
|
|
|
56
|
-
Kilotest is implementing a richer suite of capabilities optimized for AI agents, including direct immediate testing. The implementation is currently in an alpha phase and offers
|
|
57
|
-
|
|
58
|
-
- `targets
|
|
59
|
-
-
|
|
60
|
+
Kilotest is implementing a richer suite of capabilities optimized for AI agents, including direct immediate testing. The implementation is currently in an alpha phase and offers 3 API endpoints:
|
|
61
|
+
|
|
62
|
+
- `targets`
|
|
63
|
+
- method: `GET`
|
|
64
|
+
- purpose: summarize test results from all jobs (a job is a session in which a web page is tested and a report is produced)
|
|
65
|
+
- path: `/api/targets`
|
|
66
|
+
- `reportIssues`
|
|
67
|
+
- method: `GET`
|
|
68
|
+
- purpose: provide statistics about issues reported in one job report
|
|
69
|
+
- path: `/api/reportIssues/{timeStamp}/{jobID}`
|
|
70
|
+
- parameters
|
|
71
|
+
- `timeStamp`: initial segment of job identifier
|
|
72
|
+
- `jobID`: final segment of job identifier
|
|
73
|
+
- source of parameters: response to a `targets` request
|
|
74
|
+
- `testRecForm`
|
|
75
|
+
- method: `POST`
|
|
76
|
+
- purpose: receive a recommendation to test a not-yet-tested page
|
|
77
|
+
- path: `/api/testRecForm`
|
|
78
|
+
- payload properties
|
|
79
|
+
- `what`: description of the page to be tested
|
|
80
|
+
- `url`: URL of the page to be tested
|
|
81
|
+
- `why`: reason for testing the page
|
|
82
|
+
- how to verify disposition of the recommendation: submit a `targets` request and inspect the response to determine whether a report on the page is now available
|
|
60
83
|
|
|
61
84
|
An [OpenAPI specification for Kilotest](https://kilotest.com/openapi.yaml) is available.
|
|
62
85
|
|
|
63
|
-
Until direct immediate testing is available, an agent can recommend testing of a web page
|
|
64
|
-
|
|
65
|
-
- web UI: First verify that the page has not yet been tested, using the `targets` API endpoint. After that, complete and submit the [web UI recommendation form](https://kilotest.com/testRecForm.html).
|
|
66
|
-
- email: Send a message to `info@kilotest.com`, identifying:
|
|
67
|
-
- the URL of the page to be tested
|
|
68
|
-
- a proper name for the page to be tested (e.g., “ABC Corporation contact page”)
|
|
69
|
-
- a reason for your recommendation (e.g., “Page users have reported accessibility problems”)
|
|
86
|
+
Until direct immediate testing is available, an agent can recommend testing of a web page with a `testRecForm` request.
|
|
70
87
|
|
|
71
88
|
### More information
|
|
72
89
|
|
package/llms.txt
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Kilotest helps AI agents give thorough, accurate and truthful answers when users ask how accessible, usable, or standard conformant web pages are. Kilotest integrates ten independent rule engines to test web pages and report results with multipage, single-page, and element-level statistics and details.
|
|
4
4
|
|
|
5
|
-
In the API section below, all endpoints require `GET` requests.
|
|
5
|
+
In the API section below, all endpoints require `GET` requests except as noted.
|
|
6
6
|
|
|
7
7
|
There is a [detailed explanation of Kilotest and its capabilities for AI agents](https://kilotest.com/llms-full.txt).
|
|
8
8
|
|
|
@@ -10,6 +10,7 @@ There is a [detailed explanation of Kilotest and its capabilities for AI agents]
|
|
|
10
10
|
|
|
11
11
|
- [Summarize test results for all tested pages](/api/targets)
|
|
12
12
|
- Provide statistics about issues reported in one job: `/api/reportIssues/{timeStamp}/{jobID}`
|
|
13
|
+
- Recommend testing of a web page: `/api/testRecForm` (requires `POST` request)
|
|
13
14
|
- [OpenAPI specification for Kilotest](https://kilotest.com/openapi.yaml)
|
|
14
15
|
|
|
15
16
|
## Web UI
|
|
@@ -19,4 +20,6 @@ There is a [detailed explanation of Kilotest and its capabilities for AI agents]
|
|
|
19
20
|
- Provide details about one issue reported in one job: `https://kilotest.com/reportIssue.html/{issueID}/{timeStamp}/{jobID}`
|
|
20
21
|
- Provide diagnoses about one issue exhibited by one HTML element in one job: `https://kilotest.com/diagnoses.html/{issueID}/{timeStamp}/{jobID}/{catalogIndex}`
|
|
21
22
|
- [Provide statistics about frequently reported issues across all pages](https://kilotest.com/issues.html)
|
|
23
|
+
- [Recommend testing of a web page](https://kilotest.com/testRecForm.html)
|
|
24
|
+
- [List the operations that Kilotest managers are authorized to request](https://kilotest.com/manage.html)
|
|
22
25
|
- [Tutorial, “Accessibility testing strategies”](https://kilotest.com/tutorial.html)
|
package/openapi.yaml
CHANGED
|
@@ -1,22 +1,42 @@
|
|
|
1
1
|
openapi: 3.1.0
|
|
2
2
|
info:
|
|
3
3
|
title: Kilotest Agent API
|
|
4
|
-
description: Kilotest tests web pages for accessibility, usability, and standard conformity using an ensemble of ten independent tools that employ rule-based and machine-learning-based methods. This API enables AI agents to recommend web pages for testing
|
|
4
|
+
description: Kilotest tests web pages for accessibility, usability, and standard conformity using an ensemble of ten independent tools that employ rule-based and machine-learning-based methods. This API enables AI agents to recommend web pages for testing, discover available test reports, and retrieve data from reports. For background on Kilotest and the advantages of ensemble testing, visit https://kilotest.com.
|
|
5
5
|
version: 1.0.0
|
|
6
6
|
contact:
|
|
7
|
+
name: Kilotest
|
|
7
8
|
url: https://kilotest.com
|
|
8
9
|
email: info@kilotest.com
|
|
9
|
-
repository: https://github.com/jrpool/kilotest
|
|
10
10
|
|
|
11
11
|
servers:
|
|
12
12
|
- url: https://kilotest.com
|
|
13
13
|
description: Kilotest production server
|
|
14
14
|
|
|
15
15
|
paths:
|
|
16
|
-
/api/
|
|
16
|
+
/api/testRecForm:
|
|
17
17
|
post:
|
|
18
|
-
operationId:
|
|
19
|
-
summary:
|
|
18
|
+
operationId: testRecForm
|
|
19
|
+
summary: Receives a testing recommendation
|
|
20
|
+
description: Receives a recommendation for Kilotest to test a particular web page.
|
|
21
|
+
requestBody:
|
|
22
|
+
description: Test recommendation specifications
|
|
23
|
+
required: true
|
|
24
|
+
content:
|
|
25
|
+
application/json:
|
|
26
|
+
schema:
|
|
27
|
+
$ref: '#/components/schemas/TestRecForm'
|
|
28
|
+
responses:
|
|
29
|
+
'200':
|
|
30
|
+
description: Acknowledgement of test recommendation
|
|
31
|
+
content:
|
|
32
|
+
application/json:
|
|
33
|
+
schema:
|
|
34
|
+
$ref: '#/components/schemas/TestRecFormResponse'
|
|
35
|
+
|
|
36
|
+
/api/targets:
|
|
37
|
+
get:
|
|
38
|
+
operationId: targets
|
|
39
|
+
summary: Summarizes all available reports
|
|
20
40
|
description: Returns summary data about every non-hidden report available from Kilotest, including the name and URL of the tested web page, when the testing was performed, how many issues were reported, and URLs for retrieving more detailed data from the report.
|
|
21
41
|
responses:
|
|
22
42
|
'200':
|
|
@@ -24,13 +44,13 @@ paths:
|
|
|
24
44
|
content:
|
|
25
45
|
application/json:
|
|
26
46
|
schema:
|
|
27
|
-
$ref: '#/components/schemas/
|
|
47
|
+
$ref: '#/components/schemas/TargetsResponse'
|
|
28
48
|
|
|
29
49
|
/api/reportIssues/{timeStamp}/{jobID}:
|
|
30
|
-
|
|
50
|
+
get:
|
|
31
51
|
operationId: getReportIssues
|
|
32
|
-
summary:
|
|
33
|
-
description: Returns data about the issues reported in a specific Kilotest report, grouped by priority. The data on each issue include the tools that reported it, the number of HTML elements exhibiting it, and URLs for retrieving element-level detail. The timeStamp and jobID components identify the report and are available in the
|
|
52
|
+
summary: Gets data on issues from a specific report
|
|
53
|
+
description: Returns data about the issues reported in a specific Kilotest report, grouped by priority. The data on each issue include the tools that reported it, the number of HTML elements exhibiting it, and URLs for retrieving element-level detail. The timeStamp and jobID components identify the report and are available in the targets response.
|
|
34
54
|
parameters:
|
|
35
55
|
- name: timeStamp
|
|
36
56
|
in: path
|
|
@@ -39,14 +59,16 @@ paths:
|
|
|
39
59
|
schema:
|
|
40
60
|
type: string
|
|
41
61
|
pattern: '^\d{6}T\d{4}$'
|
|
42
|
-
|
|
62
|
+
examples:
|
|
63
|
+
- 260503T0432
|
|
43
64
|
- name: jobID
|
|
44
65
|
in: path
|
|
45
66
|
required: true
|
|
46
67
|
description: Job identifier component of the report identifier (e.g., xx0).
|
|
47
68
|
schema:
|
|
48
69
|
type: string
|
|
49
|
-
|
|
70
|
+
examples:
|
|
71
|
+
- xx0
|
|
50
72
|
responses:
|
|
51
73
|
'200':
|
|
52
74
|
description: Data on issues from the specified report
|
|
@@ -58,9 +80,9 @@ paths:
|
|
|
58
80
|
description: No report with the specified identifier is available
|
|
59
81
|
|
|
60
82
|
/api/reportIssue/{issueID}/{timeStamp}/{jobID}:
|
|
61
|
-
|
|
83
|
+
get:
|
|
62
84
|
operationId: getReportIssue
|
|
63
|
-
summary:
|
|
85
|
+
summary: Gets details about a specific issue in a specific report (NOT YET IMPLEMENTED)
|
|
64
86
|
description: Returns details about a single issue within a specific report, including which HTML elements exhibit the issue and, for each such element, URLs for retrieving tool-by-tool diagnoses of the issue on the element. NOT YET IMPLEMENTED.
|
|
65
87
|
parameters:
|
|
66
88
|
- name: issueID
|
|
@@ -69,7 +91,8 @@ paths:
|
|
|
69
91
|
description: Issue identifier (e.g., imageNoText). Available under "issues reported" > priority level > "identifier" in the getReportIssues response.
|
|
70
92
|
schema:
|
|
71
93
|
type: string
|
|
72
|
-
|
|
94
|
+
examples:
|
|
95
|
+
- imageNoText
|
|
73
96
|
- name: timeStamp
|
|
74
97
|
in: path
|
|
75
98
|
required: true
|
|
@@ -101,26 +124,47 @@ components:
|
|
|
101
124
|
description: Natural-language description of this response and of Kilotest. Provides context for an agent encountering Kilotest for the first time.
|
|
102
125
|
tool name:
|
|
103
126
|
type: string
|
|
104
|
-
|
|
127
|
+
examples:
|
|
128
|
+
- Kilotest
|
|
105
129
|
request:
|
|
106
130
|
type: object
|
|
107
131
|
properties:
|
|
108
|
-
|
|
132
|
+
type of request:
|
|
109
133
|
type: object
|
|
110
134
|
properties:
|
|
111
135
|
identifier:
|
|
112
136
|
type: string
|
|
113
|
-
|
|
114
|
-
name:
|
|
137
|
+
description:
|
|
115
138
|
type: string
|
|
116
|
-
|
|
117
|
-
|
|
139
|
+
method:
|
|
140
|
+
type: string
|
|
141
|
+
enum:
|
|
142
|
+
- GET
|
|
143
|
+
- POST
|
|
144
|
+
payload:
|
|
145
|
+
type: object
|
|
146
|
+
description: Present only for POST requests. The request payload.
|
|
147
|
+
URLs:
|
|
118
148
|
type: object
|
|
119
149
|
properties:
|
|
120
|
-
|
|
150
|
+
'URL of your request':
|
|
121
151
|
type: string
|
|
122
|
-
|
|
152
|
+
'equivalent URL for humans':
|
|
123
153
|
type: string
|
|
154
|
+
closest ancestor request:
|
|
155
|
+
oneOf:
|
|
156
|
+
- type: 'null'
|
|
157
|
+
- type: object
|
|
158
|
+
properties:
|
|
159
|
+
description:
|
|
160
|
+
type: string
|
|
161
|
+
URLs:
|
|
162
|
+
type: object
|
|
163
|
+
properties:
|
|
164
|
+
'for you':
|
|
165
|
+
type: string
|
|
166
|
+
'for humans':
|
|
167
|
+
type: string
|
|
124
168
|
response metadata:
|
|
125
169
|
type: object
|
|
126
170
|
properties:
|
|
@@ -131,6 +175,22 @@ components:
|
|
|
131
175
|
type: string
|
|
132
176
|
format: date-time
|
|
133
177
|
|
|
178
|
+
TestRecForm:
|
|
179
|
+
type: object
|
|
180
|
+
properties:
|
|
181
|
+
what:
|
|
182
|
+
type: string
|
|
183
|
+
description: Description of the web page to be tested.
|
|
184
|
+
url:
|
|
185
|
+
type: string
|
|
186
|
+
description: URL of the web page to be tested.
|
|
187
|
+
why:
|
|
188
|
+
type: string
|
|
189
|
+
description: Reason for testing the page.
|
|
190
|
+
|
|
191
|
+
TestRecFormResponse:
|
|
192
|
+
$ref: '#/components/schemas/CommonResponseFields'
|
|
193
|
+
|
|
134
194
|
ToolInfo:
|
|
135
195
|
type: object
|
|
136
196
|
description: An accessibility testing tool in the Kilotest ensemble.
|
|
@@ -138,15 +198,18 @@ components:
|
|
|
138
198
|
identifier:
|
|
139
199
|
type: string
|
|
140
200
|
description: Short programmatic identifier for the tool.
|
|
141
|
-
|
|
201
|
+
examples:
|
|
202
|
+
- alfa
|
|
142
203
|
name:
|
|
143
204
|
type: string
|
|
144
205
|
description: Display name of the tool.
|
|
145
|
-
|
|
206
|
+
examples:
|
|
207
|
+
- Alfa
|
|
146
208
|
sponsor:
|
|
147
209
|
type: string
|
|
148
|
-
description: Organization that created or sponsors the tool.
|
|
149
|
-
|
|
210
|
+
description: Organization that created, initially sponsored, or now sponsors the tool.
|
|
211
|
+
examples:
|
|
212
|
+
- Siteimprove
|
|
150
213
|
|
|
151
214
|
ToolFailure:
|
|
152
215
|
type: object
|
|
@@ -154,10 +217,12 @@ components:
|
|
|
154
217
|
properties:
|
|
155
218
|
name:
|
|
156
219
|
type: string
|
|
157
|
-
|
|
220
|
+
examples:
|
|
221
|
+
- WAVE
|
|
158
222
|
reason for failure:
|
|
159
223
|
type: string
|
|
160
|
-
|
|
224
|
+
examples:
|
|
225
|
+
- Not enough credits.
|
|
161
226
|
|
|
162
227
|
ToolsSummary:
|
|
163
228
|
type: object
|
|
@@ -183,13 +248,14 @@ components:
|
|
|
183
248
|
format: uri
|
|
184
249
|
description: URL for a human to view the next tier of detail.
|
|
185
250
|
|
|
186
|
-
|
|
251
|
+
TargetsItem:
|
|
187
252
|
type: object
|
|
188
253
|
description: Summary data about a single available report.
|
|
189
254
|
properties:
|
|
190
255
|
identifier:
|
|
191
256
|
type: string
|
|
192
|
-
|
|
257
|
+
examples:
|
|
258
|
+
- 260504T1659-029
|
|
193
259
|
creation date:
|
|
194
260
|
type: string
|
|
195
261
|
format: date-time
|
|
@@ -222,7 +288,7 @@ components:
|
|
|
222
288
|
type: string
|
|
223
289
|
format: uri
|
|
224
290
|
|
|
225
|
-
|
|
291
|
+
TargetsResponse:
|
|
226
292
|
allOf:
|
|
227
293
|
- $ref: '#/components/schemas/CommonResponseFields'
|
|
228
294
|
- type: object
|
|
@@ -231,7 +297,7 @@ components:
|
|
|
231
297
|
type: array
|
|
232
298
|
description: One entry per available Kilotest report, in alphabetical order by page description and, in case of multiple reports per page, in order of creation date and time. Reports are matched by page description, not page URL, so, if only the URL of a page has changed between reports, the reports are treated as reports about the same page.
|
|
233
299
|
items:
|
|
234
|
-
$ref: '#/components/schemas/
|
|
300
|
+
$ref: '#/components/schemas/TargetsItem'
|
|
235
301
|
|
|
236
302
|
IssueEntry:
|
|
237
303
|
type: object
|
|
@@ -239,22 +305,27 @@ components:
|
|
|
239
305
|
properties:
|
|
240
306
|
identifier:
|
|
241
307
|
type: string
|
|
242
|
-
|
|
308
|
+
examples:
|
|
309
|
+
- imageNoText
|
|
243
310
|
summary:
|
|
244
311
|
type: string
|
|
245
312
|
description: Brief natural-language label for the issue.
|
|
246
|
-
|
|
313
|
+
examples:
|
|
314
|
+
- image not named
|
|
247
315
|
related WCAG 2.2 standard:
|
|
248
316
|
type: object
|
|
249
317
|
description: The WCAG 2.2 success criterion or guideline most closely related to this issue.
|
|
250
318
|
properties:
|
|
251
319
|
layer:
|
|
252
320
|
type: string
|
|
253
|
-
enum:
|
|
321
|
+
enum:
|
|
322
|
+
- guideline
|
|
323
|
+
- success criterion
|
|
254
324
|
'numeric identifier':
|
|
255
325
|
type: string
|
|
256
326
|
pattern: '^\d\.\d(\.\d+)?$'
|
|
257
|
-
|
|
327
|
+
examples:
|
|
328
|
+
- 1.1.1
|
|
258
329
|
impact on a user:
|
|
259
330
|
type: string
|
|
260
331
|
description: How this issue is likely to affect users.
|
package/package.json
CHANGED
package/reportIssues/api.js
CHANGED
|
@@ -62,7 +62,7 @@ exports.response = async args => {
|
|
|
62
62
|
}));
|
|
63
63
|
const thisHost = process.env.THIS_KILOTEST_HOST;
|
|
64
64
|
// Get a response.
|
|
65
|
-
const
|
|
65
|
+
const content = {
|
|
66
66
|
summary: `This document fulfills a request made by an agent to the Kilotest service. The agent requested data from a Kilotest report about the accessibility, usability, and standard-conformity of a web page. Kilotest, with the help of Testaro, Testilo, and an ensemble of ten testing tools, performs tests on web pages, using a combination of rule- and machine-learning-based methods, and produces reports. Kilotest exposes several API endpoints for agents and several web UI URLs for humans to obtain information from Kilotest reports. To learn more about Kilotest and the advangages of testing with an ensemble of tools, visit the deployed instance of Kilotest (${process.env.DEPLOYED_KILOTEST_HOST}), which contains an introduction on its home page and a tutorial.`,
|
|
67
67
|
'tool name': 'Kilotest',
|
|
68
68
|
request: {
|
|
@@ -70,6 +70,7 @@ exports.response = async args => {
|
|
|
70
70
|
identifier: 'reportIssues',
|
|
71
71
|
description: 'What issues does the specified report describe?'
|
|
72
72
|
},
|
|
73
|
+
method: 'GET',
|
|
73
74
|
URLs: {
|
|
74
75
|
'URL of your request': `${thisHost}/api/reportIssues/${timeStamp}/${jobID}`,
|
|
75
76
|
'equivalent URL for humans': `${thisHost}/reportIssues.html/${timeStamp}/${jobID}`
|
|
@@ -122,5 +123,5 @@ exports.response = async args => {
|
|
|
122
123
|
.map(issue => getIssueFacts(thisHost, timeStamp, jobID, issue))
|
|
123
124
|
}
|
|
124
125
|
};
|
|
125
|
-
return
|
|
126
|
+
return content;
|
|
126
127
|
};
|
package/researchAgent.js
CHANGED
|
@@ -30,11 +30,11 @@ const port = hostParts[2] || (scheme === 'https' ? 443 : 80);
|
|
|
30
30
|
|
|
31
31
|
// FUNCTIONS
|
|
32
32
|
|
|
33
|
-
// Submits
|
|
33
|
+
// Submits three request to a random Kilotest host.
|
|
34
34
|
const requestService = async () => {
|
|
35
35
|
const client = scheme === 'https' ? httpsClient : httpClient;
|
|
36
|
-
const getRequestOptions = path => ({
|
|
37
|
-
method
|
|
36
|
+
const getRequestOptions = (path, method = 'GET') => ({
|
|
37
|
+
method,
|
|
38
38
|
host,
|
|
39
39
|
port,
|
|
40
40
|
path,
|
|
@@ -43,6 +43,7 @@ const requestService = async () => {
|
|
|
43
43
|
}
|
|
44
44
|
});
|
|
45
45
|
const path = `/api/targets`;
|
|
46
|
+
console.log('======================');
|
|
46
47
|
console.log(`About to submit ${scheme} request as JSON on port ${port} to ${host}${path}`);
|
|
47
48
|
// Submit a targets request.
|
|
48
49
|
client.request(getRequestOptions(path), response => {
|
|
@@ -65,15 +66,14 @@ const requestService = async () => {
|
|
|
65
66
|
try {
|
|
66
67
|
// Output it.
|
|
67
68
|
const contentObj = JSON.parse(content);
|
|
68
|
-
console.log('======================');
|
|
69
69
|
console.log(JSON.stringify(contentObj, null, 2));
|
|
70
70
|
// Get the IDs of the available reports.
|
|
71
71
|
const reportIDs = contentObj['available reports'].map(report => report.identifier);
|
|
72
72
|
// Choose one at random.
|
|
73
73
|
const [timeStamp, jobID] = reportIDs[Math.floor(Math.random() * reportIDs.length)]
|
|
74
74
|
.split('-');
|
|
75
|
-
console.log('======================');
|
|
76
75
|
const path = `/api/reportIssues/${timeStamp}/${jobID}`;
|
|
76
|
+
console.log('======================');
|
|
77
77
|
console.log(`About to submit ${scheme} request as JSON on port ${port} to ${host}${path}`);
|
|
78
78
|
const requestOptions = getRequestOptions(path);
|
|
79
79
|
// Submit an issues request for it.
|
|
@@ -98,7 +98,47 @@ const requestService = async () => {
|
|
|
98
98
|
// Output it.
|
|
99
99
|
const contentObj = JSON.parse(content);
|
|
100
100
|
console.log(JSON.stringify(contentObj, null, 2));
|
|
101
|
+
const testRecPath = `/api/testRecForm`;
|
|
101
102
|
console.log('======================');
|
|
103
|
+
console.log(
|
|
104
|
+
`About to submit ${scheme} POST request as JSON on port ${port} to ${host}${testRecPath}`
|
|
105
|
+
);
|
|
106
|
+
const testRecOptions = getRequestOptions(testRecPath, 'POST');
|
|
107
|
+
// Submit a test recommendation.
|
|
108
|
+
client.request(testRecOptions, response => {
|
|
109
|
+
// Initialize a collection of data from the response.
|
|
110
|
+
const chunks = [];
|
|
111
|
+
response
|
|
112
|
+
// If the response throws an error:
|
|
113
|
+
.on('error', async error => {
|
|
114
|
+
// Report it.
|
|
115
|
+
console.log(error.message);
|
|
116
|
+
})
|
|
117
|
+
// If the response delivers data:
|
|
118
|
+
.on('data', chunk => {
|
|
119
|
+
// Add them to the collection.
|
|
120
|
+
chunks.push(chunk);
|
|
121
|
+
})
|
|
122
|
+
// When the response is completed:
|
|
123
|
+
.on('end', async () => {
|
|
124
|
+
const content = chunks.join('');
|
|
125
|
+
try {
|
|
126
|
+
// Output it.
|
|
127
|
+
const contentObj = JSON.parse(content);
|
|
128
|
+
console.log(JSON.stringify(contentObj, null, 2));
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
console.log(error.message);
|
|
132
|
+
console.log(`Test recommendation response content: ${content || 'No content'}`);
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
})
|
|
136
|
+
// Finish sending the test recommendation request.
|
|
137
|
+
.end(JSON.stringify({
|
|
138
|
+
what: 'Page Not Already Tested',
|
|
139
|
+
url: 'https://pagenotalreadytested.info',
|
|
140
|
+
why: 'This is only a test'
|
|
141
|
+
}));
|
|
102
142
|
}
|
|
103
143
|
catch (error) {
|
|
104
144
|
console.log(error.message);
|
package/sitemap.xml
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
<url><loc>https://kilotest.com/</loc></url>
|
|
4
4
|
<url><loc>https://kilotest.com/targets.html</loc></url>
|
|
5
5
|
<url><loc>https://kilotest.com/issues.html</loc></url>
|
|
6
|
+
<url><loc>https://kilotest.com/testRecForm.html</loc></url>
|
|
7
|
+
<url><loc>https://kilotest.com/manage.html</loc></url>
|
|
6
8
|
<url><loc>https://kilotest.com/tutorial.html</loc></url>
|
|
7
9
|
<url><loc>https://kilotest.com/openapi.yaml</loc></url>
|
|
8
10
|
<url><loc>https://kilotest.com/llms.txt</loc></url>
|
package/targets/api.js
CHANGED
|
@@ -82,10 +82,12 @@ exports.response = async () => {
|
|
|
82
82
|
identifier: 'targets',
|
|
83
83
|
description: 'Give me summary data about each available report.'
|
|
84
84
|
},
|
|
85
|
+
method: 'GET',
|
|
85
86
|
URLs: {
|
|
86
87
|
'URL of your request': `${thisHost}/api/targets`,
|
|
87
88
|
'equivalent URL for humans': `${thisHost}/targets.html`
|
|
88
|
-
}
|
|
89
|
+
},
|
|
90
|
+
'closest ancestor request': null
|
|
89
91
|
},
|
|
90
92
|
'response metadata': {
|
|
91
93
|
identifier: `${getNowStamp()}-${getRandomString(3)}`,
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/*
|
|
2
|
+
api.js
|
|
3
|
+
Responds to the test-recommendation request.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// IMPORTS
|
|
7
|
+
|
|
8
|
+
const {
|
|
9
|
+
getNowStamp,
|
|
10
|
+
getRandomString,
|
|
11
|
+
updateRecs
|
|
12
|
+
} = require('../util');
|
|
13
|
+
|
|
14
|
+
// FUNCTIONS
|
|
15
|
+
|
|
16
|
+
// Returns a response to a test-recommendation request.
|
|
17
|
+
exports.response = async (what, url, why) => {
|
|
18
|
+
const thisHost = process.env.THIS_KILOTEST_HOST;
|
|
19
|
+
// Record the recommendation.
|
|
20
|
+
await updateRecs(what, url, why);
|
|
21
|
+
// Get a response.
|
|
22
|
+
const content = {
|
|
23
|
+
summary: `This response acknowledges a request made by an agent to the Kilotest service. The agent recommended that Kilotest test the ${what} web page at ${url} for accessibility, usability, and standard-conformity. A Kilotest manager usually approves a recommendation within a day. When the recommendation is approved, the testing will be performed and results will become available. You can check for the availability of the results at ${thisHost}/api/targets. Kilotest performs its testing with the help of Testaro, Testilo, and an ensemble of ten testing tools, using a combination of rule- and machine-learning-based methods. Kilotest exposes several API endpoints for agents and several web UI URLs for humans to obtain information from Kilotest reports. To learn more about Kilotest and the advangages of testing with an ensemble of tools, visit the deployed instance of Kilotest (${process.env.DEPLOYED_KILOTEST_HOST}), which contains an introduction on its home page and a tutorial.`,
|
|
24
|
+
'tool name': 'Kilotest',
|
|
25
|
+
request: {
|
|
26
|
+
'type of request': {
|
|
27
|
+
identifier: 'testRecForm',
|
|
28
|
+
description: 'I recommend that Kilotest test a particular web page.'
|
|
29
|
+
},
|
|
30
|
+
method: 'POST',
|
|
31
|
+
payload: {
|
|
32
|
+
'description of the web page': what,
|
|
33
|
+
'URL of the web page': url,
|
|
34
|
+
'reason for testing the web page': why
|
|
35
|
+
},
|
|
36
|
+
URLs: {
|
|
37
|
+
'URL of your request': `${thisHost}/api/testRecForm`,
|
|
38
|
+
'equivalent URL for humans': `${thisHost}/testRecForm.html`
|
|
39
|
+
},
|
|
40
|
+
'closest ancestor request': null
|
|
41
|
+
},
|
|
42
|
+
'response metadata': {
|
|
43
|
+
identifier: `${getNowStamp()}-${getRandomString(3)}`,
|
|
44
|
+
'date and time': new Date().toISOString()
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
return content;
|
|
48
|
+
};
|
package/util.js
CHANGED
|
@@ -626,6 +626,20 @@ const getPlainText = string => string.replace(/&/g, '+').replace(/[<>"'&]/g, ' '
|
|
|
626
626
|
const getNowStamp = exports.getNowStamp = () => {
|
|
627
627
|
return getTimeStamp(new Date());
|
|
628
628
|
};
|
|
629
|
+
// Updates the test recommendations.
|
|
630
|
+
const updateRecs = exports.updateRecs = async (what, url, why) => {
|
|
631
|
+
// Get the data on waiting recommendations.
|
|
632
|
+
const recs = await getRecs();
|
|
633
|
+
recs[url] ??= [];
|
|
634
|
+
// Add the recommendation to those for the target.
|
|
635
|
+
recs[url].push({
|
|
636
|
+
timeStamp: getNowStamp(),
|
|
637
|
+
what,
|
|
638
|
+
why
|
|
639
|
+
});
|
|
640
|
+
// Save the revised recommendations.
|
|
641
|
+
await fs.writeFile(recsPath, getJSON(recs));
|
|
642
|
+
};
|
|
629
643
|
// Processes a test or retest recommendation.
|
|
630
644
|
exports.processRec = async (testType, dirName, what, url, why) => {
|
|
631
645
|
// If the recommendation is valid:
|
|
@@ -638,17 +652,8 @@ exports.processRec = async (testType, dirName, what, url, why) => {
|
|
|
638
652
|
) {
|
|
639
653
|
// Make the reason display-safe.
|
|
640
654
|
const plainWhy = getPlainText(why);
|
|
641
|
-
//
|
|
642
|
-
|
|
643
|
-
recs[url] ??= [];
|
|
644
|
-
// Add the recommendation to those for the target.
|
|
645
|
-
recs[url].push({
|
|
646
|
-
timeStamp: getNowStamp(),
|
|
647
|
-
what,
|
|
648
|
-
why: plainWhy
|
|
649
|
-
});
|
|
650
|
-
// Save the revised recommendations.
|
|
651
|
-
await fs.writeFile(recsPath, getJSON(recs));
|
|
655
|
+
// Update the waiting recommendations.
|
|
656
|
+
await updateRecs(what, url, plainWhy);
|
|
652
657
|
// Log the recommendation.
|
|
653
658
|
console.log(`Test recommendation received for ${what}: ${plainWhy}`);
|
|
654
659
|
// Alert a manager about it.
|