@operstack/audit 0.16.0 → 0.16.2
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/src/collect.mjs +6 -5
- package/src/test-overall.mjs +22 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@operstack/audit",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.2",
|
|
4
4
|
"description": "SEO, AEO and GEO audit generator: collect public signals from a site into audit.json, let an analyst or an agent fill the narrative, render the OperStack report as HTML and PDF.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
package/src/collect.mjs
CHANGED
|
@@ -448,11 +448,6 @@ export async function collect(startUrl, { pages = 20, log = () => {}, backlinks
|
|
|
448
448
|
const msg = pagesForTrust.filter((p) => p.messengerLinks > 0);
|
|
449
449
|
checks.push(row('conv-messenger', 'conversion', 'A messenger link', msg.length ? 'ok' : 'warn', msg.length ? `on ${msg.length} of ${pagesForTrust.length} sampled page(s)` : 'none on the sampled pages', msg.length ? '' : 'for an international audience reading on a phone, one messenger link is usually worth more than a form'));
|
|
450
450
|
|
|
451
|
-
const { scores, scoreBasis } = computeScores(checks);
|
|
452
|
-
|
|
453
|
-
// Один балл на весь отчёт: его же берут страница проверки и письмо, чтобы цифры не спорили.
|
|
454
|
-
|
|
455
|
-
const overall = computeOverall(checks);
|
|
456
451
|
// Оценки считаются до перевода: язык на цифры не влияет.
|
|
457
452
|
// Сколько текста не видно без выполнения скриптов. Меряется настоящим браузером и только по
|
|
458
453
|
// просьбе: запуск браузера это десятки секунд на страницу, и еженедельному мониторингу это ни к
|
|
@@ -473,6 +468,12 @@ export async function collect(startUrl, { pages = 20, log = () => {}, backlinks
|
|
|
473
468
|
checks.push(jsBlindnessCheck(measured, lang));
|
|
474
469
|
}
|
|
475
470
|
|
|
471
|
+
// Балл считается ПОСЛЕ всех этапов, включая браузерный: раньше он снимался до него, и на прогоне
|
|
472
|
+
// с `rendered: true` сохранённое поле расходилось с тем, что печатает отчёт. Письмо говорило 61,
|
|
473
|
+
// PDF печатал 59. Одна функция, один набор проверок, один момент: вот этот.
|
|
474
|
+
const { scores, scoreBasis } = computeScores(checks);
|
|
475
|
+
const overall = computeOverall(checks);
|
|
476
|
+
|
|
476
477
|
const localised = localiseChecks(checks, lang);
|
|
477
478
|
const critical = checks.filter((c) => c.status === 'bad').map((c) => ({ title: c.label, text: `${c.value}${c.comment ? `. ${c.comment}` : ''}`, level: 'bad' }));
|
|
478
479
|
|
package/src/test-overall.mjs
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
* 44 из 60, то есть 73 процента. Два разных движка в одном документе читаются как выдуманные
|
|
6
6
|
* цифры. Эти тесты держат единственный источник балла и запрет считать неизмеренное нулём. */
|
|
7
7
|
import { readFileSync } from 'node:fs';
|
|
8
|
-
import {
|
|
8
|
+
import { createServer } from 'node:http';
|
|
9
|
+
import { collect, computeOverall, computeScores, verifyScores, SCORE_AREAS } from './collect.mjs';
|
|
9
10
|
import { toHtml } from './render.mjs';
|
|
10
11
|
|
|
11
12
|
let bad = 0;
|
|
@@ -86,5 +87,25 @@ is('все спорные: половина', computeOverall(every('warn')).scor
|
|
|
86
87
|
ok('разбивка по областям осталась под общим баллом', Object.keys(scores).every((k) => html.includes('/10') || scores[k] === null));
|
|
87
88
|
}
|
|
88
89
|
|
|
90
|
+
// Сохранённые оценки обязаны сходиться с итоговым набором проверок того же объекта.
|
|
91
|
+
//
|
|
92
|
+
// 14.09.2026 письмо сказало 61, а PDF напечатал 59: поле снималось до браузерного этапа, а он
|
|
93
|
+
// дописывает проверки. Отчёт считал заново и получал другое число. Тест поднимает маленький сайт
|
|
94
|
+
// и сверяет то, что collect положил в объект, с тем, что даёт функция по его же checks.
|
|
95
|
+
{
|
|
96
|
+
const server = createServer((req, res) => {
|
|
97
|
+
if (req.url === '/robots.txt') return res.end('User-agent: *\nAllow: /\nSitemap: http://127.0.0.1:' + server.address().port + '/sitemap.xml');
|
|
98
|
+
if (req.url === '/sitemap.xml') { res.setHeader('content-type', 'application/xml'); return res.end(`<?xml version="1.0"?><urlset><url><loc>http://127.0.0.1:${server.address().port}/</loc></url></urlset>`); }
|
|
99
|
+
res.setHeader('content-type', 'text/html');
|
|
100
|
+
res.end('<!doctype html><html><head><title>A small test page for the audit collector</title><meta name="description" content="A page that exists only so the collector has something real to read during the test run of the suite."></head><body><h1>Test page</h1><p>Ten pounds a month, measured on our own invoices in 2026.</p><h2>One</h2><p>Text.</p><h2>Two</h2><p>Text.</p><h2>Three</h2><p>Text.</p><a href="mailto:a@b.c">write</a></body></html>');
|
|
101
|
+
});
|
|
102
|
+
await new Promise((r) => server.listen(0, '127.0.0.1', r));
|
|
103
|
+
const audit = await collect(`http://127.0.0.1:${server.address().port}/`, { pages: 2, log: () => {} });
|
|
104
|
+
server.close();
|
|
105
|
+
is('сохранённый общий балл равен пересчитанному по тем же проверкам', audit.overall.score, computeOverall(audit.checks).score);
|
|
106
|
+
is('сохранённые оценки областей тоже сходятся', audit.scores, computeScores(audit.checks).scores);
|
|
107
|
+
is('и собственная проверка отчёта молчит', verifyScores(audit).filter((p) => p.startsWith('overall')), []);
|
|
108
|
+
}
|
|
109
|
+
|
|
89
110
|
if (bad) { console.error(`\n${bad} тест(ов) упало`); process.exit(1); }
|
|
90
111
|
console.log('\nвсе тесты общего балла прошли');
|