import { promises as fs } from "node:fs"; import path from "node:path"; import { glob } from "glob"; const featuresDir = path.resolve("specs/features"); const featureFiles = await glob(path.join(featuresDir, "*.feature")); /** Tags @int-* portés par les scénarios (intégration Vitest). */ const intTags = new Set(); for (const file of featureFiles) { const text = await fs.readFile(file, "utf8"); for (const line of text.split("\n")) { const trimmed = line.trim(); if (!trimmed.startsWith("@")) continue; const parts = trimmed.split(/\s+/); for (const token of parts) { if (token.startsWith("@int-")) intTags.add(token); } } } const intTestFiles = await glob(["packages/**/*.int.test.ts", "apps/**/*.int.test.ts"], { nodir: true }); const merged = ( await Promise.all(intTestFiles.map(async (f) => ({ file: f, body: await fs.readFile(f, "utf8") }))) ).reduce((acc, { file, body }) => { acc.set(file, body); return acc; }, new Map()); const missing = []; for (const tag of intTags) { let found = false; for (const body of merged.values()) { if (body.includes(tag)) { found = true; break; } } if (!found) missing.push(tag); } if (missing.length > 0) { console.error("Scénarios @int-* sans référence dans un fichier *.int.test.ts :"); for (const tag of missing.sort()) console.error(` ${tag}`); process.exit(1); } console.log(`Gherkin ↔ intégration OK (${intTags.size} tag(s) @int-* couverts dans ${intTestFiles.length} fichier(s))`);