test: parse help HTML with cheerio

This commit is contained in:
KoalaDev
2026-08-01 10:04:29 +02:00
parent 816cc38ea4
commit ec6865a0e7
3 changed files with 13 additions and 12 deletions
+1
View File
@@ -12,6 +12,7 @@
"@vitest/coverage-v8": "^4.1.10", "@vitest/coverage-v8": "^4.1.10",
"addons-linter": "^10.9.0", "addons-linter": "^10.9.0",
"archiver": "^8.0.0", "archiver": "^8.0.0",
"cheerio": "^1.2.0",
"esbuild": "^0.28.1", "esbuild": "^0.28.1",
"eslint": "^10.8.0", "eslint": "^10.8.0",
"eslint-plugin-no-unsanitized": "^4.1.5", "eslint-plugin-no-unsanitized": "^4.1.5",
+1
View File
@@ -22,6 +22,7 @@
"@vitest/coverage-v8": "^4.1.10", "@vitest/coverage-v8": "^4.1.10",
"addons-linter": "^10.9.0", "addons-linter": "^10.9.0",
"archiver": "^8.0.0", "archiver": "^8.0.0",
"cheerio": "^1.2.0",
"esbuild": "^0.28.1", "esbuild": "^0.28.1",
"eslint": "^10.8.0", "eslint": "^10.8.0",
"eslint-plugin-no-unsanitized": "^4.1.5", "eslint-plugin-no-unsanitized": "^4.1.5",
+11 -12
View File
@@ -3,6 +3,7 @@
import fs from 'node:fs'; import fs from 'node:fs';
import path from 'node:path'; import path from 'node:path';
import { fileURLToPath } from 'node:url'; import { fileURLToPath } from 'node:url';
import { load } from 'cheerio';
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
const template = fs.readFileSync(path.join(repoRoot, 'website', 'template.html'), 'utf8'); const template = fs.readFileSync(path.join(repoRoot, 'website', 'template.html'), 'utf8');
@@ -132,23 +133,21 @@ for (const metadata of requiredHelpMetadata) {
throw new Error(`help.html is missing SEO/AEO metadata: ${metadata}`); throw new Error(`help.html is missing SEO/AEO metadata: ${metadata}`);
} }
} }
const helpStructuredDataMatch = helpPage.match(/<script type="application\/ld\+json">([\s\S]*?)<\/script>/); const helpDocument = load(helpPage);
if (!helpStructuredDataMatch) { const helpStructuredDataScripts = helpDocument('script[type="application/ld+json"]');
if (helpStructuredDataScripts.length !== 1) {
throw new Error('help.html must contain JSON-LD structured data'); throw new Error('help.html must contain JSON-LD structured data');
} }
const helpStructuredData = JSON.parse(helpStructuredDataMatch[1]); const helpStructuredData = JSON.parse(helpStructuredDataScripts.html());
const helpFaqPage = helpStructuredData['@graph'].find(item => ( const helpFaqPage = helpStructuredData['@graph'].find(item => (
Array.isArray(item['@type']) && item['@type'].includes('FAQPage') Array.isArray(item['@type']) && item['@type'].includes('FAQPage')
)); ));
const helpVisibleText = helpPage const helpVisibleText = helpDocument('body')
.replace(/<script[\s\S]*?<\/script>/g, ' ') .clone()
.replace(/<[^>]+>/g, '') .find('script, style, noscript')
.replaceAll('&amp;', '&') .remove()
.replaceAll('&quot;', '"') .end()
.replaceAll('&#39;', "'") .text()
.replaceAll('&lt;', '<')
.replaceAll('&gt;', '>')
.replaceAll('&nbsp;', ' ')
.replace(/\s+/g, ' '); .replace(/\s+/g, ' ');
for (const question of helpFaqPage?.mainEntity || []) { for (const question of helpFaqPage?.mainEntity || []) {
if (!helpVisibleText.includes(question.name) || !helpVisibleText.includes(question.acceptedAnswer?.text)) { if (!helpVisibleText.includes(question.name) || !helpVisibleText.includes(question.acceptedAnswer?.text)) {