import { access, readFile } from 'node:fs/promises'; import { test } from 'node:test'; import assert from 'node:assert/strict'; /** * Structural checks for guide posts: they must carry FAQPage structured data * next to the BlogPosting entry, link to the download hub, and reference only * screenshots that the build actually shipped. */ const distRoot = new URL('../../dist/apps/website/', import.meta.url); const SITE = 'https://4gray.github.io/iptvnator'; const GUIDES = [ { slug: 'xtream-codes-setup-guide', screenshots: [ 'blog/guides/screenshots/guide-xtream-add-playlist-dark.png', 'blog/guides/screenshots/guide-xtream-auto-detect-dark.png', 'blog/guides/screenshots/guide-xtream-live-dark.png', ], }, { slug: 'stalker-portal-setup-guide', screenshots: [ 'blog/guides/screenshots/guide-stalker-add-playlist-dark.png', 'blog/guides/screenshots/guide-stalker-live-dark.png', ], }, { slug: 'm3u-playlist-epg-setup-guide', screenshots: [ 'blog/guides/screenshots/guide-m3u-add-playlist-dark.png', 'blog/guides/screenshots/guide-m3u-live-groups-dark.png', 'blog/guides/screenshots/guide-epg-settings-dark.png', ], }, { slug: 'offline-downloads-guide', screenshots: [ 'blog/guides/screenshots/guide-downloads-movie-detail-dark.png', 'blog/guides/screenshots/guide-downloads-manager-dark.png', 'blog/guides/screenshots/guide-downloads-offline-movie-dark.png', ], }, { slug: 'alternative-sources-guide', screenshots: [ 'blog/guides/screenshots/guide-sources-chip-dark.png', 'blog/guides/screenshots/guide-sources-menu-dark.png', ], }, { slug: 'remote-control-guide', screenshots: [ 'blog/guides/screenshots/guide-remote-settings-dark.png', 'blog/guides/screenshots/guide-remote-phone-dark.png', ], }, { slug: 'epg-wrong-program-fix', screenshots: [ 'blog/guides/screenshots/guide-epg-map-menu-dark.png', 'blog/guides/screenshots/guide-epg-map-dialog-dark.png', 'blog/guides/screenshots/guide-epg-offset-dark.png', ], }, { slug: 'tmdb-metadata-guide', screenshots: ['blog/guides/screenshots/guide-tmdb-settings-dark.png'], }, ]; const readDist = (relativePath) => readFile(new URL(relativePath, distRoot), 'utf8'); function extractJsonLd(html) { const blocks = [...html.matchAll(/