@jrpool/kilotest 60.1.6 → 60.1.8
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/lhm.plugin.json +1 -1
- package/openapi-3.0.yaml +1 -1
- package/openapi.yaml +1 -1
- package/package.json +1 -1
- package/server.json +1 -1
- package/style.css +34 -7
- package/util.ts +17 -6
- package/web/header.partial +6 -0
- package/web/home/index.html +1 -6
- package/web/listIssues/index.html +4 -3
- package/web/listIssues/index.ts +3 -7
- package/web/listPages/index.html +1 -6
package/lhm.plugin.json
CHANGED
package/openapi-3.0.yaml
CHANGED
|
@@ -2,7 +2,7 @@ openapi: 3.0.3
|
|
|
2
2
|
info:
|
|
3
3
|
title: Kilotest API
|
|
4
4
|
description: 'Kilotest is an ensemble testing and reporting service for front-end web quality. It uses an ensemble of 12 rule engines to test web pages for front-end quality (accessibility, usability, and web standards, including HTML, CSS, ARIA, and WCAG). Kilotest acts as a web server for human users, an MCP server for AI platforms, and an API for programmatic access. With this API you can request that a page be tested or retested, discover available reports, incrementally retrieve facts from a report: from what reports are available, to what issues were reported in one report, to what elements violated one issue, to what diagnoses rule engines gave for one violation.'
|
|
5
|
-
version: 60.1.
|
|
5
|
+
version: 60.1.8
|
|
6
6
|
license:
|
|
7
7
|
name: MIT
|
|
8
8
|
url: https://github.com/jrpool/kilotest/blob/main/LICENSE
|
package/openapi.yaml
CHANGED
|
@@ -2,7 +2,7 @@ openapi: 3.1.0
|
|
|
2
2
|
info:
|
|
3
3
|
title: Kilotest API
|
|
4
4
|
description: 'Kilotest is an ensemble testing and reporting service for front-end web quality. It uses an ensemble of 12 rule engines to test web pages for front-end quality (accessibility, usability, and web standards, including HTML, CSS, ARIA, and WCAG). Kilotest acts as a web server for human users, an MCP server for AI platforms, and an API for programmatic access. With this API you can request that a page be tested or retested, discover available reports, incrementally retrieve facts from a report: from what reports are available, to what issues were reported in one report, to what elements violated one issue, to what diagnoses rule engines gave for one violation.'
|
|
5
|
-
version: 60.1.
|
|
5
|
+
version: 60.1.8
|
|
6
6
|
license:
|
|
7
7
|
name: MIT
|
|
8
8
|
identifier: MIT
|
package/package.json
CHANGED
package/server.json
CHANGED
package/style.css
CHANGED
|
@@ -244,6 +244,10 @@ body.styled h2 {
|
|
|
244
244
|
color: var(--ink);
|
|
245
245
|
font-size: 1.4rem;
|
|
246
246
|
}
|
|
247
|
+
body.styled h3 {
|
|
248
|
+
color: var(--ink);
|
|
249
|
+
font-size: 1.2rem;
|
|
250
|
+
}
|
|
247
251
|
body.styled li, body.styled p {
|
|
248
252
|
line-height: 1.6;
|
|
249
253
|
}
|
|
@@ -257,12 +261,11 @@ body.styled header {
|
|
|
257
261
|
body.styled .header-inner {
|
|
258
262
|
max-width: 64rem;
|
|
259
263
|
margin-inline: auto;
|
|
260
|
-
padding:
|
|
261
|
-
display: flex;
|
|
262
|
-
align-items: baseline;
|
|
263
|
-
gap: 0.75rem;
|
|
264
|
+
padding: 0.75rem 1.5rem;
|
|
264
265
|
}
|
|
265
266
|
body.styled .brand {
|
|
267
|
+
display: block;
|
|
268
|
+
padding-block: 0.4rem;
|
|
266
269
|
font-weight: 800;
|
|
267
270
|
font-size: 1.25rem;
|
|
268
271
|
letter-spacing: -0.02em;
|
|
@@ -282,6 +285,7 @@ body.styled .brand svg {
|
|
|
282
285
|
vertical-align: -0.2em;
|
|
283
286
|
}
|
|
284
287
|
body.styled .brand-tag {
|
|
288
|
+
margin: 0;
|
|
285
289
|
font-size: 0.85rem;
|
|
286
290
|
color: var(--muted);
|
|
287
291
|
}
|
|
@@ -318,13 +322,15 @@ body.styled .hero .lede {
|
|
|
318
322
|
color: var(--muted);
|
|
319
323
|
}
|
|
320
324
|
body.styled details {
|
|
321
|
-
max-width: 52rem;
|
|
322
325
|
margin: 0 0 1rem;
|
|
323
326
|
padding: 0;
|
|
324
327
|
background: var(--card);
|
|
325
328
|
border: 1px solid var(--line);
|
|
326
329
|
border-radius: 0.75rem;
|
|
327
330
|
}
|
|
331
|
+
body.styled .hero details {
|
|
332
|
+
max-width: 52rem;
|
|
333
|
+
}
|
|
328
334
|
body.styled summary {
|
|
329
335
|
min-height: 44px;
|
|
330
336
|
padding: 0.9rem 1.25rem;
|
|
@@ -342,10 +348,10 @@ body.styled details[open] summary {
|
|
|
342
348
|
body.styled details > :not(summary) {
|
|
343
349
|
padding-inline: 1.25rem;
|
|
344
350
|
}
|
|
345
|
-
body.styled details h2 {
|
|
351
|
+
body.styled .hero details h2 {
|
|
346
352
|
margin: 1.5rem 0 0.5rem;
|
|
347
353
|
}
|
|
348
|
-
body.styled details h3 {
|
|
354
|
+
body.styled .hero details h3 {
|
|
349
355
|
margin: 1.35rem 0 0.35rem;
|
|
350
356
|
font-size: 1.08rem;
|
|
351
357
|
}
|
|
@@ -436,3 +442,24 @@ body.styled ul.links li {
|
|
|
436
442
|
margin-bottom: 0.4rem;
|
|
437
443
|
break-inside: avoid;
|
|
438
444
|
}
|
|
445
|
+
body.styled .page h3 {
|
|
446
|
+
margin: 1.25rem 0 0.4rem;
|
|
447
|
+
}
|
|
448
|
+
body.styled .page blockquote {
|
|
449
|
+
margin: 0.75rem 0;
|
|
450
|
+
padding-left: 1rem;
|
|
451
|
+
border-left: 3px solid var(--line);
|
|
452
|
+
color: var(--muted);
|
|
453
|
+
}
|
|
454
|
+
body.styled .page ul.headed > li + li {
|
|
455
|
+
margin-top: 1.25rem;
|
|
456
|
+
padding-top: 1.25rem;
|
|
457
|
+
border-top: 1px solid var(--line);
|
|
458
|
+
}
|
|
459
|
+
body.styled .warn {
|
|
460
|
+
margin: 0 0 1rem;
|
|
461
|
+
padding: 0.6rem 0.9rem;
|
|
462
|
+
background: #fdf6e3;
|
|
463
|
+
border: 1px solid #e8d48b;
|
|
464
|
+
border-radius: 0.5rem;
|
|
465
|
+
}
|
package/util.ts
CHANGED
|
@@ -376,14 +376,23 @@ export const getPlainText = (string: string): string => string
|
|
|
376
376
|
.replace(/&/g, '+')
|
|
377
377
|
.replace(/[<>"']/g, ' ');
|
|
378
378
|
// Markup shared by populated templates, lazily read once from files.
|
|
379
|
-
let sharedContent: {head: string, logo: string} | undefined;
|
|
379
|
+
let sharedContent: {head: string, header: string, headerNL: string, logo: string} | undefined;
|
|
380
380
|
// Returns the markup shared by populated templates.
|
|
381
|
-
const getSharedContent = async (): Promise<{head: string, logo: string}> => {
|
|
381
|
+
const getSharedContent = async (): Promise<{head: string, header: string, headerNL: string, logo: string}> => {
|
|
382
382
|
// Trailing newlines are stripped so injection does not add blank lines.
|
|
383
|
-
sharedContent
|
|
384
|
-
|
|
385
|
-
logo
|
|
386
|
-
|
|
383
|
+
if (!sharedContent) {
|
|
384
|
+
const webDir = path.join(import.meta.dirname, 'web');
|
|
385
|
+
const logo = (await fs.readFile(path.join(import.meta.dirname, 'logo.svg'), 'utf8')).trimEnd();
|
|
386
|
+
const header = (await fs.readFile(path.join(webDir, 'header.partial'), 'utf8')).trimEnd()
|
|
387
|
+
.replace(/__logo__/g, () => logo);
|
|
388
|
+
sharedContent = {
|
|
389
|
+
head: (await fs.readFile(path.join(webDir, 'head.partial'), 'utf8')).trimEnd(),
|
|
390
|
+
header,
|
|
391
|
+
// The home page gets the same header with its brand as text, not a link to itself.
|
|
392
|
+
headerNL: header.replace('<a class="brand" href="/">', '<span class="brand">').replace('</a>', '</span>'),
|
|
393
|
+
logo
|
|
394
|
+
};
|
|
395
|
+
}
|
|
387
396
|
return sharedContent;
|
|
388
397
|
};
|
|
389
398
|
// Populates an HTML template file with named values.
|
|
@@ -394,6 +403,8 @@ export const populateFile = async (filePath: string, query: Record<string, strin
|
|
|
394
403
|
const shared = await getSharedContent();
|
|
395
404
|
answerPage = answerPage
|
|
396
405
|
.replace(/__head__/g, () => shared.head)
|
|
406
|
+
.replace(/__headerNL__/g, () => shared.headerNL)
|
|
407
|
+
.replace(/__header__/g, () => shared.header)
|
|
397
408
|
.replace(/__logo__/g, () => shared.logo);
|
|
398
409
|
// Replace its placeholders.
|
|
399
410
|
Object.keys(query).forEach(param => {
|
package/web/home/index.html
CHANGED
|
@@ -52,12 +52,7 @@
|
|
|
52
52
|
</script>
|
|
53
53
|
</head>
|
|
54
54
|
<body class="styled">
|
|
55
|
-
|
|
56
|
-
<div class="header-inner">
|
|
57
|
-
<span class="brand">__logo__Kilotest</span>
|
|
58
|
-
<span class="brand-tag">Ensemble front-end testing</span>
|
|
59
|
-
</div>
|
|
60
|
-
</header>
|
|
55
|
+
__headerNL__
|
|
61
56
|
<main>
|
|
62
57
|
<div class="hero">
|
|
63
58
|
<p class="eyebrow">12 rule engines · ~1,300 tests</p>
|
|
@@ -5,9 +5,10 @@
|
|
|
5
5
|
<meta name="keywords" content="report,accessibility,a11y">
|
|
6
6
|
<title>Issues reported for __target__ | Kilotest</title>
|
|
7
7
|
</head>
|
|
8
|
-
<body>
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
<body class="styled">
|
|
9
|
+
__header__
|
|
10
|
+
<main class="page">
|
|
11
|
+
<h1>Issues reported for __target__</h1>
|
|
11
12
|
__oldWarn__
|
|
12
13
|
<h2>About the tests</h2>
|
|
13
14
|
__pageFacts__
|
package/web/listIssues/index.ts
CHANGED
|
@@ -210,7 +210,7 @@ const populateQuery = async (reportID: string, query: Record<string, any>) => {
|
|
|
210
210
|
// Add a warning if the report is not the latest about the page.
|
|
211
211
|
query.oldWarn = history.isLatest
|
|
212
212
|
? ''
|
|
213
|
-
: '<p><strong>Warning: This report is not the latest about the page.</strong> See history below.</p>';
|
|
213
|
+
: '<p class="warn"><strong>Warning: This report is not the latest about the page.</strong> See history below.</p>';
|
|
214
214
|
// Add the page-facts list to the query.
|
|
215
215
|
query.pageFacts = getPageFactsLines(pageInfo, issuesData, margin).join('\n');
|
|
216
216
|
// Add the history of reports about the page to the query.
|
|
@@ -243,17 +243,13 @@ const populateQuery = async (reportID: string, query: Record<string, any>) => {
|
|
|
243
243
|
detailsLines.push(
|
|
244
244
|
...getIssueFactsLines(report, issueID, `${margin} `, 'pseudoTopLevel')
|
|
245
245
|
);
|
|
246
|
-
// Add
|
|
247
|
-
detailsLines.push(`${margin} <ul class="nav">`);
|
|
246
|
+
// Add a violations link to the lines.
|
|
248
247
|
const whereQuestionString = 'Where was the issue found?';
|
|
249
248
|
const labelString = `The ${description} page exhibits the ${summary} issue. Where was the issue found?`;
|
|
250
249
|
const href = `href="/listViolators.html/${issueID}/${reportID}"`;
|
|
251
250
|
const label = `aria-label="${labelString}"`;
|
|
252
251
|
const whereLink = `<a ${href} ${label}>${whereQuestionString}</a>`;
|
|
253
|
-
|
|
254
|
-
detailsLines.push(`${margin} <li>${whereLink}</li>`);
|
|
255
|
-
// Add the end of the link list to the lines.
|
|
256
|
-
detailsLines.push(`${margin} </ul>`);
|
|
252
|
+
detailsLines.push(`${margin} <p class="links">${whereLink}</p>`);
|
|
257
253
|
// Add the end of the list item to the lines.
|
|
258
254
|
detailsLines.push(`${margin} </li>`);
|
|
259
255
|
});
|
package/web/listPages/index.html
CHANGED
|
@@ -6,12 +6,7 @@
|
|
|
6
6
|
<title>Pages tested | Kilotest</title>
|
|
7
7
|
</head>
|
|
8
8
|
<body class="styled">
|
|
9
|
-
|
|
10
|
-
<div class="header-inner">
|
|
11
|
-
<a class="brand" href="/">__logo__<span class="brand-name">Kilotest</span></a>
|
|
12
|
-
<span class="brand-tag">Ensemble front-end testing</span>
|
|
13
|
-
</div>
|
|
14
|
-
</header>
|
|
9
|
+
__header__
|
|
15
10
|
<main class="page">
|
|
16
11
|
<h1>Pages tested</h1>
|
|
17
12
|
__jobSections__
|