<?xml version="1.0" encoding="UTF-8" ?>
<testsuites name="vitest tests" tests="1770" failures="0" errors="0" time="11.47160521">
    <testsuite name="test/integration/cross-article-intelligence.test.js" timestamp="2026-04-28T00:15:08.112Z" hostname="runnervmeorf1" tests="6" failures="0" errors="0" skipped="0" time="0.036561026">
        <testcase classname="test/integration/cross-article-intelligence.test.js" name="Cross-Article Intelligence Integration &gt; should produce cross-references when a second related article is indexed" time="0.003733475">
        </testcase>
        <testcase classname="test/integration/cross-article-intelligence.test.js" name="Cross-Article Intelligence Integration &gt; should persist intelligence across save/load cycle and maintain cross-references" time="0.001605587">
        </testcase>
        <testcase classname="test/integration/cross-article-intelligence.test.js" name="Cross-Article Intelligence Integration &gt; should detect trends once two articles share the same topic" time="0.002886186">
        </testcase>
        <testcase classname="test/integration/cross-article-intelligence.test.js" name="Cross-Article Intelligence Integration &gt; should generate a valid &quot;Related Analysis&quot; HTML section end-to-end" time="0.022707393">
        </testcase>
        <testcase classname="test/integration/cross-article-intelligence.test.js" name="Cross-Article Intelligence Integration &gt; should produce no cross-references for a single article with no related content" time="0.000725387">
        </testcase>
        <testcase classname="test/integration/cross-article-intelligence.test.js" name="Cross-Article Intelligence Integration &gt; should build and persist a complete intelligence cycle" time="0.002843712">
        </testcase>
    </testsuite>
    <testsuite name="test/integration/sitemap-cli-byte-equality.test.js" timestamp="2026-04-28T00:15:08.149Z" hostname="runnervmeorf1" tests="5" failures="0" errors="0" skipped="0" time="5.764475826">
        <testcase classname="test/integration/sitemap-cli-byte-equality.test.js" name="sitemap CLI byte-equality regression &gt; produces byte-identical sitemap.xml across two runs" time="1.768475553">
        </testcase>
        <testcase classname="test/integration/sitemap-cli-byte-equality.test.js" name="sitemap CLI byte-equality regression &gt; produces byte-identical rss.xml across two runs (modulo lastBuildDate)" time="0.015351668">
        </testcase>
        <testcase classname="test/integration/sitemap-cli-byte-equality.test.js" name="sitemap CLI byte-equality regression &gt; generates all 14 sitemap_*.html files" time="0.001270525">
        </testcase>
        <testcase classname="test/integration/sitemap-cli-byte-equality.test.js" name="sitemap CLI byte-equality regression &gt; generates all 14 political-intelligence_*.html files" time="0.000634921">
        </testcase>
        <testcase classname="test/integration/sitemap-cli-byte-equality.test.js" name="sitemap CLI byte-equality regression &gt; produces byte-identical sitemap_*.html and political-intelligence_*.html across two runs" time="0.180269066">
        </testcase>
    </testsuite>
    <testsuite name="test/integration/week-ahead-data.test.js" timestamp="2026-04-28T00:15:08.150Z" hostname="runnervmeorf1" tests="4" failures="0" errors="0" skipped="0" time="0.015702113">
        <testcase classname="test/integration/week-ahead-data.test.js" name="Week-Ahead Data Integration &gt; Parallel Data Fetching &gt; should fetch all data sources in parallel using Promise.allSettled" time="0.007938037">
        </testcase>
        <testcase classname="test/integration/week-ahead-data.test.js" name="Week-Ahead Data Integration &gt; Parallel Data Fetching &gt; should handle partial failures gracefully" time="0.003424172">
            <system-err>
⚠️ get_committee_info failed [UNKNOWN]: Unknown tool
⚠️ monitor_legislative_pipeline failed [UNKNOWN]: Pipeline API unavailable

            </system-err>
        </testcase>
        <testcase classname="test/integration/week-ahead-data.test.js" name="Week-Ahead Data Integration &gt; Data Aggregation &gt; should aggregate data from multiple sources" time="0.000648693">
        </testcase>
        <testcase classname="test/integration/week-ahead-data.test.js" name="Week-Ahead Data Integration &gt; Fallback Behavior &gt; should provide fallback when all MCP tools fail" time="0.001239408">
            <system-err>
⚠️ get_plenary_sessions failed [UNKNOWN]: MCP unavailable
⚠️ get_committee_info failed [UNKNOWN]: MCP unavailable
⚠️ search_documents failed [UNKNOWN]: MCP unavailable
⚠️ monitor_legislative_pipeline failed [UNKNOWN]: MCP unavailable
⚠️ get_parliamentary_questions failed [UNKNOWN]: MCP unavailable

            </system-err>
        </testcase>
    </testsuite>
    <testsuite name="test/unit/aggregator-determinism.test.js" timestamp="2026-04-28T00:15:08.152Z" hostname="runnervmeorf1" tests="3" failures="0" errors="0" skipped="0" time="0.134850145">
        <testcase classname="test/unit/aggregator-determinism.test.js" name="article-generation pipeline — determinism &gt; produces byte-identical output across two consecutive runs (English only)" time="0.081950772">
        </testcase>
        <testcase classname="test/unit/aggregator-determinism.test.js" name="article-generation pipeline — determinism &gt; produces byte-identical output across two consecutive runs (all 14 languages)" time="0.043025284">
        </testcase>
        <testcase classname="test/unit/aggregator-determinism.test.js" name="article-generation pipeline — determinism &gt; produces byte-identical output in --markdown-only mode" time="0.007601562">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/analysis-aggregator.test.js" timestamp="2026-04-28T00:15:08.152Z" hostname="runnervmeorf1" tests="30" failures="0" errors="0" skipped="0" time="0.05776214">
        <testcase classname="test/unit/analysis-aggregator.test.js" name="flattenManifestFiles &gt; flattens nested category → string[] shape" time="0.003829249">
        </testcase>
        <testcase classname="test/unit/analysis-aggregator.test.js" name="flattenManifestFiles &gt; flattens flat path → description shape" time="0.000356604">
        </testcase>
        <testcase classname="test/unit/analysis-aggregator.test.js" name="flattenManifestFiles &gt; returns empty array for undefined" time="0.000208012">
        </testcase>
        <testcase classname="test/unit/analysis-aggregator.test.js" name="latestGateResult &gt; returns the most recent non-PENDING gateResult" time="0.000493459">
        </testcase>
        <testcase classname="test/unit/analysis-aggregator.test.js" name="latestGateResult &gt; returns PENDING when all entries are PENDING or empty" time="0.000302924">
        </testcase>
        <testcase classname="test/unit/analysis-aggregator.test.js" name="expandSectionArtifacts &gt; resolves exact paths and prefix directories in priority order" time="0.001841611">
        </testcase>
        <testcase classname="test/unit/analysis-aggregator.test.js" name="expandSectionArtifacts &gt; prefers root executive-brief.md over extended compatibility fallback" time="0.000452989">
        </testcase>
        <testcase classname="test/unit/analysis-aggregator.test.js" name="expandSectionArtifacts &gt; does not re-consume already-claimed artifacts" time="0.000371717">
        </testcase>
        <testcase classname="test/unit/analysis-aggregator.test.js" name="renderReaderIntelligenceGuide &gt; renders a Riksdagsmonitor-style navigation table for emitted sections" time="0.001123684">
        </testcase>
        <testcase classname="test/unit/analysis-aggregator.test.js" name="renderProvenanceBlock &gt; emits a blockquote with article type, date, run id, gate, and manifest link" time="0.000969984">
        </testcase>
        <testcase classname="test/unit/analysis-aggregator.test.js" name="renderTradecraftAppendix &gt; lists methodologies and templates separately with GitHub blob links" time="0.001136734">
        </testcase>
        <testcase classname="test/unit/analysis-aggregator.test.js" name="renderTradecraftAppendix &gt; omits section headings when no files of that kind exist" time="0.000349664">
        </testcase>
        <testcase classname="test/unit/analysis-aggregator.test.js" name="discoverTradecraftFiles &gt; discovers all committed methodology and template MD files" time="0.002910933">
        </testcase>
        <testcase classname="test/unit/analysis-aggregator.test.js" name="aggregateAnalysisRun (fixture) &gt; produces a deterministic aggregated document with executive brief first" time="0.014350808">
        </testcase>
        <testcase classname="test/unit/analysis-aggregator.test.js" name="aggregateAnalysisRun (fixture) &gt; lists every artifact in includedArtifacts with a stable section id" time="0.003452234">
        </testcase>
        <testcase classname="test/unit/analysis-aggregator.test.js" name="aggregateAnalysisRun (fixture) &gt; throws a clear error for a non-existent run directory" time="0.001365797">
        </testcase>
        <testcase classname="test/unit/analysis-aggregator.test.js" name="aggregateAnalysisRun (fixture) &gt; returns a sectionToc that mirrors the emitted H2 sections in document order" time="0.003380075">
        </testcase>
        <testcase classname="test/unit/analysis-aggregator.test.js" name="aggregateAnalysisRun (fixture) &gt; suppresses the redundant ### artifact header when a section has one matching artifact" time="0.002437393">
        </testcase>
        <testcase classname="test/unit/analysis-aggregator.test.js" name="aggregateAnalysisRun (fixture) &gt; does NOT include README.md in the aggregated output" time="0.010727918">
        </testcase>
        <testcase classname="test/unit/analysis-aggregator.test.js" name="guessDateFromRunDir &gt; extracts YYYY-MM-DD from a path with an ISO date segment" time="0.000969814">
        </testcase>
        <testcase classname="test/unit/analysis-aggregator.test.js" name="guessDateFromRunDir &gt; returns 1970-01-01 when no ISO date is present" time="0.000239839">
        </testcase>
        <testcase classname="test/unit/analysis-aggregator.test.js" name="guessDateFromRunDir &gt; handles a path with only the date component" time="0.000208472">
        </testcase>
        <testcase classname="test/unit/analysis-aggregator.test.js" name="renderAnalysisIndex &gt; produces a table with section, artifact stem, and path columns" time="0.000337916">
        </testcase>
        <testcase classname="test/unit/analysis-aggregator.test.js" name="renderAnalysisIndex &gt; lists the manifest.json link in the preamble" time="0.000670135">
        </testcase>
        <testcase classname="test/unit/analysis-aggregator.test.js" name="renderAnalysisIndex &gt; renders a row for every included artifact" time="0.000277336">
        </testcase>
        <testcase classname="test/unit/analysis-aggregator.test.js" name="resolveArticleTypeFromManifest &gt; uses canonical articleType when present" time="0.00023331">
        </testcase>
        <testcase classname="test/unit/analysis-aggregator.test.js" name="resolveArticleTypeFromManifest &gt; falls back to articleTypes[0] for legacy plural-array manifests" time="0.000184216">
        </testcase>
        <testcase classname="test/unit/analysis-aggregator.test.js" name="resolveArticleTypeFromManifest &gt; falls back to runType when neither articleType nor articleTypes is set" time="0.000203976">
        </testcase>
        <testcase classname="test/unit/analysis-aggregator.test.js" name="resolveArticleTypeFromManifest &gt; prefers articleType over articleTypes and runType" time="0.000166669">
        </testcase>
        <testcase classname="test/unit/analysis-aggregator.test.js" name="resolveArticleTypeFromManifest &gt; returns &quot;unknown&quot; when no schema field is populated" time="0.000205919">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/analysis-templates-referenced.test.js" timestamp="2026-04-28T00:15:08.157Z" hostname="runnervmeorf1" tests="2" failures="0" errors="0" skipped="0" time="0.008971566">
        <testcase classname="test/unit/analysis-templates-referenced.test.js" name="analysis/templates are referenced by prompts or agents &gt; every non-index template is referenced by basename in prompts/ or agents/" time="0.006476666">
        </testcase>
        <testcase classname="test/unit/analysis-templates-referenced.test.js" name="analysis/templates are referenced by prompts or agents &gt; template directory has at least 25 templates" time="0.000577605">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/article-generator-cli.test.js" timestamp="2026-04-28T00:15:08.158Z" hostname="runnervmeorf1" tests="32" failures="0" errors="0" skipped="0" time="0.304788769">
        <testcase classname="test/unit/article-generator-cli.test.js" name="parseCliArgs &gt; requires --run or --all" time="0.003357492">
        </testcase>
        <testcase classname="test/unit/article-generator-cli.test.js" name="parseCliArgs &gt; accepts --run=PATH inline-style" time="0.000789183">
        </testcase>
        <testcase classname="test/unit/article-generator-cli.test.js" name="parseCliArgs &gt; collects repeated --lang flags" time="0.000937856">
        </testcase>
        <testcase classname="test/unit/article-generator-cli.test.js" name="parseCliArgs &gt; rejects unknown languages" time="0.00038668">
        </testcase>
        <testcase classname="test/unit/article-generator-cli.test.js" name="parseCliArgs &gt; rejects unknown flags" time="0.000400571">
        </testcase>
        <testcase classname="test/unit/article-generator-cli.test.js" name="parseCliArgs &gt; rejects a non-existent run directory" time="0.00032739">
        </testcase>
        <testcase classname="test/unit/article-generator-cli.test.js" name="parseCliArgs &gt; honours --markdown-only" time="0.000279099">
        </testcase>
        <testcase classname="test/unit/article-generator-cli.test.js" name="parseCliArgs &gt; accepts --all with no --run" time="0.000384577">
        </testcase>
        <testcase classname="test/unit/article-generator-cli.test.js" name="parseCliArgs &gt; accepts --since YYYY-MM-DD paired with --all" time="0.000649644">
        </testcase>
        <testcase classname="test/unit/article-generator-cli.test.js" name="parseCliArgs &gt; rejects an ill-formed --since value" time="0.00050044">
        </testcase>
        <testcase classname="test/unit/article-generator-cli.test.js" name="buildArticleSlug &gt; joins date and article type with a dash" time="0.000348132">
        </testcase>
        <testcase classname="test/unit/article-generator-cli.test.js" name="buildArticleSlug &gt; appends a collision suffix when provided" time="0.00016715">
        </testcase>
        <testcase classname="test/unit/article-generator-cli.test.js" name="sanitizeRunSuffix &gt; keeps word characters, dashes, and dots" time="0.000325889">
        </testcase>
        <testcase classname="test/unit/article-generator-cli.test.js" name="sanitizeRunSuffix &gt; replaces unsafe characters with a single dash" time="0.000147481">
        </testcase>
        <testcase classname="test/unit/article-generator-cli.test.js" name="sanitizeRunSuffix &gt; trims leading and trailing dashes" time="0.000216314">
        </testcase>
        <testcase classname="test/unit/article-generator-cli.test.js" name="sanitizeRunSuffix &gt; caps output length at 32 characters" time="0.00012667">
        </testcase>
        <testcase classname="test/unit/article-generator-cli.test.js" name="sanitizeRunSuffix &gt; falls back to `run` for empty input" time="0.000198968">
        </testcase>
        <testcase classname="test/unit/article-generator-cli.test.js" name="extractDefaultDescription &gt; returns the first prose paragraph, truncated to 300 chars" time="0.000775843">
        </testcase>
        <testcase classname="test/unit/article-generator-cli.test.js" name="extractDefaultDescription &gt; falls back when nothing qualifies" time="0.000236634">
        </testcase>
        <testcase classname="test/unit/article-generator-cli.test.js" name="generateArticle (end-to-end fixture) &gt; writes article.md to the run directory (riksdagsmonitor pattern)" time="0.105983472">
        </testcase>
        <testcase classname="test/unit/article-generator-cli.test.js" name="generateArticle (end-to-end fixture) &gt; writes source .md plus 14 HTML files and reports determinism" time="0.04902805">
        </testcase>
        <testcase classname="test/unit/article-generator-cli.test.js" name="generateArticle (end-to-end fixture) &gt; supports --markdown-only (no HTML written)" time="0.00392299">
        </testcase>
        <testcase classname="test/unit/article-generator-cli.test.js" name="generateArticle (end-to-end fixture) &gt; is deterministic across runs (byte-identical output)" time="0.0814753">
        </testcase>
        <testcase classname="test/unit/article-generator-cli.test.js" name="generateArticle (end-to-end fixture) &gt; suppresses the redundant ### heading when a single-artifact section title matches" time="0.031468323">
        </testcase>
        <testcase classname="test/unit/article-generator-cli.test.js" name="discoverAnalysisRuns &gt; returns nothing when analysis/daily is missing" time="0.001007921">
        </testcase>
        <testcase classname="test/unit/article-generator-cli.test.js" name="discoverAnalysisRuns &gt; finds runs at any nesting depth and sorts by date then path" time="0.002391825">
        </testcase>
        <testcase classname="test/unit/article-generator-cli.test.js" name="discoverAnalysisRuns &gt; skips runs with missing or &quot;unknown&quot; articleType" time="0.001779937">
        </testcase>
        <testcase classname="test/unit/article-generator-cli.test.js" name="discoverAnalysisRuns &gt; recovers the date from the directory name when the manifest lacks it" time="0.002034419">
        </testcase>
        <testcase classname="test/unit/article-generator-cli.test.js" name="groupRunsForCollision &gt; buckets runs by (date, articleType) pair" time="0.000473109">
        </testcase>
        <testcase classname="test/unit/article-generator-cli.test.js" name="generateAllArticles (batch mode) &gt; applies a collision suffix when two runs share (date, articleType)" time="0.004165403">
        </testcase>
        <testcase classname="test/unit/article-generator-cli.test.js" name="generateAllArticles (batch mode) &gt; uses the bare slug when a (date, articleType) pair is unique" time="0.002258415">
        </testcase>
        <testcase classname="test/unit/article-generator-cli.test.js" name="generateAllArticles (batch mode) &gt; honours --since to skip earlier runs" time="0.003862939">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/article-html.test.js" timestamp="2026-04-28T00:15:08.163Z" hostname="runnervmeorf1" tests="25" failures="0" errors="0" skipped="0" time="0.023743696">
        <testcase classname="test/unit/article-html.test.js" name="getArticleFilename &gt; uses &lt;date&gt;-&lt;type&gt;-&lt;lang&gt;.html pattern uniformly" time="0.00304251">
        </testcase>
        <testcase classname="test/unit/article-html.test.js" name="buildArticleHreflangLinks &gt; emits one &lt;link rel=&quot;alternate&quot;&gt; per language plus x-default" time="0.00074086">
        </testcase>
        <testcase classname="test/unit/article-html.test.js" name="wrapArticleHtml &gt; emits a complete HTML5 document with the article body" time="0.001639557">
        </testcase>
        <testcase classname="test/unit/article-html.test.js" name="wrapArticleHtml &gt; includes the skip-link and theme toggle button for a11y parity" time="0.000628021">
        </testcase>
        <testcase classname="test/unit/article-html.test.js" name="wrapArticleHtml &gt; renders hreflang alternates for all 14 languages + x-default" time="0.000688612">
        </testcase>
        <testcase classname="test/unit/article-html.test.js" name="wrapArticleHtml &gt; renders the language switcher with an active state for current lang" time="0.00044672">
        </testcase>
        <testcase classname="test/unit/article-html.test.js" name="wrapArticleHtml &gt; does NOT inline any &lt;script&gt; in the body (CSP-safe)" time="0.000524957">
        </testcase>
        <testcase classname="test/unit/article-html.test.js" name="wrapArticleHtml &gt; references the same-origin Mermaid initializer with a version cache-bust (CSP-safe)" time="0.000878577">
        </testcase>
        <testcase classname="test/unit/article-html.test.js" name="wrapArticleHtml &gt; renders a reader-facing article hero before the artifact body" time="0.000678667">
        </testcase>
        <testcase classname="test/unit/article-html.test.js" name="wrapArticleHtml &gt; sets dir=&quot;rtl&quot; for Arabic and Hebrew" time="0.002126847">
        </testcase>
        <testcase classname="test/unit/article-html.test.js" name="wrapArticleHtml &gt; includes a JSON-LD NewsArticle block with escaped &lt; characters" time="0.001078947">
        </testcase>
        <testcase classname="test/unit/article-html.test.js" name="wrapArticleHtml &gt; emits the optional source-markdown link when provided" time="0.000690104">
        </testcase>
        <testcase classname="test/unit/article-html.test.js" name="wrapArticleHtml &gt; renders the article TOC sidebar when toc entries are supplied" time="0.000977845">
        </testcase>
        <testcase classname="test/unit/article-html.test.js" name="wrapArticleHtml &gt; omits the sidebar entirely when toc is empty or absent" time="0.001313208">
        </testcase>
        <testcase classname="test/unit/article-html.test.js" name="wrapArticleHtml &gt; embeds the language switcher INSIDE the header using site-header__langs (matches index chrome)" time="0.001876052">
        </testcase>
        <testcase classname="test/unit/article-html.test.js" name="wrapArticleHtml &gt; uses the banner asset as the header logo (matches index chrome)" time="0.000422353">
        </testcase>
        <testcase classname="test/unit/article-html.test.js" name="wrapArticleHtml &gt; surfaces the footer-stats line when articleCount is provided" time="0.00039342">
        </testcase>
        <testcase classname="test/unit/article-html.test.js" name="wrapArticleHtml &gt; omits the footer-stats line when articleCount is absent" time="0.000313861">
        </testcase>
        <testcase classname="test/unit/article-html.test.js" name="wrapArticleHtml &gt; embeds isBasedOn in JSON-LD when source artifact URLs are provided" time="0.000418007">
        </testcase>
        <testcase classname="test/unit/article-html.test.js" name="wrapArticleHtml &gt; omits isBasedOn from JSON-LD when the option is absent" time="0.00043376">
        </testcase>
        <testcase classname="test/unit/article-html.test.js" name="wrapArticleHtml &gt; omits isBasedOn from JSON-LD when an empty array is provided" time="0.000559269">
        </testcase>
        <testcase classname="test/unit/article-html.test.js" name="buildArticleToc &gt; returns an empty string when there are no entries" time="0.000144717">
        </testcase>
        <testcase classname="test/unit/article-html.test.js" name="buildArticleToc &gt; renders an &lt;aside&gt;&lt;details&gt;&lt;nav&gt;&lt;ol&gt; tree with stable anchors" time="0.000261332">
        </testcase>
        <testcase classname="test/unit/article-html.test.js" name="buildArticleToc &gt; escapes HTML in entry titles and ids to prevent injection" time="0.000291607">
        </testcase>
        <testcase classname="test/unit/article-html.test.js" name="buildArticleToc &gt; localises the nav label from TOC_ARIA_LABELS" time="0.000168032">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/article-metadata.test.js" timestamp="2026-04-28T00:15:08.168Z" hostname="runnervmeorf1" tests="60" failures="0" errors="0" skipped="0" time="0.040546778">
        <testcase classname="test/unit/article-metadata.test.js" name="shouldSkipDescriptionLine — tightened leak filter &gt; still rejects the original structural openers" time="0.002269131">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="shouldSkipDescriptionLine — tightened leak filter &gt; rejects mermaid %%{init blocks and `title` directives" time="0.000290055">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="shouldSkipDescriptionLine — tightened leak filter &gt; rejects emoji-prefixed metadata banners" time="0.000309975">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="shouldSkipDescriptionLine — tightened leak filter &gt; rejects `Key: value` metadata rows regardless of bold/italic wrapping" time="0.000577635">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="shouldSkipDescriptionLine — tightened leak filter &gt; rejects decorative separators" time="0.000278197">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="shouldSkipDescriptionLine — tightened leak filter &gt; still accepts real prose lines" time="0.000230064">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="stripInlineMarkdown &gt; removes link, emphasis, and inline-code syntax" time="0.000689774">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="stripInlineMarkdown &gt; preserves the visible text of images" time="0.000275092">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="truncation helpers &gt; preserves short input" time="0.000498287">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="truncation helpers &gt; truncates on a word boundary when possible" time="0.000438937">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="extractFirstH1 &gt; returns the first `# …` heading text, stripped of anchor syntax" time="0.000347982">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="extractFirstH1 &gt; returns an empty string when no H1 exists" time="0.000136264">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="extractFirstH1 &gt; skips `##` and `###` lines" time="0.000175694">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="extractStrongProseLine &gt; returns the first prose paragraph, truncated" time="0.000268212">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="extractStrongProseLine &gt; does NOT leak mermaid init blocks" time="0.000224887">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="extractStrongProseLine &gt; does NOT leak emoji-banner metadata rows" time="0.000428262">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="extractStrongProseLine &gt; does NOT leak `Analysis Date:` / `Run:` / `Window:` banners" time="0.000235983">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="extractStrongProseLine &gt; does NOT leak mermaid `title` directives" time="0.000256645">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="extractStrongProseLine &gt; returns empty when nothing qualifies" time="0.000132919">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="humanizeSlug &gt; title-cases and de-dashifies slugs" time="0.000352749">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="isGenericHeading &gt; rejects the default `${humanize(type)} — ${date}` form" time="0.000260961">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="isGenericHeading &gt; rejects the legacy &quot;EU Parliament &lt;Type&gt; — &lt;date&gt;&quot; form" time="0.000124857">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="isGenericHeading &gt; rejects the collision-suffix &quot;Breaking Breaking — &lt;date&gt;&quot; form" time="0.000156715">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="isGenericHeading &gt; accepts any non-generic editorial headline" time="0.000350616">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="isGenericHeading &gt; rejects empty headings" time="0.000142473">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="deriveWeekRange / deriveMonthLabel &gt; returns the Mon–Sun week containing the supplied ISO date" time="0.001053249">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="deriveWeekRange / deriveMonthLabel &gt; returns the raw date when parsing fails" time="0.000145719">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="deriveWeekRange / deriveMonthLabel &gt; labels the month with English name + year" time="0.000187511">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="deriveReportingWindowForWeekInReview — D-36 → D-8 window (ADR-006) &gt; returns start=D-36 and end=D-8 for a known date" time="0.000225407">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="deriveReportingWindowForWeekInReview — D-36 → D-8 window (ADR-006) &gt; end is always 28 days after start" time="0.000251807">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="deriveReportingWindowForWeekInReview — D-36 → D-8 window (ADR-006) &gt; end date is exactly 8 days before the supplied article date" time="0.000154171">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="deriveReportingWindowForWeekInReview — D-36 → D-8 window (ADR-006) &gt; returns the raw date for both start and end when parsing fails" time="0.000132268">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="deriveReportingWindowForWeekInReview — D-36 → D-8 window (ADR-006) &gt; window end is strictly earlier than the article date (vote-lag safety)" time="0.000130836">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="buildTemplateFallback — 14 langs × 8 types = last-resort coverage &gt; covers all 14 languages for type=breaking" time="0.001453749">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="buildTemplateFallback — 14 langs × 8 types = last-resort coverage &gt; covers all 14 languages for type=committee-reports" time="0.001156053">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="buildTemplateFallback — 14 langs × 8 types = last-resort coverage &gt; covers all 14 languages for type=motions" time="0.001460919">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="buildTemplateFallback — 14 langs × 8 types = last-resort coverage &gt; covers all 14 languages for type=propositions" time="0.001131115">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="buildTemplateFallback — 14 langs × 8 types = last-resort coverage &gt; covers all 14 languages for type=week-ahead" time="0.001279167">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="buildTemplateFallback — 14 langs × 8 types = last-resort coverage &gt; covers all 14 languages for type=month-ahead" time="0.002028931">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="buildTemplateFallback — 14 langs × 8 types = last-resort coverage &gt; covers all 14 languages for type=week-in-review" time="0.000992006">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="buildTemplateFallback — 14 langs × 8 types = last-resort coverage &gt; covers all 14 languages for type=month-in-review" time="0.001537735">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="buildTemplateFallback — 14 langs × 8 types = last-resort coverage &gt; yields non-English titles for non-English languages" time="0.000330205">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="buildTemplateFallback — 14 langs × 8 types = last-resort coverage &gt; committee-reports uses the supplied committee code" time="0.000172268">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="buildTemplateFallback — 14 langs × 8 types = last-resort coverage &gt; unknown article types get a sensible humanised fallback" time="0.000215243">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="buildTemplateFallback — 14 langs × 8 types = last-resort coverage &gt; week-in-review title uses D-36→D-8 reporting window, not the calendar week" time="0.000281642">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="buildTemplateFallback — 14 langs × 8 types = last-resort coverage &gt; week-in-review English subtitle references last full reporting week" time="0.000277847">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="buildTemplateFallback — 14 langs × 8 types = last-resort coverage &gt; week-ahead title still uses the calendar week (not the reporting window)" time="0.000197947">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="resolveArticleMetadata — priority ladder &gt; Tier 1 — manifest string override wins over everything else" time="0.002919025">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="resolveArticleMetadata — priority ladder &gt; Tier 1 — manifest per-language object applies per language" time="0.00084713">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="resolveArticleMetadata — priority ladder &gt; non-English languages never inherit the English editorial headline" time="0.00202851">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="resolveArticleMetadata — priority ladder &gt; non-English languages still honour an explicit per-language manifest override" time="0.000626609">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="resolveArticleMetadata — priority ladder &gt; Tier 2 — first non-generic artefact H1 wins over aggregated H1" time="0.000925938">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="resolveArticleMetadata — priority ladder &gt; Tier 3 — non-generic aggregated H1 wins when no artefact exists" time="0.00068759">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="resolveArticleMetadata — priority ladder &gt; Tier 4 — strong prose wins when every heading is generic" time="0.000659509">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="resolveArticleMetadata — priority ladder &gt; Tier 5 — localized template fallback for every language when nothing else exists" time="0.000610595">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="resolveArticleMetadata — priority ladder &gt; truncates long resolved titles and descriptions" time="0.000638066">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="resolveArticleMetadata — priority ladder &gt; covers all 14 languages with non-empty title+description in every tier" time="0.001118496">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="extractArtifactHighlight &gt; returns null for a non-existent directory" time="0.000561302">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="extractArtifactHighlight &gt; skips SPDX HTML-comment headers and picks the real H1" time="0.000814351">
        </testcase>
        <testcase classname="test/unit/article-metadata.test.js" name="extractArtifactHighlight &gt; ignores an artefact whose H1 is generic" time="0.000851686">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/backport-article-seo.test.js" timestamp="2026-04-28T00:15:08.178Z" hostname="runnervmeorf1" tests="60" failures="0" errors="0" skipped="0" time="0.046414742">
        <testcase classname="test/unit/backport-article-seo.test.js" name="sliceArticleBody &gt; returns the slice between &lt;article&gt; and &lt;/article&gt;" time="0.005615265">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="sliceArticleBody &gt; falls back to the entire document when no &lt;article&gt; tag is present" time="0.000543815">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="extractBodyH1 / extractBodyFirstProse &gt; extracts the first body H1 text with inline tags stripped" time="0.000932658">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="extractBodyH1 / extractBodyFirstProse &gt; skips header metadata spans and returns the first long body paragraph" time="0.001203694">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="extractBodyH1 / extractBodyFirstProse &gt; skips paragraphs that are metadata-banner stubs" time="0.000572448">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="extractBodyH1 / extractBodyFirstProse &gt; skips aggregator ICD-203 / Run-metadata / Purpose-banner paragraphs" time="0.001151215">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="extractBodyH1 / extractBodyFirstProse &gt; decodes HTML entities so the output is plain prose" time="0.000348753">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="isGenericBodyH1 &gt; flags legacy template H1s as generic" time="0.000741372">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="isGenericBodyH1 &gt; flags the pure `&lt;Phrase&gt; — &lt;ISO-date&gt;` aggregator default form even with a run-suffixed articleType" time="0.000832958">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="isGenericBodyH1 &gt; accepts real editorial headlines" time="0.000333149">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="truncateUpto &gt; returns the input unchanged when under the cap" time="0.000318608">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="truncateUpto &gt; clips on a word boundary and appends an ellipsis" time="0.000924195">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="deriveMetadataForFile — full pipeline &gt; replaces a generic legacy H1 with a body-derived editorial highlight" time="0.004381917">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="deriveMetadataForFile — full pipeline &gt; keeps a rich editorial H1 when one already exists" time="0.001607039">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="deriveMetadataForFile — full pipeline &gt; falls back to template metadata when body has no prose" time="0.000591677">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="deriveMetadataForFile — full pipeline &gt; uses the localized template when body language does not match filename language" time="0.001222552">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="deriveMetadataForFile — full pipeline &gt; mines the body when its `&lt;html lang&gt;` matches the filename language" time="0.000835602">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="rewriteHtml — idempotency + surface coverage &gt; rewrites every SEO-facing region but leaves the body untouched" time="0.002563322">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="rewriteHtml — idempotency + surface coverage &gt; is idempotent — rewriting twice with the same metadata produces byte-identical output" time="0.000955692">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="rewriteHtml — idempotency + surface coverage &gt; HTML-escapes special characters in new metadata values" time="0.000636484">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="rewriteHtml — idempotency + surface coverage &gt; preserves the original &lt;head&gt; structure for tags we do not rewrite" time="0.000669013">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="rewriteHtml — idempotency + surface coverage &gt; correctly rewrites meta tags whose existing content contains apostrophes" time="0.000904827">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="parseArgs — CLI argument parsing branches &gt; returns defaults when no arguments are supplied" time="0.000444296">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="parseArgs — CLI argument parsing branches &gt; --apply sets apply=true" time="0.000813529">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="parseArgs — CLI argument parsing branches &gt; --dry-run resets apply to false even after --apply" time="0.000259669">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="parseArgs — CLI argument parsing branches &gt; --dir consumes the next positional as a path" time="0.000437546">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="parseArgs — CLI argument parsing branches &gt; --dir without a value throws" time="0.001131055">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="parseArgs — CLI argument parsing branches &gt; --only splits comma lists into a Set and trims whitespace" time="0.000378578">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="parseArgs — CLI argument parsing branches &gt; --only without a value throws" time="0.000369804">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="parseArgs — CLI argument parsing branches &gt; unknown flags throw with a helpful message" time="0.000351647">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="listArticleFiles — filesystem walk skip branches &gt; returns the parsed entries for well-formed filenames only" time="0.002249952">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="chooseTitle — tier fallback branches &gt; returns the body H1 when it is non-generic" time="0.000308402">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="chooseTitle — tier fallback branches &gt; falls back to prose first-sentence when the H1 is generic" time="0.000261552">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="chooseTitle — tier fallback branches &gt; falls back to the template when neither H1 nor prose are usable" time="0.000185599">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="chooseTitle — tier fallback branches &gt; skips a too-short first sentence and returns the template" time="0.000194531">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="isGenericBodyH1 — legacy + date-suffix patterns &gt; flags each known legacy-era title verbatim" time="0.00101421">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="isGenericBodyH1 — legacy + date-suffix patterns &gt; flags legacy templates when they carry a suffix" time="0.000230886">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="isGenericBodyH1 — legacy + date-suffix patterns &gt; flags the &quot;&lt;Short-Phrase&gt; — &lt;ISO-date&gt;&quot; form even for run-suffixed types" time="0.000327191">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="isGenericBodyH1 — legacy + date-suffix patterns &gt; returns false for a genuinely editorial headline" time="0.000269824">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="extractFirstSentence — boundary + cap branches &gt; returns the first sentence up to the first terminator" time="0.000190616">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="extractFirstSentence — boundary + cap branches &gt; supports ! and ? as sentence terminators" time="0.000219008">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="extractFirstSentence — boundary + cap branches &gt; returns the whole prose when no terminator is present and within cap" time="0.000162373">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="extractFirstSentence — boundary + cap branches &gt; truncates long sentences with an ellipsis at word boundary" time="0.000284286">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="truncateUpto — boundary branches &gt; returns unchanged text when within cap" time="0.000154752">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="truncateUpto — boundary branches &gt; trims mid-word breaks to the last space" time="0.000379318">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="truncateUpto — boundary branches &gt; falls through to raw slice when no word boundary is near the cap" time="0.000229043">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="truncateUpto — boundary branches &gt; strips trailing punctuation before the ellipsis" time="0.00030038">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="pickLangEntry — safe map lookup &gt; returns the language-specific entry when present" time="0.000269514">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="pickLangEntry — safe map lookup &gt; falls back to en when the requested language is absent" time="0.000282633">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="pickLangEntry — safe map lookup &gt; returns empty strings when neither lang nor en is present" time="0.000192489">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="pickLangEntry — safe map lookup &gt; is immune to prototype-pollution lookup keys" time="0.00024034">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="decodeEntities — named + numeric branches &gt; decodes common named entities" time="0.000355523">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="decodeEntities — named + numeric branches &gt; decodes typographic named entities" time="0.00024006">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="decodeEntities — named + numeric branches &gt; decodes diacritic named entities" time="0.000236274">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="decodeEntities — named + numeric branches &gt; decodes decimal numeric entities" time="0.000191837">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="decodeEntities — named + numeric branches &gt; decodes hex numeric entities" time="0.000217446">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="decodeEntities — named + numeric branches &gt; leaves unknown entities verbatim" time="0.000141613">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="extractBodySecondProse — selection branches &gt; returns the second paragraph of substantial prose" time="0.000270746">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="extractBodySecondProse — selection branches &gt; returns empty string when fewer than two paragraphs qualify" time="0.000167702">
        </testcase>
        <testcase classname="test/unit/backport-article-seo.test.js" name="extractBodySecondProse — selection branches &gt; ignores paragraphs inside the article header and nav" time="0.000398588">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/clean-artifact.test.js" timestamp="2026-04-28T00:15:08.188Z" hostname="runnervmeorf1" tests="30" failures="0" errors="0" skipped="0" time="0.022801784">
        <testcase classname="test/unit/clean-artifact.test.js" name="stripFrontMatter &gt; removes a leading YAML block" time="0.002840577">
        </testcase>
        <testcase classname="test/unit/clean-artifact.test.js" name="stripFrontMatter &gt; ignores a document with no front-matter" time="0.000254722">
        </testcase>
        <testcase classname="test/unit/clean-artifact.test.js" name="stripFrontMatter &gt; only strips the leading block, not later separators" time="0.000499769">
        </testcase>
        <testcase classname="test/unit/clean-artifact.test.js" name="stripBanners &gt; removes document-owner and shields.io banners with trailing HR" time="0.001752767">
        </testcase>
        <testcase classname="test/unit/clean-artifact.test.js" name="stripBanners &gt; leaves content-only documents untouched" time="0.000438818">
        </testcase>
        <testcase classname="test/unit/clean-artifact.test.js" name="demoteHeadings &gt; removes H1 and demotes H2 to H3, H3 to H4" time="0.001071866">
        </testcase>
        <testcase classname="test/unit/clean-artifact.test.js" name="demoteHeadings &gt; preserves headings inside fenced code blocks" time="0.000495583">
        </testcase>
        <testcase classname="test/unit/clean-artifact.test.js" name="demoteHeadings &gt; handles H6 by clamping at H6 (no H7)" time="0.000382683">
        </testcase>
        <testcase classname="test/unit/clean-artifact.test.js" name="demoteHeadings &gt; drops setext H1 (underline form)" time="0.00179488">
        </testcase>
        <testcase classname="test/unit/clean-artifact.test.js" name="resolveLink + rewriteLinks &gt; converts relative .md targets to GitHub blob URLs" time="0.000723355">
        </testcase>
        <testcase classname="test/unit/clean-artifact.test.js" name="resolveLink + rewriteLinks &gt; preserves absolute URLs" time="0.000402573">
        </testcase>
        <testcase classname="test/unit/clean-artifact.test.js" name="resolveLink + rewriteLinks &gt; preserves anchors" time="0.00019322">
        </testcase>
        <testcase classname="test/unit/clean-artifact.test.js" name="resolveLink + rewriteLinks &gt; preserves mailto and tel" time="0.000224556">
        </testcase>
        <testcase classname="test/unit/clean-artifact.test.js" name="resolveLink + rewriteLinks &gt; rewrites inline link in prose line" time="0.000993749">
        </testcase>
        <testcase classname="test/unit/clean-artifact.test.js" name="resolveLink + rewriteLinks &gt; leaves links inside fenced code blocks alone" time="0.000337526">
        </testcase>
        <testcase classname="test/unit/clean-artifact.test.js" name="resolveLink + rewriteLinks &gt; preserves link title attribute" time="0.000301471">
        </testcase>
        <testcase classname="test/unit/clean-artifact.test.js" name="dedupMermaid &gt; replaces duplicate mermaid blocks with a cross-reference comment" time="0.00076752">
        </testcase>
        <testcase classname="test/unit/clean-artifact.test.js" name="dedupMermaid &gt; keeps distinct mermaid blocks" time="0.000370806">
        </testcase>
        <testcase classname="test/unit/clean-artifact.test.js" name="stripSpdxTags &gt; removes italicised SPDX footer lines (markdown-it would otherwise emit &lt;em&gt;…&lt;/em&gt;&lt;/p&gt; and break REUSE)" time="0.000542563">
        </testcase>
        <testcase classname="test/unit/clean-artifact.test.js" name="stripSpdxTags &gt; strips HTML-comment SPDX headers and FileCopyrightText lines" time="0.000272419">
        </testcase>
        <testcase classname="test/unit/clean-artifact.test.js" name="stripSpdxTags &gt; is a no-op when no SPDX tag is present" time="0.000325769">
        </testcase>
        <testcase classname="test/unit/clean-artifact.test.js" name="cleanArtifact end-to-end &gt; applies every pass and returns deterministic output" time="0.001430894">
        </testcase>
        <testcase classname="test/unit/clean-artifact.test.js" name="cleanArtifact end-to-end &gt; also strips SPDX footer lines via the cleanArtifact pipeline" time="0.000299789">
        </testcase>
        <testcase classname="test/unit/clean-artifact.test.js" name="cleanArtifact end-to-end &gt; shares mermaid dedup state across two invocations" time="0.000357786">
        </testcase>
        <testcase classname="test/unit/clean-artifact.test.js" name="cleanArtifact end-to-end &gt; strips the metadata preamble and reflects it in strippedMetaLines" time="0.000509794">
        </testcase>
        <testcase classname="test/unit/clean-artifact.test.js" name="stripArtifactMetadataPreamble &gt; strips a **Run:** / **Window:** block followed by a standalone ---" time="0.000426109">
        </testcase>
        <testcase classname="test/unit/clean-artifact.test.js" name="stripArtifactMetadataPreamble &gt; strips block with no trailing --- (stops at first non-metadata line)" time="0.000346499">
        </testcase>
        <testcase classname="test/unit/clean-artifact.test.js" name="stripArtifactMetadataPreamble &gt; leaves content-only documents untouched (no leading metadata)" time="0.00021345">
        </testcase>
        <testcase classname="test/unit/clean-artifact.test.js" name="stripArtifactMetadataPreamble &gt; counts lines removed correctly" time="0.00037407">
        </testcase>
        <testcase classname="test/unit/clean-artifact.test.js" name="stripArtifactMetadataPreamble &gt; returns { lines: 0 } for a document starting with a blank line then non-metadata" time="0.000238047">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/cli-parse.test.js" timestamp="2026-04-28T00:15:08.194Z" hostname="runnervmeorf1" tests="26" failures="0" errors="0" skipped="0" time="0.012082258">
        <testcase classname="test/unit/cli-parse.test.js" name="parseCliArgsSafe — kind:&quot;options&quot; happy paths &gt; accepts --run with a space-separated value" time="0.0026955">
        </testcase>
        <testcase classname="test/unit/cli-parse.test.js" name="parseCliArgsSafe — kind:&quot;options&quot; happy paths &gt; accepts --run=PATH inline-style" time="0.000287571">
        </testcase>
        <testcase classname="test/unit/cli-parse.test.js" name="parseCliArgsSafe — kind:&quot;options&quot; happy paths &gt; accepts the --analysis-dir alias" time="0.000260921">
        </testcase>
        <testcase classname="test/unit/cli-parse.test.js" name="parseCliArgsSafe — kind:&quot;options&quot; happy paths &gt; accepts --all without --run" time="0.000363966">
        </testcase>
        <testcase classname="test/unit/cli-parse.test.js" name="parseCliArgsSafe — kind:&quot;options&quot; happy paths &gt; collects repeated --lang flags" time="0.000907761">
        </testcase>
        <testcase classname="test/unit/cli-parse.test.js" name="parseCliArgsSafe — kind:&quot;options&quot; happy paths &gt; accepts the --language alias" time="0.000314802">
        </testcase>
        <testcase classname="test/unit/cli-parse.test.js" name="parseCliArgsSafe — kind:&quot;options&quot; happy paths &gt; honours --markdown-only" time="0.00023377">
        </testcase>
        <testcase classname="test/unit/cli-parse.test.js" name="parseCliArgsSafe — kind:&quot;options&quot; happy paths &gt; honours --since" time="0.000321402">
        </testcase>
        <testcase classname="test/unit/cli-parse.test.js" name="parseCliArgsSafe — kind:&quot;options&quot; happy paths &gt; honours --title and --description" time="0.000568101">
        </testcase>
        <testcase classname="test/unit/cli-parse.test.js" name="parseCliArgsSafe — kind:&quot;options&quot; happy paths &gt; honours the --output alias for --out-dir" time="0.000264546">
        </testcase>
        <testcase classname="test/unit/cli-parse.test.js" name="parseCliArgsSafe — kind:&quot;options&quot; happy paths &gt; defaults langs to ALL_LANGUAGES when none specified" time="0.00036747">
        </testcase>
        <testcase classname="test/unit/cli-parse.test.js" name="parseCliArgsSafe — kind:&quot;help&quot; &gt; returns kind:&quot;help&quot; for --help" time="0.000161762">
        </testcase>
        <testcase classname="test/unit/cli-parse.test.js" name="parseCliArgsSafe — kind:&quot;help&quot; &gt; returns kind:&quot;help&quot; for -h shorthand" time="0.000140561">
        </testcase>
        <testcase classname="test/unit/cli-parse.test.js" name="parseCliArgsSafe — kind:&quot;help&quot; &gt; short-circuits even when other flags follow --help" time="0.000148252">
        </testcase>
        <testcase classname="test/unit/cli-parse.test.js" name="parseCliArgsSafe — kind:&quot;help&quot; &gt; exposes HELP_TEXT as a non-empty string with all documented aliases" time="0.00082053">
        </testcase>
        <testcase classname="test/unit/cli-parse.test.js" name="parseCliArgsSafe — kind:&quot;error&quot; &gt; errors when neither --run nor --all is provided" time="0.000244727">
        </testcase>
        <testcase classname="test/unit/cli-parse.test.js" name="parseCliArgsSafe — kind:&quot;error&quot; &gt; errors when --run path does not exist" time="0.000185448">
        </testcase>
        <testcase classname="test/unit/cli-parse.test.js" name="parseCliArgsSafe — kind:&quot;error&quot; &gt; errors on unknown flags" time="0.00022016">
        </testcase>
        <testcase classname="test/unit/cli-parse.test.js" name="parseCliArgsSafe — kind:&quot;error&quot; &gt; errors on unsupported language codes" time="0.000203174">
        </testcase>
        <testcase classname="test/unit/cli-parse.test.js" name="parseCliArgsSafe — kind:&quot;error&quot; &gt; errors on malformed --since date" time="0.000201272">
        </testcase>
        <testcase classname="test/unit/cli-parse.test.js" name="parseCliArgsSafe — kind:&quot;error&quot; &gt; errors when a value-bearing flag has no value" time="0.000204927">
        </testcase>
        <testcase classname="test/unit/cli-parse.test.js" name="parseCliArgsSafe — kind:&quot;error&quot; &gt; errors when --title is provided without a value" time="0.000191137">
        </testcase>
        <testcase classname="test/unit/cli-parse.test.js" name="parseCliArgsSafe — kind:&quot;error&quot; &gt; errors when an inline `--flag=` form has an empty value" time="0.000195913">
        </testcase>
        <testcase classname="test/unit/cli-parse.test.js" name="parseCliArgsSafe — kind:&quot;error&quot; &gt; errors on empty inline value for --lang=" time="0.000168883">
        </testcase>
        <testcase classname="test/unit/cli-parse.test.js" name="parseCliArgsSafe — kind:&quot;error&quot; &gt; errors on empty inline value for --since=" time="0.000156845">
        </testcase>
        <testcase classname="test/unit/cli-parse.test.js" name="parseCliArgsSafe — kind:&quot;error&quot; &gt; does not call process.exit on --help (testable without spy)" time="0.000123825">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/content-metadata.test.js" timestamp="2026-04-28T00:15:08.199Z" hostname="runnervmeorf1" tests="15" failures="0" errors="0" skipped="0" time="0.015016976">
        <testcase classname="test/unit/content-metadata.test.js" name="content-metadata &gt; enrichMetadataFromContent &gt; should enrich title with content-derived heading when available" time="0.004738602">
        </testcase>
        <testcase classname="test/unit/content-metadata.test.js" name="content-metadata &gt; enrichMetadataFromContent &gt; should use lede paragraph as description" time="0.000808382">
        </testcase>
        <testcase classname="test/unit/content-metadata.test.js" name="content-metadata &gt; enrichMetadataFromContent &gt; should use section lede paragraph as description" time="0.000454661">
        </testcase>
        <testcase classname="test/unit/content-metadata.test.js" name="content-metadata &gt; enrichMetadataFromContent &gt; should fall back to base subtitle when content has no lede" time="0.000789414">
        </testcase>
        <testcase classname="test/unit/content-metadata.test.js" name="content-metadata &gt; enrichMetadataFromContent &gt; should extract committee abbreviations as keywords" time="0.001141651">
        </testcase>
        <testcase classname="test/unit/content-metadata.test.js" name="content-metadata &gt; enrichMetadataFromContent &gt; should extract political group names as keywords" time="0.000656404">
        </testcase>
        <testcase classname="test/unit/content-metadata.test.js" name="content-metadata &gt; enrichMetadataFromContent &gt; should extract headings as keywords" time="0.000252388">
        </testcase>
        <testcase classname="test/unit/content-metadata.test.js" name="content-metadata &gt; enrichMetadataFromContent &gt; should extract headings with nested markup" time="0.00083412">
        </testcase>
        <testcase classname="test/unit/content-metadata.test.js" name="content-metadata &gt; enrichMetadataFromContent &gt; should preserve base keywords" time="0.00057364">
        </testcase>
        <testcase classname="test/unit/content-metadata.test.js" name="content-metadata &gt; enrichMetadataFromContent &gt; should preserve base category" time="0.000244366">
        </testcase>
        <testcase classname="test/unit/content-metadata.test.js" name="content-metadata &gt; enrichMetadataFromContent &gt; should not modify title if it already has a long suffix" time="0.000265829">
        </testcase>
        <testcase classname="test/unit/content-metadata.test.js" name="content-metadata &gt; enrichMetadataFromContent &gt; should extract statistics from content for title suffix" time="0.000436915">
        </testcase>
        <testcase classname="test/unit/content-metadata.test.js" name="content-metadata &gt; enrichMetadataFromContent &gt; should limit description to 200 characters" time="0.000277737">
        </testcase>
        <testcase classname="test/unit/content-metadata.test.js" name="content-metadata &gt; enrichMetadataFromContent &gt; should limit keywords to 15" time="0.000303305">
        </testcase>
        <testcase classname="test/unit/content-metadata.test.js" name="content-metadata &gt; enrichMetadataFromContent &gt; should deduplicate keywords" time="0.000185458">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/ep-mcp-client.test.js" timestamp="2026-04-28T00:15:08.201Z" hostname="runnervmeorf1" tests="286" failures="0" errors="0" skipped="0" time="0.732678397">
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Constructor &gt; should initialize with default options" time="0.004133175">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Constructor &gt; should default serverPath to npm package binary in node_modules/.bin" time="0.000563654">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Constructor &gt; should accept custom options" time="0.000388803">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Constructor &gt; should use environment variable for server path" time="0.000276534">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Constructor &gt; should initialize pending requests map" time="0.000403004">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Connection Management &gt; should use serverPath as binary command (not node with script argument)" time="0.000579829">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Connection Management &gt; should handle connection behavior consistently" time="0.508387178">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Connection Management &gt; should not reconnect if already connected" time="0.000392849">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Connection Management &gt; should disconnect properly" time="0.00442365">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Connection Management &gt; should handle disconnect when not connected" time="0.000423806">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Message Handling &gt; should handle valid JSON response messages" time="0.00272911">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Message Handling &gt; should handle error response messages" time="0.000491006">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Message Handling &gt; should handle notification messages without id" time="0.001376313">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Message Handling &gt; should handle invalid JSON gracefully" time="0.000469463">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Message Handling &gt; should ignore messages for unknown request IDs" time="0.000495873">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Request Sending &gt; should throw error when not connected" time="0.001385347">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Request Sending &gt; should increment request ID" time="0.000402934">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Request Sending &gt; should format request correctly" time="0.000728372">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Tool Operations &gt; should list tools" time="0.000490265">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Tool Operations &gt; should call tool with arguments" time="0.000954912">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Tool Operations &gt; should get MEPs" time="0.000812057">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Tool Operations &gt; should reject array arguments in callTool" time="0.000352829">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should get MEPs with options" time="0.000604516">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should handle missing getMEPs tool gracefully" time="0.000859558">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should get plenary sessions" time="0.000484946">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should pass dateFrom and dateTo directly in getPlenarySessions" time="0.000378638">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should pass year parameter in getPlenarySessions" time="0.000521502">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should handle missing plenary sessions tool gracefully" time="0.000426158">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should pass date filters through and return plenary sessions unchanged without local filtering" time="0.000779868">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should return plenary session totals unchanged without fixing mismatched counts" time="0.001442522">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should search documents" time="0.000575182">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should pass keyword directly to MCP tool without renaming in searchDocuments" time="0.002696932">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should handle missing search documents tool gracefully" time="0.000398277">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should get parliamentary questions" time="0.000572197">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should pass dateFrom directly in getParliamentaryQuestions" time="0.000434381">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should handle missing parliamentary questions tool gracefully" time="0.000375072">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should get committee info" time="0.00041404">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should handle missing committee info tool gracefully" time="0.000346559">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should monitor legislative pipeline" time="0.001668751">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should pass no dates to the underlying tool when none supplied (opts-in to server default)" time="0.000705828">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should handle missing legislative pipeline tool gracefully" time="0.001010164">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should get MEP details" time="0.000456324">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should handle missing get_mep_details tool gracefully" time="0.000418918">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should return null fallback for empty id in getMEPDetails" time="0.00041351">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should return null fallback for whitespace-only id in getMEPDetails" time="0.000701211">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should get voting records" time="0.000449554">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should handle missing get_voting_records tool gracefully" time="0.00041369">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should analyze voting patterns" time="0.000532147">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should handle missing analyze_voting_patterns tool gracefully" time="0.000582183">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should return null fallback for empty mepId in analyzeVotingPatterns" time="0.00041368">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should return null fallback for whitespace-only mepId in analyzeVotingPatterns" time="0.0003737">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should track legislation" time="0.000482413">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should handle missing track_legislation tool gracefully" time="0.000412969">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should return null fallback for empty procedureId in trackLegislation" time="0.000403845">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should return null fallback for whitespace-only procedureId in trackLegislation" time="0.000954581">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should generate report" time="0.000527069">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should handle missing generate_report tool gracefully" time="0.000433029">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should return null fallback for empty reportType in generateReport" time="0.000350635">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should return null fallback for whitespace-only reportType in generateReport" time="0.000512298">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; OSINT Intelligence Methods &gt; should assess MEP influence" time="0.00068048">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; OSINT Intelligence Methods &gt; should handle missing assess MEP influence tool gracefully" time="0.000428032">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; OSINT Intelligence Methods &gt; should return fallback for assessMEPInfluence with blank mepId" time="0.00040057">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; OSINT Intelligence Methods &gt; should analyze coalition dynamics" time="0.000552007">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; OSINT Intelligence Methods &gt; should handle missing analyze coalition dynamics tool gracefully" time="0.000364005">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; OSINT Intelligence Methods &gt; should pass PPE alias unchanged to server (v1.2.14+ canonicalization)" time="0.00080749">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; OSINT Intelligence Methods &gt; should return EPP group with non-zero memberCount when MCP server resolves PPE alias (v1.2.14+)" time="0.00082102">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; OSINT Intelligence Methods &gt; should detect voting anomalies" time="0.000411938">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; OSINT Intelligence Methods &gt; should handle missing detect voting anomalies tool gracefully" time="0.000408813">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; OSINT Intelligence Methods &gt; should compare political groups" time="0.000539678">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; OSINT Intelligence Methods &gt; should handle missing compare political groups tool gracefully" time="0.000435172">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; OSINT Intelligence Methods &gt; should return fallback for comparePoliticalGroups with empty groups" time="0.000376544">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; OSINT Intelligence Methods &gt; should analyze legislative effectiveness" time="0.00080707">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; OSINT Intelligence Methods &gt; should handle missing analyze legislative effectiveness tool gracefully" time="0.000399048">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; OSINT Intelligence Methods &gt; should return fallback for analyzeLegislativeEffectiveness with blank subjectId" time="0.000431026">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; OSINT Intelligence Methods &gt; should analyze committee activity" time="0.000525598">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; OSINT Intelligence Methods &gt; should handle missing analyze_committee_activity tool gracefully" time="0.000405358">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; OSINT Intelligence Methods &gt; should track MEP attendance" time="0.000409574">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; OSINT Intelligence Methods &gt; should handle missing track_mep_attendance tool gracefully" time="0.000387441">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; OSINT Intelligence Methods &gt; should analyze country delegation" time="0.000952327">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; OSINT Intelligence Methods &gt; should handle missing analyze_country_delegation tool gracefully" time="0.00045375">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; OSINT Intelligence Methods &gt; should return fallback for analyzeCountryDelegation with empty country" time="0.001653639">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; OSINT Intelligence Methods &gt; should generate political landscape" time="0.00050063">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; OSINT Intelligence Methods &gt; should handle missing generate_political_landscape tool gracefully" time="0.000412358">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should get current MEPs" time="0.000516053">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should handle missing get_current_meps tool gracefully" time="0.000560229">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should get speeches" time="0.000499799">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should handle missing get_speeches tool gracefully" time="0.000478958">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should get procedures" time="0.000451026">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should handle missing get_procedures tool gracefully" time="0.000425178">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should get adopted texts" time="0.000485147">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should handle missing get_adopted_texts tool gracefully" time="0.000810574">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should get events" time="0.000477696">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should handle missing get_events tool gracefully" time="0.000498728">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should get meeting activities" time="0.000804365">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should handle missing get_meeting_activities tool gracefully" time="0.001011085">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should return fallback for getMeetingActivities with empty sittingId" time="0.000457386">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should return fallback for getMeetingActivities with whitespace sittingId" time="0.000463975">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should get meeting decisions" time="0.000503645">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should handle missing get_meeting_decisions tool gracefully" time="0.000650465">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should return fallback for getMeetingDecisions with empty sittingId" time="0.000465077">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should return fallback for getMeetingDecisions with whitespace sittingId" time="0.000505908">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should get MEP declarations" time="0.000452699">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should handle missing get_mep_declarations tool gracefully" time="0.000462503">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should get incoming MEPs" time="0.000816644">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should handle missing get_incoming_meps tool gracefully" time="0.00046679">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should get outgoing MEPs" time="0.000637075">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should handle missing get_outgoing_meps tool gracefully" time="0.000570906">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should get homonym MEPs" time="0.000648882">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should handle missing get_homonym_meps tool gracefully" time="0.000587631">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should get plenary documents" time="0.000548602">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should handle missing get_plenary_documents tool gracefully" time="0.000571957">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should get committee documents" time="0.000497986">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should handle missing get_committee_documents tool gracefully" time="0.00051371">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should get plenary session documents" time="0.000615362">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should handle missing get_plenary_session_documents tool gracefully" time="0.000512718">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should get plenary session document items" time="0.000522413">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should handle missing get_plenary_session_document_items tool gracefully" time="0.000515372">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should get controlled vocabularies" time="0.000488212">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should handle missing get_controlled_vocabularies tool gracefully" time="0.000520039">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should get external documents" time="0.000451147">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should handle missing get_external_documents tool gracefully" time="0.000775132">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should get meeting foreseen activities" time="0.000562934">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should handle missing get_meeting_foreseen_activities tool gracefully" time="0.000498487">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should return fallback for getMeetingForeseenActivities with empty sittingId" time="0.000549494">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should return fallback for getMeetingForeseenActivities with whitespace sittingId" time="0.000628632">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should get procedure events" time="0.000633069">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should handle missing get_procedure_events tool gracefully" time="0.000483685">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should return fallback for getProcedureEvents with empty processId" time="0.000545187">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should return fallback for getProcedureEvents with whitespace-only processId" time="0.000451536">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should get meeting plenary session documents" time="0.000615503">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should handle missing get_meeting_plenary_session_documents tool gracefully" time="0.000565237">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should return fallback for getMeetingPlenarySessionDocuments with empty sittingId" time="0.000487921">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should return fallback for getMeetingPlenarySessionDocuments with whitespace sittingId" time="0.000565167">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should get meeting plenary session document items" time="0.000527601">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should handle missing get_meeting_plenary_session_document_items tool gracefully" time="0.00067379">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should return fallback for getMeetingPlenarySessionDocumentItems with empty sittingId" time="0.000482153">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Open Data Portal Methods &gt; should return fallback for getMeetingPlenarySessionDocumentItems with whitespace sittingId" time="0.000524466">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Phase 6 OSINT Intelligence Methods &gt; should run network analysis" time="0.000695292">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Phase 6 OSINT Intelligence Methods &gt; should handle missing network_analysis tool gracefully" time="0.000521442">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Phase 6 OSINT Intelligence Methods &gt; should run sentiment tracker" time="0.000579819">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Phase 6 OSINT Intelligence Methods &gt; should handle missing sentiment_tracker tool gracefully" time="0.000512808">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Phase 6 OSINT Intelligence Methods &gt; should run early warning system" time="0.000677786">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Phase 6 OSINT Intelligence Methods &gt; should handle missing early_warning_system tool gracefully" time="0.000697836">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Phase 6 OSINT Intelligence Methods &gt; should run comparative intelligence" time="0.000641832">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Phase 6 OSINT Intelligence Methods &gt; should handle missing comparative_intelligence tool gracefully" time="0.000497295">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Phase 6 OSINT Intelligence Methods &gt; should return fallback for comparativeIntelligence with insufficient mepIds" time="0.000535192">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Phase 6 OSINT Intelligence Methods &gt; should return fallback for comparativeIntelligence with empty mepIds" time="0.00043416">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Phase 6 OSINT Intelligence Methods &gt; should run correlate intelligence" time="0.000458066">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Phase 6 OSINT Intelligence Methods &gt; should return fallback for correlateIntelligence with empty mepIds" time="0.000397275">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Precomputed Statistics &gt; should get all generated stats with default options" time="0.000418567">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Precomputed Statistics &gt; should get all generated stats with custom options" time="0.000472328">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Precomputed Statistics &gt; should handle missing get_all_generated_stats tool gracefully" time="0.000457065">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Precomputed Statistics &gt; should pass category filter correctly" time="0.000526308">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; EP API v2 Feed Endpoint Methods &gt; should get MEPs feed with default options" time="0.000502994">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; EP API v2 Feed Endpoint Methods &gt; should handle missing get_meps_feed tool gracefully" time="0.000869463">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; EP API v2 Feed Endpoint Methods &gt; should get events feed with pagination" time="0.000683454">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; EP API v2 Feed Endpoint Methods &gt; should handle missing get_events_feed tool gracefully" time="0.000528452">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; EP API v2 Feed Endpoint Methods &gt; should get procedures feed" time="0.00068778">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; EP API v2 Feed Endpoint Methods &gt; should handle missing get_procedures_feed tool gracefully" time="0.000600299">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; EP API v2 Feed Endpoint Methods &gt; should get adopted texts feed" time="0.000632418">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; EP API v2 Feed Endpoint Methods &gt; should handle missing get_adopted_texts_feed tool gracefully" time="0.000571066">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; EP API v2 Feed Endpoint Methods &gt; should get MEP declarations feed" time="0.000517947">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; EP API v2 Feed Endpoint Methods &gt; should handle missing get_mep_declarations_feed tool gracefully" time="0.000541332">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; EP API v2 Feed Endpoint Methods &gt; should get documents feed" time="0.001554861">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; EP API v2 Feed Endpoint Methods &gt; should handle missing get_documents_feed tool gracefully" time="0.000482052">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; EP API v2 Feed Endpoint Methods &gt; should get plenary documents feed" time="0.000406739">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; EP API v2 Feed Endpoint Methods &gt; should handle missing get_plenary_documents_feed tool gracefully" time="0.000575463">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; EP API v2 Feed Endpoint Methods &gt; should get committee documents feed" time="0.000479229">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; EP API v2 Feed Endpoint Methods &gt; should handle missing get_committee_documents_feed tool gracefully" time="0.000405598">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; EP API v2 Feed Endpoint Methods &gt; should get plenary session documents feed" time="0.000364346">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; EP API v2 Feed Endpoint Methods &gt; should handle missing get_plenary_session_documents_feed tool gracefully" time="0.000421311">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; EP API v2 Feed Endpoint Methods &gt; should get external documents feed" time="0.000370355">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; EP API v2 Feed Endpoint Methods &gt; should handle missing get_external_documents_feed tool gracefully" time="0.000905818">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; EP API v2 Feed Endpoint Methods &gt; should get parliamentary questions feed" time="0.000571096">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; EP API v2 Feed Endpoint Methods &gt; should handle missing get_parliamentary_questions_feed tool gracefully" time="0.000432708">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; EP API v2 Feed Endpoint Methods &gt; should get corporate bodies feed" time="0.000465257">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; EP API v2 Feed Endpoint Methods &gt; should handle missing get_corporate_bodies_feed tool gracefully" time="0.000627691">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; EP API v2 Feed Endpoint Methods &gt; should get controlled vocabularies feed" time="0.000437726">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; EP API v2 Feed Endpoint Methods &gt; should handle missing get_controlled_vocabularies_feed tool gracefully" time="0.000409484">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Retry Logic &gt; should have retry configuration" time="0.000315784">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; Retry Logic &gt; should reset connection attempts on success" time="0.000378928">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; Singleton Functions &gt; should create singleton client instance" time="0.000943093">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; Singleton Functions &gt; should close singleton client" time="0.000638918">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; Singleton Functions &gt; should handle closing when no client exists" time="0.000810465">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; Gateway Mode &gt; should detect gateway mode from constructor options" time="0.000412919">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; Gateway Mode &gt; should detect gateway mode from environment variables" time="0.000451897">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; Gateway Mode &gt; should default to stdio mode when no gateway configured" time="0.000415022">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; Gateway Mode &gt; should prefer explicit gatewayUrl over environment variable" time="0.000425007">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; Gateway Mode &gt; should store gateway API key from options" time="0.000485758">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; Gateway Mode &gt; should store gateway API key from environment" time="0.000369453">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; Gateway Mode &gt; should handle gateway connection failure gracefully" time="0.001211576">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; Gateway Mode &gt; should clear session on disconnect in gateway mode" time="0.000742393">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getFailedTools &gt; should return an empty map when no tools have failed" time="0.000526409">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getFailedTools &gt; should return a defensive copy that cannot mutate internal state" time="0.000402664">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getFailedTools &gt; should record a timeout failure after safeCallTool catches a timeout error" time="0.001187059">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getFailedTools &gt; should record a NOT_FOUND failure for 404 errors" time="0.000576243">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getFailedTools &gt; should record a SERVER_ERROR failure for 502 errors" time="0.000523364">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getFailedTools &gt; should classify &quot;Gateway Timeout&quot; (504) as SERVER_ERROR not TIMEOUT" time="0.000592669">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getFailedTools &gt; should classify rate limit (429) errors as RATE_LIMIT" time="0.000630095">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getFailedTools &gt; should clear a tool from failed map when a subsequent call succeeds" time="0.000651887">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getFailedTools &gt; should record an INTERNAL_ERROR failure when isError is true with INTERNAL_ERROR content" time="0.000659418">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getFailedTools &gt; should record a SERVER_ERROR failure when isError is true with UPSTREAM_500 content" time="0.000641231">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getFailedTools &gt; should record an UNKNOWN failure when isError is true with empty content" time="0.000565417">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getFeedHealthSummary &gt; should show all feeds as unchecked when no calls have been made" time="0.00076708">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getFeedHealthSummary &gt; should show operational feeds as ✅ after successful calls" time="0.000544957">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getFeedHealthSummary &gt; should show failed feeds with ❌ markers and reduce operational count" time="0.000838256">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; isFeedUnavailable and raw-404 detection (upstream #378) &gt; should record raw upstream 404 envelope as NOT_FOUND failure for get_events_feed" time="0.000705157">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; isFeedUnavailable and raw-404 detection (upstream #378) &gt; should record uniform {status:&quot;unavailable&quot;} envelope as NOT_FOUND failure" time="0.000632678">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; isFeedUnavailable and raw-404 detection (upstream #378) &gt; should not flag well-formed feed results with {&quot;data&quot;: [...]} as unavailable" time="0.000630575">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; isFeedUnavailable and raw-404 detection (upstream #378) &gt; should not flag results with malformed JSON text as unavailable" time="0.000523554">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getEventsFeed timeout downgrade (slow-feed warning, §11 row #8) &gt; should downgrade a timeout to a slow-feed warning (not recorded in failedTools)" time="0.000683865">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getEventsFeed timeout downgrade (slow-feed warning, §11 row #8) &gt; should return a fallback result with slowFeedWarning:true on timeout" time="0.000601322">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getEventsFeed timeout downgrade (slow-feed warning, §11 row #8) &gt; should NOT downgrade a 404 error — it still goes to failedTools" time="0.000549804">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getEventsFeed timeout downgrade (slow-feed warning, §11 row #8) &gt; should NOT downgrade a 5xx error — it still goes to failedTools" time="0.000575622">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getEventsFeed timeout downgrade (slow-feed warning, §11 row #8) &gt; should show 🟡 in getFeedHealthSummary for a slow-feed timeout" time="0.000590195">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getEventsFeed timeout downgrade (slow-feed warning, §11 row #8) &gt; should emit a 🟡 console warning on timeout" time="0.000579478">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getEventsFeed timeout downgrade (slow-feed warning, §11 row #8) &gt; should return the returned map copy independent of internal state" time="0.000441862">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getEventsFeed timeout downgrade (slow-feed warning, §11 row #8) &gt; getToolErrorSummary should still report other feed errors but not the slow timeout" time="0.000801922">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getEventsFeed timeout downgrade (slow-feed warning, §11 row #8) &gt; should NOT downgrade a 504 &quot;Gateway Timeout&quot; — classified as SERVER_ERROR" time="0.000589193">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getEventsFeed timeout downgrade (slow-feed warning, §11 row #8) &gt; should clear a prior slow-feed warning when a subsequent call succeeds" time="0.000588883">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getEventsFeed timeout downgrade (slow-feed warning, §11 row #8) &gt; should clear a prior failure entry when a subsequent timeout downgrades to slow-feed" time="0.000681932">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getEventsFeed timeout downgrade (slow-feed warning, §11 row #8) &gt; should clear a prior slow-feed warning when a subsequent non-timeout failure occurs" time="0.008445678">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getProceduresFeed recess-mode detection (§11 row #5) &gt; should add recessMode:true when all items are pre-1995 (historical archive)" time="0.000987781">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getProceduresFeed recess-mode detection (§11 row #5) &gt; should emit a 🟡 console warning on recess mode" time="0.000521932">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getProceduresFeed recess-mode detection (§11 row #5) &gt; should NOT set recessMode when items contain current-year procedures" time="0.000440641">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getProceduresFeed recess-mode detection (§11 row #5) &gt; should NOT set recessMode on an empty items array" time="0.000375643">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getProceduresFeed recess-mode detection (§11 row #5) &gt; should NOT record get_procedures_feed as failed when recess mode is detected" time="0.000529854">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getProceduresFeed recess-mode detection (§11 row #5) &gt; should also detect recess mode via procedures[] shape" time="0.000464466">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getProceduresFeed recess-mode detection (§11 row #5) &gt; should preserve existing dataQualityWarnings when appending RECESS_MODE" time="0.000651156">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; detectProceduresFeedRecessMode helper function &gt; should return false for undefined payload" time="0.000632658">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; detectProceduresFeedRecessMode helper function &gt; should return false for empty items array" time="0.000452548">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; detectProceduresFeedRecessMode helper function &gt; should return true for all-pre-1995 items (via dateInitiated)" time="0.000316624">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; detectProceduresFeedRecessMode helper function &gt; should return true for items using reference field (1990/0001 pattern)" time="0.000277245">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; detectProceduresFeedRecessMode helper function &gt; should return false when any item has a post-1995 year" time="0.00026073">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; detectProceduresFeedRecessMode helper function &gt; should return false when all items lack date fields" time="0.000320831">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; detectProceduresFeedRecessMode helper function &gt; should handle procedures[] shape" time="0.000274161">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; detectProceduresFeedRecessMode helper function &gt; should use dateLastActivity as fallback when dateInitiated is absent" time="0.000255713">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; detectProceduresFeedRecessMode helper function &gt; should return false for borderline 1996 year (just above threshold)" time="0.000783745">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; detectProceduresFeedRecessMode helper function &gt; should return true for borderline 1995 year (exactly at threshold)" time="0.000310366">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getAdoptedTexts empty-string sentinel (upstream #369) &gt; should record CONTENT_PENDING failure when docId lookup returns all-empty-string sentinel" time="0.004917129">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getAdoptedTexts empty-string sentinel (upstream #369) &gt; should write the docId to the pending-documents sidecar on empty-string sentinel" time="0.005835526">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getAdoptedTexts empty-string sentinel (upstream #369) &gt; should NOT record failure for a year-range list query (no docId)" time="0.000737936">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getAdoptedTexts empty-string sentinel (upstream #369) &gt; should NOT record failure when docId lookup returns populated fields" time="0.000728332">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getAdoptedTexts empty-string sentinel (upstream #369) &gt; should NOT flag sparse payloads with fewer than 3 string fields (avoid false positives)" time="0.000786699">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getAdoptedTextsFeed FRESHNESS_FALLBACK warning handling &gt; should forward FRESHNESS_FALLBACK warning into dataFreshnessWarnings and set freshness=augmented" time="0.001021601">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getAdoptedTextsFeed FRESHNESS_FALLBACK warning handling &gt; should preserve multiple FRESHNESS_FALLBACK warnings in dataFreshnessWarnings" time="0.000717365">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getAdoptedTextsFeed FRESHNESS_FALLBACK warning handling &gt; should escalate FRESHNESS_FALLBACK_FAILED to ANALYSIS_ONLY tool failure" time="0.000664966">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getAdoptedTextsFeed FRESHNESS_FALLBACK warning handling &gt; should return unchanged result when no FRESHNESS_FALLBACK warnings present" time="0.000483965">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getAdoptedTextsFeed FRESHNESS_FALLBACK warning handling &gt; should return unchanged result when dataQualityWarnings is absent" time="0.000461071">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getAdoptedTextsFeed FRESHNESS_FALLBACK warning handling &gt; should return fallback when tool call throws" time="0.000504726">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getAdoptedTextsFeed FRESHNESS_FALLBACK warning handling &gt; should pick the FAILED warning specifically when FAILED and non-FAILED FRESHNESS_FALLBACK warnings co-exist" time="0.000537966">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getAdoptedTextsFeed FRESHNESS_FALLBACK warning handling &gt; should preserve isError and additional content items when augmenting freshness" time="0.000805297">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getToolErrorSummary &gt; should report &quot;all operational&quot; when no failures recorded" time="0.0004866">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getToolErrorSummary &gt; should group failures by error code" time="0.000595302">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getToolErrorSummary &gt; should expose the raw-404 envelope as NOT_FOUND in the summary" time="0.000417125">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getProcedureEventById &gt; should get a specific procedure event by id" time="0.001208572">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getProcedureEventById &gt; should handle missing get_procedure_event_by_id tool gracefully" time="0.000528692">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getProcedureEventById &gt; should return fallback for getProcedureEventById with empty processId" time="0.000414371">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getProcedureEventById &gt; should return fallback for getProcedureEventById with empty eventId" time="0.000443805">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getProcedureEventById &gt; should return fallback for getProcedureEventById with whitespace-only processId" time="0.000403144">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getProcedureEventById &gt; should trim processId and eventId" time="0.000470495">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getServerHealth &gt; should get server health with no arguments" time="0.000568362">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getServerHealth &gt; should handle missing get_server_health tool gracefully" time="0.000455473">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getFreshProcedures &gt; should call get_procedures with default limit=100" time="0.001603473">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getFreshProcedures &gt; should call get_procedures with custom limit" time="0.000642503">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getFreshProcedures &gt; should return empty procedures when the API returns empty list" time="0.000571757">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getFreshProcedures &gt; should sort procedures by dateLastActivity descending" time="0.011773936">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getFreshProcedures &gt; should fall back to dateInitiated when dateLastActivity is empty" time="0.001150064">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getFreshProcedures &gt; should exclude procedures older than the windowDays cutoff" time="0.001165417">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getFreshProcedures &gt; should apply topN cap after sorting and filtering" time="0.001143765">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getFreshProcedures &gt; should persist procedure IDs to the seen-cache file" time="0.001323834">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getFreshProcedures &gt; should not write cache file when no procedures pass the window filter" time="0.000841662">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getFreshProcedures &gt; should skip procedures with empty id when writing to cache" time="0.000822172">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getFreshProcedures &gt; should handle get_procedures tool failure gracefully" time="0.000773889">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getFreshProcedures &gt; should handle malformed procedures payload gracefully" time="0.000572518">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getFreshProcedures &gt; should use default windowDays=30 when not specified" time="0.000877915">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getAdoptedTexts UPSTREAM_404 indexing-lag retry (Stage B) &gt; should reclassify UPSTREAM_404 &quot;document indexed but content not yet available&quot; as CONTENT_PENDING" time="0.002536211">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getAdoptedTexts UPSTREAM_404 indexing-lag retry (Stage B) &gt; should be case-insensitive when matching the indexing-lag message" time="0.001396292">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getAdoptedTexts UPSTREAM_404 indexing-lag retry (Stage B) &gt; should write the docId to the pending-documents sidecar" time="0.00174177">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getAdoptedTexts UPSTREAM_404 indexing-lag retry (Stage B) &gt; should NOT reclassify a plain NOT_FOUND error as CONTENT_PENDING" time="0.000781942">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getAdoptedTexts UPSTREAM_404 indexing-lag retry (Stage B) &gt; should NOT apply indexing-lag detection to year-range list queries (no docId)" time="0.000757425">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getAdoptedTexts UPSTREAM_404 indexing-lag retry (Stage B) &gt; should expose getDueAdoptedTextsForReprobe method" time="0.001525416">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getAdoptedTexts UPSTREAM_404 indexing-lag retry (Stage B) &gt; should expose resolveAdoptedText method" time="0.002681369">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getAdoptedTexts UPSTREAM_404 indexing-lag retry (Stage B) &gt; should expose escalateStalePendingDocuments method" time="0.000831797">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getAdoptedTexts UPSTREAM_404 indexing-lag retry (Stage B) &gt; should expose getPendingDocumentsSummary method" time="0.001012607">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getAdoptedTexts UPSTREAM_404 indexing-lag retry (Stage B) &gt; should detect the message when delivered via isError:true response body" time="0.001249893">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/ep-open-data-client.test.js" timestamp="2026-04-28T00:15:08.248Z" hostname="runnervmeorf1" tests="40" failures="0" errors="0" skipped="0" time="0.039697115">
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; EP_OPEN_DATA_TOOLS drift guard &gt; exposes exactly the one virtual tool name" time="0.003723561">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; EP_OPEN_DATA_TOOLS drift guard &gt; is a readonly array of strings" time="0.00044043">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; EPOpenDataPortalClient alias &gt; is the same class as EPOpenDataClient" time="0.000281132">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; EPOpenDataClient construction &gt; uses the default EP Open Data base URL and timeout" time="0.001922962">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; EPOpenDataClient construction &gt; honours EP_OPEN_DATA_BASE_URL env var and strips trailing slashes" time="0.001060519">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; EPOpenDataClient construction &gt; honours EP_OPEN_DATA_TIMEOUT_MS env var" time="0.001011136">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; EPOpenDataClient construction &gt; prefers explicit options over env vars" time="0.000857645">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; EPOpenDataClient construction &gt; ignores a malformed timeout env var and falls back to the default" time="0.001971024">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; EPOpenDataClient construction &gt; connect() accepts a valid base URL and disconnect() clears it" time="0.001136833">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; EPOpenDataClient construction &gt; connect() rejects a malformed base URL" time="0.004440114">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; getVotingRecords &gt; requests /decision with correct query parameters and normalises the response" time="0.004868968">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; getVotingRecords &gt; extracts identifier from @id URI when identifier field is absent" time="0.000627821">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; getVotingRecords &gt; returns empty votes on empty data array" time="0.000636654">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; getVotingRecords &gt; returns empty-votes fallback without calling fetch when dateFrom is missing" time="0.000668912">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; getVotingRecords &gt; returns empty-votes fallback without calling fetch when dateTo is missing" time="0.00048695">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; getVotingRecords &gt; returns empty-votes fallback on HTTP error" time="0.000488101">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; getVotingRecords &gt; returns empty-votes fallback on network error" time="0.000872097">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; getVotingRecords &gt; returns empty-votes fallback on non-JSON response" time="0.000479659">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; getVotingRecords &gt; uses Accept header for JSON-LD" time="0.000497065">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; isVotingDataEmpty (static) &gt; returns true for empty votes array" time="0.000371927">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; isVotingDataEmpty (static) &gt; returns false for non-empty votes array" time="0.000238978">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; isVotingDataEmpty (static) &gt; returns true for {&quot;votes&quot;:null}" time="0.000217195">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; isVotingDataEmpty (static) &gt; returns true for missing content array" time="0.000171868">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; isVotingDataEmpty (static) &gt; returns true for empty content text" time="0.000251928">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; isVotingDataEmpty (static) &gt; returns true for non-JSON content text" time="0.000207271">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; isVotingDataEmpty (static) &gt; returns true for the 🔴 unavailability marker (votes:[]) shape" time="0.000264677">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; buildVotingUnavailableMarker (static) &gt; returns an MCP-shaped result with empty votes array" time="0.000430746">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; buildVotingUnavailableMarker (static) &gt; includes the 🔴 marker string with the date window" time="0.000269023">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; buildVotingUnavailableMarker (static) &gt; includes a reason string with guidance on structural-proxy use" time="0.000284557">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; getVotingRecordsWithFallback — three-state decision tree &gt; (a) uses MCP result when it contains non-empty votes" time="0.0007742">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; getVotingRecordsWithFallback — three-state decision tree &gt; (b) falls back to EP Open Data Portal when MCP returns empty" time="0.000815041">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; getVotingRecordsWithFallback — three-state decision tree &gt; (c) emits 🔴 unavailability marker when both MCP and portal are empty" time="0.000808412">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; getVotingRecordsWithFallback — three-state decision tree &gt; (c) also emits 🔴 marker when portal fetch errors out" time="0.000590224">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; getVotingRecordsWithFallback — three-state decision tree &gt; propagates limit option to the portal query string" time="0.000935392">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; getVotingRecordsWithFallback — three-state decision tree &gt; throws when dateFrom is missing (avoids misleading freshness label)" time="0.000541571">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; getVotingRecordsWithFallback — three-state decision tree &gt; throws when dateTo is missing (avoids misleading freshness label)" time="0.000725116">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; getVotingRecordsWithFallback — three-state decision tree &gt; throws a configuration error when EP_OPEN_DATA_BASE_URL is malformed (vs. swallowing as unavailable)" time="0.000436204">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; Singleton lifecycle &gt; getEPOpenDataClient returns a connected singleton" time="0.000363895">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; Singleton lifecycle &gt; closeEPOpenDataClient disconnects and clears the singleton" time="0.000605377">
        </testcase>
        <testcase classname="test/unit/ep-open-data-client.test.js" name="ep-open-data-client &gt; Singleton lifecycle &gt; getEPOpenDataClient throws and clears singleton on malformed base URL" time="0.000443795">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/file-utils.test.js" timestamp="2026-04-28T00:15:08.254Z" hostname="runnervmeorf1" tests="68" failures="0" errors="0" skipped="0" time="0.082701717">
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; parseArticleFilename &gt; should parse valid article filename" time="0.00380319">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; parseArticleFilename &gt; should parse filename with complex slug" time="0.000752918">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; parseArticleFilename &gt; should return null for invalid filename" time="0.00063347">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; getNewsArticles &gt; should return empty array for non-existent directory" time="0.001463904">
            <system-out>
📁 News directory does not exist yet

            </system-out>
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; getNewsArticles &gt; should filter only article HTML files" time="0.003411102">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; groupArticlesByLanguage &gt; should group articles by language code" time="0.009180038">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; groupArticlesByLanguage &gt; should sort articles by date (newest first)" time="0.000526519">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; formatSlug &gt; should format slug to title case" time="0.000471767">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; formatSlug &gt; should handle single word" time="0.000505848">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; formatSlug &gt; should handle empty string" time="0.000415292">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; getModifiedDate &gt; should return YYYY-MM-DD format" time="0.000976904">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; formatDateForSlug &gt; should format current date as YYYY-MM-DD" time="0.000455142">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; formatDateForSlug &gt; should format specific date" time="0.000452729">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; calculateReadTime &gt; should calculate read time based on word count" time="0.00047998">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; calculateReadTime &gt; should return at least 1 minute" time="0.000402403">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; calculateReadTime &gt; should use custom words per minute" time="0.00038688">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; ensureDirectoryExists &gt; should create directory if it does not exist" time="0.000941851">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; ensureDirectoryExists &gt; should not throw if directory already exists" time="0.000482483">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; writeFileContent &gt; should write content to file and create parent dirs" time="0.000885176">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; writeFileContent &gt; should overwrite existing file" time="0.000870094">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; extractArticleMeta &gt; should extract title from h1 element" time="0.001515331">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; extractArticleMeta &gt; should extract description from meta description tag" time="0.000828953">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; extractArticleMeta &gt; should return empty strings for file with no matching elements" time="0.000716384">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; extractArticleMeta &gt; should decode HTML entities in extracted values" time="0.000723835">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; extractArticleMeta &gt; should use the first h1 when multiple h1 tags are present" time="0.000664156">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; extractArticleMeta &gt; should use the first meta description when multiple description tags are present" time="0.000718857">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; extractArticleMeta &gt; should handle malformed or unclosed tags gracefully" time="0.000781261">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; extractArticleMeta &gt; prefers &lt;head&gt;&lt;title&gt; (suffix stripped) over body &lt;h1&gt;" time="0.000988782">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; extractArticleMeta &gt; strips both em-dash and pipe site-suffix variants from &lt;title&gt;" time="0.001166037">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; extractArticleMeta &gt; falls back to body &lt;h1&gt; when &lt;title&gt; is empty or absent" time="0.000683364">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; extractArticleMeta &gt; should extract title when h1 has custom attributes" time="0.000646659">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; extractArticleMeta &gt; should return empty strings for non-existent file" time="0.000515122">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; atomicWrite &gt; should write content to a new file atomically" time="0.001304164">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; atomicWrite &gt; should overwrite existing file atomically" time="0.000998467">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; atomicWrite &gt; should create parent directories if they do not exist" time="0.00115417">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; atomicWrite &gt; should not leave a temp file after successful write" time="0.001057555">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; atomicWrite &gt; should produce a file with the exact expected content (no partial writes)" time="0.001062823">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; atomicWrite &gt; should handle EEXIST/EPERM fallback when renameSync cannot overwrite" time="0.005128586">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; atomicWrite &gt; should clean up temp file when all rename attempts fail" time="0.002051515">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; atomicWrite &gt; should log console.warn when temp cleanup fails with non-ENOENT error" time="0.001467339">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; checkArticleExists &gt; should return true when article file exists" time="0.000835422">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; checkArticleExists &gt; should return false when article file does not exist" time="0.000558597">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; checkArticleExists &gt; should return false when news directory does not exist" time="0.000412939">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; checkArticleExists &gt; should distinguish between different languages" time="0.000764676">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; discoverAnalysisFileEntries &gt; should return empty array for non-existent directory" time="0.000522834">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; discoverAnalysisFileEntries &gt; should discover .md files in known subdirectories" time="0.001876462">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; discoverAnalysisFileEntries &gt; should discover root-level .md files" time="0.001244976">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; discoverAnalysisFileEntries &gt; should discover files in documents/ subdirectory" time="0.001229212">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; discoverAnalysisFileEntries &gt; should ignore non-.md files" time="0.001610855">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; discoverAnalysisFileEntries &gt; should discover files across all known subdirectories" time="0.002797933">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; discoverAnalysisFileEntries &gt; should map known filenames to canonical method IDs" time="0.002057784">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; mergeManifestHistory &gt; creates a manifest with a history array when file does not exist" time="0.000902903">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; mergeManifestHistory &gt; appends to an existing history array without clobbering top-level fields" time="0.00121437">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; mergeManifestHistory &gt; recovers from a corrupt manifest by starting fresh" time="0.000958627">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; readLatestGateResult &gt; returns PENDING when the manifest does not exist" time="0.000449834">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; readLatestGateResult &gt; returns the gateResult from the last history entry" time="0.000559939">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; readLatestGateResult &gt; falls back to a top-level gateResult when history is missing (back-compat)" time="0.000586158">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; readLatestGateResult &gt; returns PENDING for an invalid/unknown gateResult" time="0.000551226">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; readLatestResolvedGateResult &gt; returns PENDING when the manifest does not exist" time="0.000583164">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; readLatestResolvedGateResult &gt; returns PENDING when all history entries are PENDING" time="0.000587791">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; readLatestResolvedGateResult &gt; skips a trailing PENDING to return the last resolved result (GREEN)" time="0.000526159">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; readLatestResolvedGateResult &gt; returns ANALYSIS_ONLY when that is the last resolved result" time="0.00087404">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; readLatestResolvedGateResult &gt; returns GREEN_WITH_WARNINGS when that is the last resolved result" time="0.000797255">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; readLatestResolvedGateResult &gt; returns PENDING for a missing or empty history" time="0.000589864">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; readLatestResolvedGateResult &gt; returns GREEN from top-level gateResult when history is absent (back-compat)" time="0.000584325">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; readLatestResolvedGateResult &gt; returns ANALYSIS_ONLY from top-level gateResult when history is absent (back-compat)" time="0.00067397">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; readLatestResolvedGateResult &gt; returns PENDING for top-level gateResult of PENDING (back-compat does not promote PENDING)" time="0.000562943">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; readLatestResolvedGateResult &gt; returns PENDING for corrupt JSON" time="0.000622483">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/forward-statements-registry.test.js" timestamp="2026-04-28T00:15:08.264Z" hostname="runnervmeorf1" tests="48" failures="0" errors="0" skipped="0" time="0.105534356">
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; shardPath &gt; should return YYYY-MM.jsonl path for a given date" time="0.003391683">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; shardPath &gt; should handle month boundaries" time="0.000618286">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; parseLine &gt; should parse a valid JSON line" time="0.001413809">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; parseLine &gt; should return null for blank lines" time="0.000571977">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; parseLine &gt; should return null for malformed JSON" time="0.000464996">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; newId &gt; should return a UUID v4 string" time="0.001072648">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; newId &gt; should return unique values on each call" time="0.000695192">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; validateEntry &gt; should return no errors for a valid entry" time="0.001835211">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; validateEntry &gt; should error when topic is missing" time="0.000963885">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; validateEntry &gt; should error when originatingDate is not YYYY-MM-DD" time="0.000524597">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; validateEntry &gt; should error when originatingDate is an impossible calendar date" time="0.000441742">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; validateEntry &gt; should accept YYYY-Www for expectedHorizon" time="0.001388261">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; validateEntry &gt; should reject out-of-range ISO weeks and impossible horizon dates" time="0.000592098">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; validateEntry &gt; should error when status is not in the allowed enum" time="0.000732518">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; validateEntry &gt; should error when evidenceRefs is not an array" time="0.000789343">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; validateEntry &gt; should error for null entry" time="0.00046682">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; appendEntries &gt; should write a JSONL shard and return { written: 1, errors: [] }" time="0.001018106">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; appendEntries &gt; should auto-generate an id if missing" time="0.000749394">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; appendEntries &gt; should preserve a provided id" time="0.000670875">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; appendEntries &gt; should default status to open when not provided" time="0.000695031">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; appendEntries &gt; should collect errors for invalid entries without aborting valid ones" time="0.00091443">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; appendEntries &gt; should append multiple entries to the same shard on the same date" time="0.000934621">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; appendEntries &gt; should write entries to different shards for different months" time="0.000904245">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; readEntries &gt; should return empty array when registry dir does not exist" time="0.000791356">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; readEntries &gt; should read all entries when no filters are applied" time="0.000890345">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; readEntries &gt; should filter by status" time="0.000920219">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; readEntries &gt; should apply status filters to canonical last-occurrence entries only" time="0.002393748">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; readEntries &gt; should filter by horizonFrom" time="0.001043545">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; readEntries &gt; should filter by horizonTo" time="0.000957556">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; readEntries &gt; should skip blank and malformed lines" time="0.000972908">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; readEntries &gt; should skip entries with missing or invalid horizons during filtered reads" time="0.00402347">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; updateEntry &gt; should append an update line and return { updated: true }" time="0.001172968">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; updateEntry &gt; should return last-occurrence semantics — updated status visible in readEntries" time="0.001178967">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; updateEntry &gt; should return { updated: false } for an unknown id" time="0.000536865">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; updateEntry &gt; should return { updated: false } for an invalid status" time="0.000778016">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; updateEntry &gt; should append evidenceRefs without duplicating existing refs" time="0.001879537">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; updateEntry &gt; should deduplicate evidenceRefs when the same ref is added twice" time="0.001185147">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; cli &gt; should append JSON entries from stdin via fd 0" time="0.053293872">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; buildSummary &gt; should include status counts" time="0.001465136">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; buildSummary &gt; should handle empty registry" time="0.000626238">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; normaliseHorizon &gt; should pass through YYYY-MM-DD unchanged" time="0.000417426">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; normaliseHorizon &gt; should convert ISO week to Monday date" time="0.000510746">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; normaliseHorizon &gt; should handle week 1 of a year" time="0.000451757">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; normaliseHorizon &gt; should throw for an out-of-range ISO week number" time="0.000995733">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; normaliseHorizon &gt; should throw for invalid calendar dates and malformed horizons" time="0.000782993">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; multi-day foreseen activities fan-out &gt; should generate session day IDs for a 4-day plenary week" time="0.001415481">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; multi-day foreseen activities fan-out &gt; should generate session day IDs for a 2-day mini-session" time="0.000597796">
        </testcase>
        <testcase classname="test/unit/forward-statements-registry.test.js" name="forward-statements-registry &gt; multi-day foreseen activities fan-out &gt; should detect a Monday run date for urgency motion sweep" time="0.000838777">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/generate-news-indexes.test.js" timestamp="2026-04-28T00:15:08.271Z" hostname="runnervmeorf1" tests="50" failures="0" errors="0" skipped="0" time="0.212626206">
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Article Filename Parsing &gt; should parse valid article filename" time="0.003975248">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Article Filename Parsing &gt; should parse filename with complex slug" time="0.000786479">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Article Filename Parsing &gt; should reject invalid date format" time="0.000538487">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Article Filename Parsing &gt; should reject missing language code" time="0.000517235">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Article Filename Parsing &gt; should reject invalid language code" time="0.000445388">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Article Grouping &gt; should group articles by language" time="0.001989852">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Article Grouping &gt; should sort articles by date (newest first)" time="0.012484381">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Slug Formatting &gt; should format slug to title case" time="0.000542263">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Slug Formatting &gt; should handle single word slug" time="0.000508112">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Slug Formatting &gt; should handle empty slug" time="0.000501612">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Index HTML Generation &gt; should generate valid HTML structure" time="0.001278796">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Index HTML Generation &gt; should include language-specific title" time="0.000748532">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Index HTML Generation &gt; should include language indicator" time="0.000413479">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Index HTML Generation &gt; should show &quot;no articles&quot; message when empty" time="0.00038053">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Index HTML Generation &gt; should list articles when present" time="0.000513329">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Index HTML Generation &gt; should include meta description" time="0.000475653">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Index HTML Generation &gt; should include stylesheet link" time="0.000342424">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Index HTML Generation &gt; should include footer with copyright" time="0.000505778">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Index HTML Generation &gt; should include skip navigation link" time="0.000339569">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Index HTML Generation &gt; should include main element with id" time="0.000464986">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Index HTML Generation &gt; should include security meta tags" time="0.000398206">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Index HTML Generation &gt; should use brand name in hero title without News suffix" time="0.000330815">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Index HTML Generation &gt; should include Open Graph meta tags" time="0.000449965">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Index HTML Generation &gt; should include hreflang alternate links" time="0.000355132">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Index HTML Generation &gt; should capitalize badge category text" time="0.000441402">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Multi-Language Support &gt; should support all Hack23 market languages" time="0.000435903">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Multi-Language Support &gt; should generate index for each language" time="0.00096047">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Multi-Language Support &gt; should use correct language names" time="0.001506728">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; File Operations &gt; should handle missing news directory" time="0.000489053">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; File Operations &gt; should filter HTML files correctly" time="0.002703822">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Edge Cases &gt; should handle article with no slug" time="0.000578888">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Edge Cases &gt; should handle very long slug" time="0.00057392">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Edge Cases &gt; should handle special characters in slug (already hyphenated)" time="0.000504245">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Real generateIndexHTML &gt; should include AI section with correct structure" time="0.002932085">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Real generateIndexHTML &gt; should include AI section quote element" time="0.000902112">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Real generateIndexHTML &gt; should include AI feature list with 4 items" time="0.000948962">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Real generateIndexHTML &gt; should include app version in footer" time="0.00075385">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Real generateIndexHTML &gt; should include disclaimer with link to GitHub issues" time="0.000708863">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Real generateIndexHTML &gt; should include AI section for all languages with localized content" time="0.004182097">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Real generateIndexHTML &gt; should not include lang=&quot;en&quot; override on AI section for non-English pages" time="0.000829433">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Real generateIndexHTML &gt; should render the news feed before the AI section" time="0.05038985">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Real generateIndexHTML &gt; should mark the active language link with aria-current and lang attributes" time="0.028022418">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Real generateIndexHTML &gt; should escape localized language names in link attributes" time="0.02445432">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Real generateIndexHTML &gt; should include a stacked homepage header and full-width hero banner layout" time="0.05239178">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Real generateIndexHTML &gt; should contain German localized AI heading on German page" time="0.000719117">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Real generateIndexHTML &gt; should contain Japanese localized AI heading on Japanese page" time="0.000642773">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Real generateIndexHTML &gt; should contain Arabic localized AI heading on Arabic page" time="0.000583034">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Real generateIndexHTML &gt; should generate valid HTML with AI section" time="0.000823935">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Real generateIndexHTML &gt; should include filter toolbar when articles are present" time="0.001285476">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Real generateIndexHTML &gt; should not include filter toolbar when no articles" time="0.000992828">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/generate-sitemap.test.js" timestamp="2026-04-28T00:15:08.279Z" hostname="runnervmeorf1" tests="92" failures="0" errors="0" skipped="0" time="0.16272621">
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Sitemap XML Structure &gt; should generate valid XML with declaration" time="0.005356248">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Sitemap XML Structure &gt; should include all language index pages" time="0.002959505">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Sitemap XML Structure &gt; should include 14 language index URLs" time="0.002958814">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Sitemap XML Structure &gt; should include news articles" time="0.001737154">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Sitemap XML Structure &gt; should include sitemap HTML page URLs" time="0.001544945">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Sitemap XML Structure &gt; should include docs files when provided" time="0.001532226">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; URL Properties &gt; should set high priority for index pages" time="0.00169431">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; URL Properties &gt; should set daily changefreq for index pages" time="0.001703303">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; URL Properties &gt; should set priority 0.8 for news articles" time="0.001821691">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; URL Properties &gt; should set monthly changefreq for news articles" time="0.007070106">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; URL Properties &gt; should set priority 0.5 for sitemap HTML pages" time="0.001210885">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; URL Properties &gt; should set priority 0.3 for docs files" time="0.00112105">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; URL Properties &gt; should set weekly changefreq for docs files" time="0.001310994">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; URL Properties &gt; should include lastmod date for all URLs" time="0.001986537">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; URL Properties &gt; should format lastmod in YYYY-MM-DD format" time="0.001640128">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; URL Count &gt; should calculate total URLs correctly with articles and docs" time="0.001037155">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; URL Count &gt; should handle no articles and no docs" time="0.000956483">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; URL Count &gt; should handle many articles" time="0.001047379">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; XML Validation &gt; should have balanced XML tags" time="0.00087446">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; XML Validation &gt; should properly escape special characters in URLs" time="0.00243575">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; XML Validation &gt; should use HTTPS protocol" time="0.002619906">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; XML Validation &gt; should use correct base URL" time="0.001406968">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Date Handling &gt; should use current date for index pages" time="0.001820909">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Date Handling &gt; should handle valid date format" time="0.000399359">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; File Operations &gt; should handle empty news directory" time="0.000513639">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; File Operations &gt; should filter only HTML files" time="0.000969263">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; File Operations &gt; should get file modification time" time="0.000728051">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Edge Cases &gt; should handle article with future date" time="0.001546618">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Edge Cases &gt; should handle article with past date" time="0.001719227">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Edge Cases &gt; should handle very long filename" time="0.00151488">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Performance &gt; should handle large number of articles" time="0.00599871">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; collectDocsHtmlFiles &gt; should return empty array for non-existent directory" time="0.001179959">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; collectDocsHtmlFiles &gt; should collect HTML files recursively" time="0.001807138">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; collectDocsHtmlFiles &gt; should skip non-HTML files" time="0.001245246">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; getSitemapFilename &gt; should return sitemap.html for English" time="0.000515382">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; getSitemapFilename &gt; should return sitemap_&lt;lang&gt;.html for other languages" time="0.000448733">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemapHTML &gt; should generate valid HTML5 document" time="0.002545374">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemapHTML &gt; should include sitemap title in target language" time="0.001424565">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemapHTML &gt; should include all language index page links" time="0.00122746">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemapHTML &gt; should include article titles and dates" time="0.001378676">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemapHTML &gt; should include article description when present" time="0.000626369">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemapHTML &gt; should handle articles without description" time="0.000813479">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemapHTML &gt; should include docs section when hasDocsDir is true" time="0.000951386">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemapHTML &gt; should not include docs section when hasDocsDir is false" time="0.000772608">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemapHTML &gt; should use localized docs labels" time="0.00075403">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemapHTML &gt; should set correct RTL direction for Arabic" time="0.000735042">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemapHTML &gt; should set correct LTR direction for English" time="0.000633549">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemapHTML &gt; should include language switcher for sitemap pages" time="0.000710605">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemapHTML &gt; should include skip link for accessibility" time="0.000705146">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemapHTML &gt; should include footer with Hack23 info" time="0.000672168">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemapHTML &gt; should escape HTML in article titles" time="0.000942783">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemapHTML &gt; should link news articles correctly" time="0.000636183">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemapHTML &gt; should generate all 14 language variants" time="0.005074205">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemap (exported function) &gt; should include sitemap HTML URLs in generated XML" time="0.003114448">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemap (exported function) &gt; should include docs files in generated XML" time="0.001917153">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemap (exported function) &gt; should set weekly changefreq for docs URLs" time="0.00220816">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemap (exported function) &gt; should include rss.xml URL in sitemap" time="0.001444896">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateRssFeed &gt; should generate valid RSS 2.0 XML" time="0.000608322">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateRssFeed &gt; should include channel metadata" time="0.000399569">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateRssFeed &gt; should include atom self link" time="0.000346519">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateRssFeed &gt; should include article items with correct structure" time="0.000949644">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateRssFeed &gt; should include multi-language items" time="0.000569444">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateRssFeed &gt; should escape XML special characters in titles" time="0.000446709">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateRssFeed &gt; should handle empty items list" time="0.000508202">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateRssFeed &gt; should handle large number of items" time="0.002026757">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Sitemap Locale Validation &gt; should include index page for every supported language" time="0.003667376">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Sitemap Locale Validation &gt; should include sitemap HTML page for every supported language" time="0.003623921">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Sitemap Locale Validation &gt; should include rss.xml in sitemap" time="0.003837401">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Sitemap Locale Validation &gt; should include all article locale variants when provided" time="0.0030554">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Sitemap Locale Validation &gt; should include docs files when present" time="0.001636393">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Sitemap Locale Validation &gt; should have exactly 14 index pages, 14 sitemap pages, 14 political-intelligence pages, 1 rss.xml with no articles" time="0.001427209">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Sitemap Locale Validation &gt; should have correct total URL count with articles and docs" time="0.003045284">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Sitemap Locale Validation &gt; should set correct priorities for all page types" time="0.001866167">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Hreflang / xhtml:link Alternates &gt; should declare the xhtml namespace on urlset" time="0.001418296">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Hreflang / xhtml:link Alternates &gt; should emit hreflang alternates for all 14 index pages" time="0.002606937">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Hreflang / xhtml:link Alternates &gt; should emit hreflang alternates for sitemap HTML pages" time="0.001637494">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Hreflang / xhtml:link Alternates &gt; should group multi-language article variants with hreflang alternates" time="0.001684234">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Hreflang / xhtml:link Alternates &gt; should NOT emit alternates for single-locale articles" time="0.001642011">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Hreflang / xhtml:link Alternates &gt; should NOT emit alternates for docs files" time="0.001779167">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Hreflang / xhtml:link Alternates &gt; should emit hreflang alternates for political-intelligence HTML pages" time="0.001669973">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Hreflang / xhtml:link Alternates &gt; should list all 14 political-intelligence language variants as &lt;loc&gt; entries" time="0.002093037">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Hreflang / xhtml:link Alternates &gt; should keep URL count stable (alternates do not add &lt;url&gt; elements)" time="0.001831365">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Sitemap HTML Enhancements &gt; should include a canonical link in the HTML head" time="0.000804826">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Sitemap HTML Enhancements &gt; should include hreflang alternates in the HTML head for all 14 languages" time="0.000905798">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Sitemap HTML Enhancements &gt; should include JSON-LD CollectionPage structured data" time="0.00104756">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Sitemap HTML Enhancements &gt; should render a hero section with intro text" time="0.000670264">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Sitemap HTML Enhancements &gt; should render a breadcrumb navigation" time="0.000635042">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Sitemap HTML Enhancements &gt; should render stats with article counts" time="0.012036329">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Sitemap HTML Enhancements &gt; should group News Articles by editorial category" time="0.000652658">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Sitemap HTML Enhancements &gt; should include section descriptions for Pages, Docs, and News" time="0.000534151">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Sitemap HTML Enhancements &gt; should render localized hero intro in Swedish" time="0.000414861">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Sitemap HTML Enhancements &gt; should set canonical URL to the language-specific sitemap page" time="0.000490405">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/html-sanitize.test.js" timestamp="2026-04-28T00:15:08.291Z" hostname="runnervmeorf1" tests="25" failures="0" errors="0" skipped="0" time="0.013909367">
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripScriptBlocks &gt; should return empty string for empty input" time="0.00348334">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripScriptBlocks &gt; should return the same string when no script tags are present" time="0.000262043">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripScriptBlocks &gt; should strip a simple script block" time="0.000759088">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripScriptBlocks &gt; should strip multiple script blocks" time="0.000539599">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripScriptBlocks &gt; should handle script tag with attributes" time="0.000423014">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripScriptBlocks &gt; should be case-insensitive for script tags" time="0.000176024">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripScriptBlocks &gt; should handle mixed case script tags" time="0.000154852">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripScriptBlocks &gt; should handle malformed opening script tag without closing &gt;" time="0.000366349">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripScriptBlocks &gt; should handle script tag without closing &lt;/script&gt; tag" time="0.001096684">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripScriptBlocks &gt; should handle &lt;/script tag without closing &gt;" time="0.000206159">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripScriptBlocks &gt; should preserve content before and after script blocks" time="0.000306689">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripScriptBlocks &gt; should handle empty script tags" time="0.000157005">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripScriptBlocks &gt; should handle script with newlines" time="0.000177826">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripScriptBlocks &gt; should handle adjacent script blocks" time="0.000184968">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripScriptBlocks &gt; should handle script at the very beginning" time="0.000267832">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripScriptBlocks &gt; should handle script at the very end" time="0.000230876">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripScriptBlocks &gt; should handle plain text without HTML" time="0.000136185">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripHtmlTags &gt; should return empty string for empty input" time="0.000239328">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripHtmlTags &gt; should return the same string when no tags are present" time="0.000144276">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripHtmlTags &gt; should strip simple HTML tags" time="0.000138318">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripHtmlTags &gt; should strip tags with attributes" time="0.000155824">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripHtmlTags &gt; should strip multiple tags" time="0.000241753">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripHtmlTags &gt; should handle self-closing tags" time="0.000136234">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripHtmlTags &gt; should handle unclosed tag gracefully" time="0.000198377">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripHtmlTags &gt; should not cause ReDoS on many &lt; characters" time="0.000246689">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/imf-mcp-client.test.js" timestamp="2026-04-28T00:15:08.294Z" hostname="runnervmeorf1" tests="36" failures="0" errors="0" skipped="0" time="0.0372455">
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; IMF_MCP_TOOLS drift guard &gt; exposes exactly the five virtual IMF tool names" time="0.002549311">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; IMF_MCP_TOOLS drift guard &gt; is a readonly array of strings" time="0.000526719">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; IMFClient alias &gt; is the same class as IMFMCPClient (forward-looking alias)" time="0.000215813">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; countIMFSDMXObservations &gt; counts observations nested under SDMX series rows" time="0.000598758">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; countIMFSDMXObservations &gt; counts flat dataset observations and returns zero for invalid JSON" time="0.000343164">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; IMFMCPClient construction &gt; uses the default SDMX 3.0 base URL and timeout" time="0.002083473">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; IMFMCPClient construction &gt; honours IMF_API_BASE_URL env var and strips trailing slashes" time="0.000950705">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; IMFMCPClient construction &gt; honours IMF_API_TIMEOUT_MS env var" time="0.00090733">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; IMFMCPClient construction &gt; prefers explicit options over env vars" time="0.001409122">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; IMFMCPClient construction &gt; ignores a malformed timeout env var and falls back to the default" time="0.000743464">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; IMFMCPClient construction &gt; connect() accepts a valid base URL and disconnect() clears it" time="0.001296453">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; IMFMCPClient construction &gt; connect() rejects a malformed base URL" time="0.003235609">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; listDatabases &gt; requests the /dataflow/IMF endpoint and normalises the payload" time="0.00243512">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; listDatabases &gt; returns empty fallback on HTTP error" time="0.000597966">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; listDatabases &gt; returns empty fallback on network/abort error" time="0.000482323">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; searchDatabases &gt; filters the dataflow list by case-insensitive substring" time="0.002137994">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; searchDatabases &gt; returns empty fallback without calling fetch when keyword is blank" time="0.001101631">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; getParameterDefs &gt; requests /datastructure/{id} and extracts the dimension list" time="0.001300029">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; getParameterDefs &gt; validates the databaseId argument" time="0.000830594">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; getParameterDefs &gt; URI-encodes the databaseId" time="0.000733369">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; getParameterCodes &gt; requires databaseId and parameter" time="0.001026418">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; getParameterCodes &gt; returns codes from an inlined `values` array when present" time="0.000623154">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; getParameterCodes &gt; resolves codes from a referenced codelist when inline values are empty" time="0.000555983">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; getParameterCodes &gt; applies the search filter as a case-insensitive substring" time="0.000701361">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; getParameterCodes &gt; returns an empty list when the requested dimension is not declared" time="0.000551617">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; fetchData &gt; builds the SDMX URL using the default dimension order for WEO" time="0.001158356">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; fetchData &gt; honours a caller-supplied dimensionOrder override" time="0.00046732">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; fetchData &gt; rejects an empty filters map" time="0.000561221">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; fetchData &gt; rejects an inverted year range" time="0.000438897">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; fetchData &gt; rejects non-finite year inputs" time="0.00037377">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; fetchData &gt; returns empty fallback when the transport fails" time="0.000451447">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; fetchData &gt; URI-encodes dimension codes containing reserved characters" time="0.00050075">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; Singleton lifecycle &gt; closeIMFMCPClient is safe to call when no instance exists" time="0.000630244">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; Singleton lifecycle &gt; closeIMFMCPClient is idempotent" time="0.000178317">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; Singleton lifecycle &gt; getIMFMCPClient returns a connected singleton" time="0.000555262">
        </testcase>
        <testcase classname="test/unit/imf-mcp-client.test.js" name="imf-mcp-client &gt; Singleton lifecycle &gt; getIMFMCPClient rejects a malformed base URL" time="0.000762543">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/infra-github-urls.test.js" timestamp="2026-04-28T00:15:08.298Z" hostname="runnervmeorf1" tests="11" failures="0" errors="0" skipped="0" time="0.007577917">
        <testcase classname="test/unit/infra-github-urls.test.js" name="infra/github-urls — constants &gt; exports the canonical repo slug" time="0.002656682">
        </testcase>
        <testcase classname="test/unit/infra-github-urls.test.js" name="infra/github-urls — constants &gt; exports the canonical default branch" time="0.000223455">
        </testcase>
        <testcase classname="test/unit/infra-github-urls.test.js" name="infra/github-urls — blobUrl &gt; builds a blob URL for a POSIX path" time="0.000228202">
        </testcase>
        <testcase classname="test/unit/infra-github-urls.test.js" name="infra/github-urls — blobUrl &gt; normalises Windows-style separators to POSIX" time="0.000147801">
        </testcase>
        <testcase classname="test/unit/infra-github-urls.test.js" name="infra/github-urls — blobUrl &gt; handles a single-segment path" time="0.00014041">
        </testcase>
        <testcase classname="test/unit/infra-github-urls.test.js" name="infra/github-urls — blobUrl &gt; matches the legacy githubBlobUrl shim byte-for-byte" time="0.000182153">
        </testcase>
        <testcase classname="test/unit/infra-github-urls.test.js" name="infra/github-urls — rawUrl &gt; builds a raw.githubusercontent URL" time="0.000191137">
        </testcase>
        <testcase classname="test/unit/infra-github-urls.test.js" name="infra/github-urls — rawUrl &gt; normalises backslashes to forward slashes" time="0.000154271">
        </testcase>
        <testcase classname="test/unit/infra-github-urls.test.js" name="infra/github-urls — rawUrl &gt; matches the legacy githubRawUrl shim byte-for-byte" time="0.0001938">
        </testcase>
        <testcase classname="test/unit/infra-github-urls.test.js" name="infra/github-urls — treeUrl &gt; builds a tree URL for a directory path" time="0.000155984">
        </testcase>
        <testcase classname="test/unit/infra-github-urls.test.js" name="infra/github-urls — treeUrl &gt; normalises Windows-style separators" time="0.000121733">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/intelligence-index.test.js" timestamp="2026-04-28T00:15:08.300Z" hostname="runnervmeorf1" tests="62" failures="0" errors="0" skipped="0" time="0.089332253">
        <testcase classname="test/unit/intelligence-index.test.js" name="createEmptyIndex &gt; should return a valid empty structure" time="0.00866068">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="createEmptyIndex &gt; should include a lastUpdated timestamp" time="0.000713659">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="addArticleToIndex &gt; should add an entry and return an updated index" time="0.000891987">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="addArticleToIndex &gt; should update the actors map" time="0.000935071">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="addArticleToIndex &gt; should update the policyDomains map" time="0.000303174">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="addArticleToIndex &gt; should update the procedures map" time="0.000351687">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="addArticleToIndex &gt; should replace an existing entry with the same id" time="0.000485838">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="addArticleToIndex &gt; should clean up stale map associations when replacing an article" time="0.000733288">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="addArticleToIndex &gt; should not duplicate article IDs in maps" time="0.000524396">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="addArticleToIndex &gt; should not mutate the original index" time="0.000356003">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="buildIndexFromEntries &gt; should deduplicate article IDs when entries have duplicate topics" time="0.000638747">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="buildIndexFromEntries &gt; should reject prototype-pollution keys like __proto__" time="0.000722463">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="addArticleToIndex prototype-safety &gt; should reject dangerous keys in addArticleToIndex" time="0.000415603">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="findRelatedArticles &gt; should find articles sharing topics" time="0.00132776">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="findRelatedArticles &gt; should find articles sharing actors" time="0.000474451">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="findRelatedArticles &gt; should return empty array for empty topics and actors" time="0.000455002">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="findRelatedArticles &gt; should respect maxResults limit" time="0.000415613">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="findRelatedArticles &gt; should sort results by relevance score (highest first)" time="0.000466328">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="findRelatedArticles &gt; should handle empty index" time="0.00042082">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="generateCrossReferences &gt; should generate cross-references for related articles" time="0.000758246">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="generateCrossReferences &gt; should not generate self-references" time="0.000338137">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="generateCrossReferences &gt; should assign strong strength for ≥3 shared items" time="0.00032666">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="generateCrossReferences &gt; should assign follows_up for older target articles" time="0.000360521">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="generateCrossReferences &gt; should assign preceded_by for newer target articles" time="0.00032054">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="generateCrossReferences &gt; should assign related for same-date target articles" time="0.00036068">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="generateCrossReferences &gt; should return empty array for no related articles" time="0.000412859">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="detectTrends &gt; should detect trends when ≥2 articles share topics" time="0.001732967">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="detectTrends &gt; should NOT detect a trend when only 1 article covers a topic" time="0.00025981">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="detectTrends &gt; should detect procedure-based trends" time="0.000459318">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="detectTrends &gt; should return empty array for empty index" time="0.000276445">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="detectTrends &gt; should set confidence based on article count" time="0.000591657">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="detectTrends &gt; should set direction to strengthening when ≥4 articles" time="0.000382874">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="detectTrends &gt; should produce non-colliding trend IDs for non-Latin scripts" time="0.001399297">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="findOrCreateSeries &gt; should create a new series when none exists" time="0.000436975">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="findOrCreateSeries &gt; should find an existing series by procedureRef" time="0.000239639">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="findOrCreateSeries &gt; should add the series to the index" time="0.000327441">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="findOrCreateSeries &gt; should generate a stable id from procedureRef" time="0.000399999">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="loadIntelligenceIndex &gt; should return empty index if file not found" time="0.000897766">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="loadIntelligenceIndex &gt; should return empty index if file is malformed JSON" time="0.000775622">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="loadIntelligenceIndex &gt; should normalize partial JSON (missing fields) to a complete index" time="0.001804043">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="loadIntelligenceIndex &gt; should rebuild lookup maps from articles when maps are missing" time="0.001185516">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="loadIntelligenceIndex &gt; should normalize article entries missing required arrays" time="0.001179397">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="loadIntelligenceIndex &gt; should reject non-string seriesId values during normalization" time="0.00085406">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="loadIntelligenceIndex &gt; should rebuild lookup maps when values are not string arrays (corrupt map)" time="0.000825918">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="loadIntelligenceIndex &gt; should recompute trends when lookup maps are rebuilt on load" time="0.00111447">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="loadIntelligenceIndex &gt; should sanitize unsafe keys from structurally valid persisted maps" time="0.001308371">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="saveIntelligenceIndex + loadIntelligenceIndex (round-trip) &gt; should persist and reload an index correctly" time="0.00126111">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="saveIntelligenceIndex + loadIntelligenceIndex (round-trip) &gt; should create parent directories if they do not exist" time="0.00098715">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="buildRelatedArticlesHTML &gt; should return empty string when no related articles or trends" time="0.000486669">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="buildRelatedArticlesHTML &gt; should return empty string when only empty arrays are provided" time="0.000211958">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="buildRelatedArticlesHTML &gt; should render crossRefs even when target article is not in relatedArticles" time="0.009466107">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="buildRelatedArticlesHTML &gt; should render output when only crossRefs are provided" time="0.000344707">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="buildRelatedArticlesHTML &gt; should generate a section element with aria-label" time="0.025110544">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="buildRelatedArticlesHTML &gt; should include rel=&quot;noopener noreferrer&quot; on links" time="0.000424165">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="buildRelatedArticlesHTML &gt; should include links to article HTML files" time="0.000323555">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="buildRelatedArticlesHTML &gt; should render trend blocks when trends are provided" time="0.000485458">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="buildRelatedArticlesHTML &gt; should include the article count in the trend description" time="0.000342844">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="buildRelatedArticlesHTML &gt; should show &quot;Related&quot; links when there are articles but no explicit cross-refs" time="0.000495683">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="buildRelatedArticlesHTML &gt; should escape HTML special characters in context" time="0.000431406">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="buildRelatedArticlesHTML &gt; should localise UI strings when a non-English lang is passed" time="0.00104093">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="buildRelatedArticlesHTML &gt; should localise trend labels for German" time="0.000942002">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="buildRelatedArticlesHTML &gt; should fall back to English for unknown language codes" time="0.000431927">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/languages.test.js" timestamp="2026-04-28T00:15:08.308Z" hostname="runnervmeorf1" tests="56" failures="0" errors="0" skipped="0" time="0.113892372">
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; ALL_LANGUAGES &gt; should contain exactly 14 language codes" time="0.003991722">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; ALL_LANGUAGES &gt; should contain all expected Hack23 market languages" time="0.001282392">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; LANGUAGE_PRESETS &gt; should have all presets" time="0.000257766">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; LANGUAGE_PRESETS &gt; should have eu-core preset with 5 languages" time="0.000939578">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; LANGUAGE_PRESETS &gt; should have nordic preset with 5 languages" time="0.000722283">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; Language Maps &gt; should have entries for all 14 languages in LANGUAGE_NAMES" time="0.00100712">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; Language Maps &gt; should have entries for all 14 languages in PAGE_TITLES" time="0.00042063">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; Language Maps &gt; should have entries for all 14 languages in PAGE_DESCRIPTIONS" time="0.000455663">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; Language Maps &gt; should have entries for all 14 languages in SECTION_HEADINGS" time="0.000535082">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; Language Maps &gt; should have entries for all 14 languages in NO_ARTICLES_MESSAGES" time="0.000554922">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; Language Maps &gt; should have entries for all 14 languages in ARTICLE_TYPE_LABELS" time="0.004206565">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; Language Maps &gt; should have entries for all 14 languages in READ_TIME_LABELS" time="0.001021931">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; Language Maps &gt; should have entries for all 14 languages in BACK_TO_NEWS_LABELS" time="0.00044073">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; Language Maps &gt; should have entries for all 14 languages in WEEK_AHEAD_TITLES" time="0.001710904">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; Language Maps &gt; should have entries for all 14 languages in MOTIONS_TITLES" time="0.001772337">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; Language Maps &gt; should have entries for all 14 languages in BREAKING_NEWS_TITLES" time="0.002544153">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; Language Maps &gt; should have entries for all 14 languages in PROPOSITIONS_TITLES" time="0.001972476">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; Language Maps &gt; should have entries for all 14 languages in PROPOSITIONS_STRINGS" time="0.003404162">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; Language Maps &gt; should have correct native language names" time="0.000314642">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; getLocalizedString &gt; should return correct value for supported language" time="0.000252909">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; getLocalizedString &gt; should fall back to English for unsupported language" time="0.000171327">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; getLocalizedString &gt; should work with function-valued maps" time="0.000182683">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; isSupportedLanguage &gt; should return true for supported languages" time="0.000346249">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; isSupportedLanguage &gt; should return false for unsupported languages" time="0.000216515">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; getTextDirection &gt; should return ltr for LTR languages" time="0.000545258">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; getTextDirection &gt; should return rtl for Arabic" time="0.000202754">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; getTextDirection &gt; should return rtl for Hebrew" time="0.000158077">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; getTextDirection &gt; should return ltr for unknown languages" time="0.000176124">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; COMMITTEE_REPORTS_TITLES &gt; should have entries for all 14 supported languages" time="0.0002536">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; COMMITTEE_REPORTS_TITLES &gt; should generate non-empty title containing committee name for each language" time="0.003885363">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="EDITORIAL_STRINGS &gt; should have entries for all 14 supported languages" time="0.000238578">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="EDITORIAL_STRINGS &gt; should contain all required editorial string fields for every language" time="0.004067496">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="EDITORIAL_STRINGS &gt; should return English editorial strings via getLocalizedString fallback for unsupported language" time="0.000305278">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="EDITORIAL_STRINGS &gt; should have non-empty whyThisMatters for all languages" time="0.001049082">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="PROPOSITIONS_STRINGS whyThisMatters &gt; should have whyThisMatters field for all 14 languages" time="0.001063003">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="Footer and header localization constants &gt; should have entries for all 14 languages in HEADER_SUBTITLE_LABELS" time="0.001107309">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="Footer and header localization constants &gt; should have English value &quot;European Parliament Intelligence&quot; in HEADER_SUBTITLE_LABELS" time="0.000129995">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="Footer and header localization constants &gt; should have entries for all 14 languages in FOOTER_ABOUT_HEADING_LABELS" time="0.001122732">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="Footer and header localization constants &gt; should have English value in FOOTER_ABOUT_HEADING_LABELS" time="0.000148122">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="Footer and header localization constants &gt; should have entries for all 14 languages in FOOTER_ABOUT_TEXT_LABELS" time="0.000871477">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="Footer and header localization constants &gt; should have entries for all 14 languages in FOOTER_QUICK_LINKS_LABELS" time="0.000786399">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="Footer and header localization constants &gt; should have English value &quot;Quick Links&quot; in FOOTER_QUICK_LINKS_LABELS" time="0.000224256">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="Footer and header localization constants &gt; should have entries for all 14 languages in FOOTER_BUILT_BY_LABELS" time="0.000768402">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="Footer and header localization constants &gt; should have English value &quot;Built by Hack23 AB&quot; in FOOTER_BUILT_BY_LABELS" time="0.000148383">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="Footer and header localization constants &gt; should have entries for all 14 languages in FOOTER_LANGUAGES_LABELS" time="0.000769793">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="Footer and header localization constants &gt; should have English value &quot;Languages&quot; in FOOTER_LANGUAGES_LABELS" time="0.00011322">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="Footer and header localization constants &gt; should return fallback English value for unknown lang in HEADER_SUBTITLE_LABELS" time="0.00016644">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="MONTHLY_REVIEW_TITLES &gt; should have entries for all 14 languages" time="0.000311406">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="MONTHLY_REVIEW_TITLES &gt; should generate title and subtitle for each language" time="0.001493528">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="DEEP_ANALYSIS_STRINGS &gt; should have entries for all 14 languages" time="0.000199329">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="DEEP_ANALYSIS_STRINGS &gt; should have all required fields for each language" time="0.038361754">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="DEEP_ANALYSIS_STRINGS &gt; should not have English fallbacks in non-EN enhanced analysis fields" time="0.01006917">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="MONTH_IN_REVIEW_STRINGS &gt; should have entries for all 14 languages" time="0.000275063">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="MONTH_IN_REVIEW_STRINGS &gt; should have all required section heading fields for each language" time="0.004375137">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="ANALYSIS_QUALITY_LABELS &gt; should have entries for all 14 languages" time="0.000391237">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="ANALYSIS_QUALITY_LABELS &gt; should have all required quality indicator fields for each language" time="0.007291979">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/lint-prompts.test.js" timestamp="2026-04-28T00:15:08.316Z" hostname="runnervmeorf1" tests="15" failures="0" errors="0" skipped="0" time="0.721191748">
        <testcase classname="test/unit/lint-prompts.test.js" name="scripts/lint-prompts.js &gt; exits 0 when every workflow follows the single-PR rule" time="0.046974282">
        </testcase>
        <testcase classname="test/unit/lint-prompts.test.js" name="scripts/lint-prompts.js &gt; exits 1 when a workflow calls create_pull_request more than once" time="0.047236726">
        </testcase>
        <testcase classname="test/unit/lint-prompts.test.js" name="scripts/lint-prompts.js &gt; flags forbidden phrases regardless of casing" time="0.048260791">
        </testcase>
        <testcase classname="test/unit/lint-prompts.test.js" name="scripts/lint-prompts.js &gt; flags references to modules purged in the April-2026 aggregator migration" time="0.046984718">
        </testcase>
        <testcase classname="test/unit/lint-prompts.test.js" name="scripts/lint-prompts.js &gt; accepts workflows that reference the aggregator entry point and CLI" time="0.052747044">
        </testcase>
        <testcase classname="test/unit/lint-prompts.test.js" name="scripts/lint-prompts.js &gt; still allows generate-news-indexes (not a purged module)" time="0.043275659">
        </testcase>
        <testcase classname="test/unit/lint-prompts.test.js" name="scripts/lint-prompts.js &gt; flags push_repo_memory references" time="0.047250807">
        </testcase>
        <testcase classname="test/unit/lint-prompts.test.js" name="scripts/lint-prompts.js &gt; exempts news-translate.md from every rule" time="0.049922651">
        </testcase>
        <testcase classname="test/unit/lint-prompts.test.js" name="scripts/lint-prompts.js &gt; flags missing analysis-awareness anchor in a news-*.md" time="0.049061611">
        </testcase>
        <testcase classname="test/unit/lint-prompts.test.js" name="scripts/lint-prompts.js &gt; accepts workflows that import news-generation.agent.md (transitive anchors)" time="0.049663523">
        </testcase>
        <testcase classname="test/unit/lint-prompts.test.js" name="scripts/lint-prompts.js &gt; accepts workflows that directly reference both analysis anchors" time="0.044245182">
        </testcase>
        <testcase classname="test/unit/lint-prompts.test.js" name="scripts/lint-prompts.js &gt; applies the single-PR rule to news-*-analysis.md" time="0.049148991">
        </testcase>
        <testcase classname="test/unit/lint-prompts.test.js" name="scripts/lint-prompts.js &gt; applies the single-PR rule to news-*-article.md" time="0.047146881">
        </testcase>
        <testcase classname="test/unit/lint-prompts.test.js" name="scripts/lint-prompts.js &gt; accepts a news-*-article.md that anchors only the completeness gate (no analysis guide)" time="0.056168482">
        </testcase>
        <testcase classname="test/unit/lint-prompts.test.js" name="scripts/lint-prompts.js &gt; flags a news-*-article.md that anchors neither agent nor gate" time="0.040242853">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/manifest.test.js" timestamp="2026-04-28T00:15:08.318Z" hostname="runnervmeorf1" tests="34" failures="0" errors="0" skipped="0" time="0.020408937">
        <testcase classname="test/unit/manifest.test.js" name="resolveArticleType &gt; prefers canonical articleType when present" time="0.003338563">
        </testcase>
        <testcase classname="test/unit/manifest.test.js" name="resolveArticleType &gt; falls back to articleTypes[0] when articleType missing" time="0.000346469">
        </testcase>
        <testcase classname="test/unit/manifest.test.js" name="resolveArticleType &gt; falls back to runType for very-legacy manifests" time="0.000236795">
        </testcase>
        <testcase classname="test/unit/manifest.test.js" name="resolveArticleType &gt; returns &quot;unknown&quot; when every variant is missing" time="0.000275282">
        </testcase>
        <testcase classname="test/unit/manifest.test.js" name="resolveArticleType &gt; returns &quot;unknown&quot; for empty strings" time="0.000230185">
        </testcase>
        <testcase classname="test/unit/manifest.test.js" name="resolveArticleType &gt; skips empty articleTypes[0] and falls through" time="0.000242694">
        </testcase>
        <testcase classname="test/unit/manifest.test.js" name="resolveRunId &gt; uses string runId when present" time="0.000282023">
        </testcase>
        <testcase classname="test/unit/manifest.test.js" name="resolveRunId &gt; coerces numeric runId to string" time="0.00023314">
        </testcase>
        <testcase classname="test/unit/manifest.test.js" name="resolveRunId &gt; uses fallback when runId missing" time="0.000279719">
        </testcase>
        <testcase classname="test/unit/manifest.test.js" name="resolveRunId &gt; uses fallback when runId is empty string" time="0.000196815">
        </testcase>
        <testcase classname="test/unit/manifest.test.js" name="resolveDate &gt; returns strict YYYY-MM-DD as-is" time="0.000348473">
        </testcase>
        <testcase classname="test/unit/manifest.test.js" name="resolveDate &gt; returns undefined for non-ISO date" time="0.00028045">
        </testcase>
        <testcase classname="test/unit/manifest.test.js" name="resolveDate &gt; returns undefined for missing date" time="0.000218568">
        </testcase>
        <testcase classname="test/unit/manifest.test.js" name="resolveDate &gt; returns undefined for partial ISO date" time="0.000180751">
        </testcase>
        <testcase classname="test/unit/manifest.test.js" name="latestGateResult &gt; returns PENDING when history is missing" time="0.000268613">
        </testcase>
        <testcase classname="test/unit/manifest.test.js" name="latestGateResult &gt; returns PENDING when history is empty" time="0.000187431">
        </testcase>
        <testcase classname="test/unit/manifest.test.js" name="latestGateResult &gt; returns the latest non-PENDING gateResult" time="0.000227821">
        </testcase>
        <testcase classname="test/unit/manifest.test.js" name="latestGateResult &gt; skips PENDING entries searching from the end" time="0.000200441">
        </testcase>
        <testcase classname="test/unit/manifest.test.js" name="latestGateResult &gt; returns PENDING when every entry is PENDING" time="0.000219219">
        </testcase>
        <testcase classname="test/unit/manifest.test.js" name="flattenManifestFiles &gt; returns [] when files is undefined" time="0.001183283">
        </testcase>
        <testcase classname="test/unit/manifest.test.js" name="flattenManifestFiles &gt; flattens nested array values" time="0.001502702">
        </testcase>
        <testcase classname="test/unit/manifest.test.js" name="flattenManifestFiles &gt; extracts keys from path → description objects" time="0.000495102">
        </testcase>
        <testcase classname="test/unit/manifest.test.js" name="flattenManifestFiles &gt; ignores unknown value shapes" time="0.000266399">
        </testcase>
        <testcase classname="test/unit/manifest.test.js" name="flattenManifestFiles &gt; filters non-string array entries" time="0.000281031">
        </testcase>
        <testcase classname="test/unit/manifest.test.js" name="flattenManifestFiles &gt; de-duplicates entries while preserving first-seen order" time="0.000278617">
        </testcase>
        <testcase classname="test/unit/manifest.test.js" name="flattenManifestFiles &gt; de-duplicates inside a single section as well" time="0.000262633">
        </testcase>
        <testcase classname="test/unit/manifest.test.js" name="parseManifest &gt; parses well-formed JSON" time="0.000282553">
        </testcase>
        <testcase classname="test/unit/manifest.test.js" name="parseManifest &gt; returns null on malformed JSON" time="0.000232789">
        </testcase>
        <testcase classname="test/unit/manifest.test.js" name="parseManifest &gt; returns null on empty input" time="0.000171317">
        </testcase>
        <testcase classname="test/unit/manifest.test.js" name="readManifest &gt; returns {manifest:null} when manifest.json is missing" time="0.001305357">
        </testcase>
        <testcase classname="test/unit/manifest.test.js" name="readManifest &gt; parses a valid manifest.json" time="0.00072068">
        </testcase>
        <testcase classname="test/unit/manifest.test.js" name="readManifest &gt; returns null on malformed JSON without throwing" time="0.000650244">
        </testcase>
        <testcase classname="test/unit/manifest.test.js" name="readManifest &gt; handles legacy plural-articleTypes schema" time="0.000857926">
        </testcase>
        <testcase classname="test/unit/manifest.test.js" name="readManifest &gt; handles very-legacy runType schema" time="0.000711797">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/markdown-renderer.test.js" timestamp="2026-04-28T00:15:08.322Z" hostname="runnervmeorf1" tests="13" failures="0" errors="0" skipped="0" time="0.038900311">
        <testcase classname="test/unit/markdown-renderer.test.js" name="slugify &gt; lowercases, strips punctuation, replaces spaces with dashes" time="0.003722539">
        </testcase>
        <testcase classname="test/unit/markdown-renderer.test.js" name="slugify &gt; preserves unicode letters and digits" time="0.000576003">
        </testcase>
        <testcase classname="test/unit/markdown-renderer.test.js" name="slugify &gt; returns empty string for a punctuation-only input" time="0.000571757">
        </testcase>
        <testcase classname="test/unit/markdown-renderer.test.js" name="buildMarkdownIt &gt; returns a markdown-it instance with html enabled" time="0.00507766">
        </testcase>
        <testcase classname="test/unit/markdown-renderer.test.js" name="renderMarkdown &gt; strips Jekyll YAML front matter before rendering the body" time="0.009300439">
        </testcase>
        <testcase classname="test/unit/markdown-renderer.test.js" name="renderMarkdown &gt; renders headings with stable anchor ids" time="0.001677564">
        </testcase>
        <testcase classname="test/unit/markdown-renderer.test.js" name="renderMarkdown &gt; converts ```mermaid fences into &lt;pre class=&quot;mermaid&quot;&gt; in a labelled figure" time="0.001415692">
        </testcase>
        <testcase classname="test/unit/markdown-renderer.test.js" name="renderMarkdown &gt; does not inject any inline &lt;script&gt; tags" time="0.001166609">
        </testcase>
        <testcase classname="test/unit/markdown-renderer.test.js" name="renderMarkdown &gt; wraps tables in a scrollable region" time="0.004231092">
        </testcase>
        <testcase classname="test/unit/markdown-renderer.test.js" name="renderMarkdown &gt; renders standard code fences without modification" time="0.001140109">
        </testcase>
        <testcase classname="test/unit/markdown-renderer.test.js" name="renderMarkdown &gt; accepts a custom mermaidLabel callback via options" time="0.00100743">
        </testcase>
        <testcase classname="test/unit/markdown-renderer.test.js" name="renderMarkdown &gt; preserves footnotes" time="0.003653105">
        </testcase>
        <testcase classname="test/unit/markdown-renderer.test.js" name="renderMarkdown &gt; escapes uppercase placeholder pseudo-tags while preserving trusted HTML wrappers" time="0.00236179">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/mcp-connection.test.js" timestamp="2026-04-28T00:15:08.324Z" hostname="runnervmeorf1" tests="105" failures="0" errors="0" skipped="0" time="0.091493162">
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; parseSSEResponse &gt; should parse a valid SSE response with single data line" time="0.008149694">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; parseSSEResponse &gt; should return null for empty string" time="0.00024036">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; parseSSEResponse &gt; should return null for response with no data lines" time="0.000299198">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; parseSSEResponse &gt; should return first valid data line when multiple exist" time="0.000296074">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; parseSSEResponse &gt; should skip invalid JSON and return the first valid one" time="0.000277385">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; parseSSEResponse &gt; should return null when all data lines contain malformed JSON" time="0.000208031">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; parseSSEResponse &gt; should skip data lines with empty content after prefix" time="0.000192889">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; parseSSEResponse &gt; should handle data lines with extra whitespace after prefix" time="0.000582623">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; parseSSEResponse &gt; should handle mixed valid/invalid lines with event prefixes" time="0.001068852">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; parseSSEResponse &gt; should parse error responses from SSE" time="0.000858356">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; formatRetryAfter &gt; should format numeric seconds" time="0.000490355">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; formatRetryAfter &gt; should format numeric seconds with trailing s suffix" time="0.000209254">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; formatRetryAfter &gt; should format zero seconds" time="0.000402473">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; formatRetryAfter &gt; should format a future HTTP-date as seconds until that time" time="0.000485919">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; formatRetryAfter &gt; should format a past HTTP-date as just the UTC string" time="0.00025355">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; formatRetryAfter &gt; should return the raw value when not numeric and not a valid date" time="0.000138207">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; formatRetryAfter &gt; should return the raw value for an empty string (not &quot;0s&quot;)" time="0.000138298">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; formatRetryAfter &gt; should return the raw value for a whitespace-only string (not &quot;0s&quot;)" time="0.000124687">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPSessionExpiredError &gt; should be an instance of Error" time="0.000315743">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPSessionExpiredError &gt; should be an instance of MCPSessionExpiredError" time="0.000155974">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPSessionExpiredError &gt; should have name MCPSessionExpiredError" time="0.000134421">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPSessionExpiredError &gt; should include 401 and statusText in the message" time="0.000315643">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; isRetriableError &gt; should return true for a timeout error" time="0.000234221">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; isRetriableError &gt; should return true for a connection-closed error" time="0.000142303">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; isRetriableError &gt; should return true for a connection-reset error" time="0.000129865">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; isRetriableError &gt; should return true for a not-connected error" time="0.000131928">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; isRetriableError &gt; should return false for a generic unknown error (allow-list)" time="0.000128763">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; isRetriableError &gt; should return false for MCPSessionExpiredError" time="0.000175203">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; isRetriableError &gt; should return false for a TypeError" time="0.000123525">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; isRetriableError &gt; should return false for a rate-limit error" time="0.000123415">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; isRetriableError &gt; should return false for a MCPRateLimitError instance" time="0.000181683">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; isRetriableError &gt; should return false for a TypeError even when message contains a retriable keyword" time="0.000137527">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; isRetriableError &gt; should return true for a 502 Bad Gateway error" time="0.000128713">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; isRetriableError &gt; should return true for a 503 Service Unavailable error" time="0.00028722">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; isRetriableError &gt; should return true for a 504 Gateway Timeout error" time="0.000155793">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; isRetriableError &gt; should return false for a 404 Not Found error (not transient)" time="0.000134612">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; isRetriableError &gt; should return true for ECONNREFUSED error" time="0.000129725">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; isRetriableError &gt; should return true for socket hang up error" time="0.000146028">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; Constructor &gt; should initialize health metrics to zero" time="0.000883774">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; Constructor &gt; should accept maxRetries option" time="0.000225808">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; Constructor &gt; should default maxRetries to 2" time="0.000292849">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; Constructor &gt; should initialize reconnectingPromise to null" time="0.000323024">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; getConnectionHealth &gt; should reflect connected state" time="0.000235333">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; getConnectionHealth &gt; should accumulate timeout count" time="0.001332687">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; callToolWithRetry &gt; should succeed on first attempt without retrying" time="0.000466449">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; callToolWithRetry &gt; should retry on timeout and succeed" time="0.001554149">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; callToolWithRetry &gt; should increment timeoutCount on each timeout" time="0.002580808">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; callToolWithRetry &gt; should throw after exhausting all retries" time="0.004917931">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; callToolWithRetry &gt; should trigger reconnect when disconnected mid-retry" time="0.004381446">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; callToolWithRetry &gt; should not reconnect when still connected on retry" time="0.00196128">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; callToolWithRetry &gt; should use instance maxRetries when no override provided" time="0.001739718">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; callToolWithRetry &gt; should throw immediately without retrying on rate-limit (429) error" time="0.000496975">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; callToolWithRetry &gt; should throw immediately without retrying on MCPSessionExpiredError" time="0.000300641">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; callToolWithRetry &gt; should throw immediately without retrying on TypeError (programmer error)" time="0.000564876">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; callToolWithRetry &gt; should throw RangeError for negative maxRetries" time="0.00057424">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; reconnect &gt; should increment reconnectCount on each call" time="0.002682009">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; reconnect &gt; should await the same in-flight promise when called concurrently" time="0.001540639">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; reconnect &gt; should clear reconnectingPromise after success" time="0.001418717">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; reconnect &gt; should clear reconnectingPromise after all attempts fail" time="0.001644204">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; Gateway session expiry (401) &gt; should throw MCPSessionExpiredError and clear session on 401" time="0.001067269">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; Gateway session expiry (401) &gt; should include statusText in the MCPSessionExpiredError message" time="0.000539469">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; Rate limit handling (X-Retry-After) &gt; should throw rate limit error with numeric delay from X-Retry-After" time="0.000674521">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; Rate limit handling (X-Retry-After) &gt; should fall back to Retry-After header if X-Retry-After is absent" time="0.000570255">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; Rate limit handling (X-Retry-After) &gt; should format HTTP-date Retry-After as seconds until expiry" time="0.000630806">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; Rate limit handling (X-Retry-After) &gt; should throw generic gateway error when no rate-limit header present" time="0.000554601">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; Rate limit handling (X-Retry-After) &gt; should throw RATE_LIMIT_MSG for 429 without Retry-After header" time="0.000468602">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; Rate limit handling (X-Retry-After) &gt; should throw generic gateway error (not rate-limit) for non-429 with Retry-After header" time="0.000571176">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; Rate limit handling (X-Retry-After) &gt; should throw MCPRateLimitError (not plain Error) for 429 with Retry-After" time="0.000524005">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; Rate limit handling (X-Retry-After) &gt; should throw MCPRateLimitError with retryAfterMs=0 for 429 with whitespace-only Retry-After header" time="0.000590234">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; Rate limit handling (X-Retry-After) &gt; should rethrow MCPSessionExpiredError immediately without retrying in connect()" time="0.000845116">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; Rate limit handling (X-Retry-After) &gt; should use Retry-After delay (not exponential backoff) when connect() encounters 429" time="0.002408921">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; _buildAuthorizationHeader &gt; should return empty string for an empty API key" time="0.000405769">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; _buildAuthorizationHeader &gt; should return empty string for a whitespace-only API key" time="0.000217416">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; _buildAuthorizationHeader &gt; should return raw token unchanged when no scheme prefix is present" time="0.000233931">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; _buildAuthorizationHeader &gt; should pass through pre-prefixed Bearer value unchanged" time="0.000290746">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; _buildAuthorizationHeader &gt; should pass through pre-prefixed Token value unchanged" time="0.000239519">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; _buildAuthorizationHeader &gt; should pass through pre-prefixed AWS4-HMAC-SHA256 scheme unchanged" time="0.000204146">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; _buildAuthorizationHeader &gt; should prepend EP_MCP_GATEWAY_AUTH_SCHEME when set to a valid token" time="0.000250396">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; _buildAuthorizationHeader &gt; should not prepend EP_MCP_GATEWAY_AUTH_SCHEME when key is already prefixed" time="0.00030046">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; _buildAuthorizationHeader &gt; should ignore EP_MCP_GATEWAY_AUTH_SCHEME when it contains invalid tchar characters" time="0.000269574">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; _buildAuthorizationHeader &gt; should throw when API key contains CR character (header injection risk)" time="0.000383505">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; _buildAuthorizationHeader &gt; should throw when API key contains LF character (header injection risk)" time="0.000329644">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="CircuitBreaker (mcp-retry) &gt; starts in CLOSED state and allows requests" time="0.000439018">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="CircuitBreaker (mcp-retry) &gt; stays CLOSED when failures are below threshold" time="0.000363135">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="CircuitBreaker (mcp-retry) &gt; opens after reaching failure threshold" time="0.000308653">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="CircuitBreaker (mcp-retry) &gt; transitions OPEN → HALF_OPEN after reset timeout" time="0.000328102">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="CircuitBreaker (mcp-retry) &gt; closes circuit on success after HALF_OPEN" time="0.000306019">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="CircuitBreaker (mcp-retry) &gt; re-opens on failure in HALF_OPEN" time="0.000256454">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="CircuitBreaker (mcp-retry) &gt; allows only one probe in HALF_OPEN state" time="0.000268723">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="CircuitBreaker (mcp-retry) &gt; resets consecutive failures on success" time="0.000298868">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="CircuitBreaker (mcp-retry) &gt; getStats returns current state and failure count" time="0.00039364">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="CircuitBreaker (mcp-retry) &gt; does not transition to HALF_OPEN when timeout has not elapsed" time="0.000274291">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="withRetry (mcp-retry) &gt; returns result on first success" time="0.000551236">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="withRetry (mcp-retry) &gt; retries and succeeds on later attempt" time="0.003217622">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="withRetry (mcp-retry) &gt; throws last error after all retries exhausted" time="0.002703932">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="withRetry (mcp-retry) &gt; uses exponential backoff between retries" time="0.004023961">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="withRetry (mcp-retry) &gt; caps delay at maxDelayMs" time="0.002781058">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="withRetry (mcp-retry) &gt; defaults to 3 retries when no policy given" time="0.006905048">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="MCPHealthMonitor (mcp-health) &gt; creates breakers on demand for new tools" time="0.000446018">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="MCPHealthMonitor (mcp-health) &gt; returns the same breaker for repeated calls with same tool name" time="0.000212909">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="MCPHealthMonitor (mcp-health) &gt; applies default options to newly created breakers" time="0.000224476">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="MCPHealthMonitor (mcp-health) &gt; provides aggregated health snapshot" time="0.000374751">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="MCPHealthMonitor (mcp-health) &gt; lists registered tools" time="0.001152908">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="MCPHealthMonitor (mcp-health) &gt; returns empty snapshot when no tools registered" time="0.000781061">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="MCPHealthMonitor (mcp-health) &gt; tracks HALF_OPEN state in snapshot" time="0.000277065">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/news-metadata.test.js" timestamp="2026-04-28T00:15:08.339Z" hostname="runnervmeorf1" tests="15" failures="0" errors="0" skipped="0" time="0.042876821">
        <testcase classname="test/unit/news-metadata.test.js" name="utils/news-metadata &gt; buildMetadataDatabase &gt; should build database from article files" time="0.0175009">
        </testcase>
        <testcase classname="test/unit/news-metadata.test.js" name="utils/news-metadata &gt; buildMetadataDatabase &gt; should extract metadata from filenames" time="0.001368791">
        </testcase>
        <testcase classname="test/unit/news-metadata.test.js" name="utils/news-metadata &gt; buildMetadataDatabase &gt; should use real title from h1 when present in HTML" time="0.000979989">
        </testcase>
        <testcase classname="test/unit/news-metadata.test.js" name="utils/news-metadata &gt; buildMetadataDatabase &gt; should handle empty news directory" time="0.000744716">
        </testcase>
        <testcase classname="test/unit/news-metadata.test.js" name="utils/news-metadata &gt; buildMetadataDatabase &gt; should skip non-article files" time="0.001503834">
        </testcase>
        <testcase classname="test/unit/news-metadata.test.js" name="utils/news-metadata &gt; writeMetadataDatabase / readMetadataDatabase &gt; should write and read metadata database" time="0.001711405">
        </testcase>
        <testcase classname="test/unit/news-metadata.test.js" name="utils/news-metadata &gt; writeMetadataDatabase / readMetadataDatabase &gt; should return null for non-existent file" time="0.000525288">
        </testcase>
        <testcase classname="test/unit/news-metadata.test.js" name="utils/news-metadata &gt; writeMetadataDatabase / readMetadataDatabase &gt; should create parent directory if it does not exist" time="0.001024505">
        </testcase>
        <testcase classname="test/unit/news-metadata.test.js" name="utils/news-metadata &gt; updateMetadataDatabase &gt; should build and write metadata in one step" time="0.001525026">
        </testcase>
        <testcase classname="test/unit/news-metadata.test.js" name="utils/news-metadata &gt; updateIntelligenceIndex &gt; should build an intelligence index from article files and persist it" time="0.003801959">
        </testcase>
        <testcase classname="test/unit/news-metadata.test.js" name="utils/news-metadata &gt; updateIntelligenceIndex &gt; should extract key topics from article slugs and metadata" time="0.00170809">
        </testcase>
        <testcase classname="test/unit/news-metadata.test.js" name="utils/news-metadata &gt; updateIntelligenceIndex &gt; should prune deleted articles when rebuilt" time="0.002482811">
        </testcase>
        <testcase classname="test/unit/news-metadata.test.js" name="utils/news-metadata &gt; updateIntelligenceIndex &gt; should detect trends when articles share topics" time="0.001563133">
        </testcase>
        <testcase classname="test/unit/news-metadata.test.js" name="utils/news-metadata &gt; updateIntelligenceIndex &gt; should handle empty news directory" time="0.001323874">
        </testcase>
        <testcase classname="test/unit/news-metadata.test.js" name="utils/news-metadata &gt; updateIntelligenceIndex &gt; should only use slug tokens for non-English articles" time="0.002231385">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/pending-documents.test.js" timestamp="2026-04-28T00:15:08.342Z" hostname="runnervmeorf1" tests="39" failures="0" errors="0" skipped="0" time="0.070988521">
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; computeNextProbeAfter &gt; should return 24h ahead for attempt 1" time="0.004042619">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; computeNextProbeAfter &gt; should double the delay for attempt 2 (48 h)" time="0.000835692">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; computeNextProbeAfter &gt; should cap the delay at MAX_BACKOFF_MS (72 h) for attempt 3+" time="0.00066726">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; computeNextProbeAfter &gt; should cap to MAX_BACKOFF_MS but not exceed it" time="0.000573339">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; isDueForProbe &gt; should return true when nextProbeAfter has passed" time="0.000627911">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; isDueForProbe &gt; should return false when nextProbeAfter has not passed" time="0.000602853">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; isDueForProbe &gt; should return false for RESOLVED documents" time="0.000464666">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; isDueForProbe &gt; should return false for ESCALATED documents" time="0.000586419">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; isDueForProbe &gt; should return true when nextProbeAfter equals now exactly" time="0.000634892">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; isExpiredPending &gt; should return true when document is older than 14 days" time="0.000588852">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; isExpiredPending &gt; should return false when document is within 14 days" time="0.000496935">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; isExpiredPending &gt; should return false for RESOLVED documents even if old" time="0.00052726">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; isExpiredPending &gt; should return false for ESCALATED documents" time="0.000493991">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; loadPendingDocuments &gt; should return an empty store when the file does not exist" time="0.002247879">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; loadPendingDocuments &gt; should load an existing store" time="0.006442195">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; loadPendingDocuments &gt; should return an empty store when the file contains invalid JSON" time="0.002511825">
            <system-err>
⚠️ pending-documents: failed to load store: Unexpected token &apos;o&apos;, &quot;not json&quot; is not valid JSON

            </system-err>
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; loadPendingDocuments &gt; should return safe defaults when documents key is null" time="0.00311618">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; loadPendingDocuments &gt; should return safe defaults when the file contains an empty object {}" time="0.001341661">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; savePendingDocuments &gt; should write the store and update lastUpdatedAt" time="0.001596453">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; savePendingDocuments &gt; should create parent directories as needed" time="0.002863031">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; recordPendingDocument &gt; should create a new PENDING record on first observation" time="0.001879297">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; recordPendingDocument &gt; should persist the record to disk" time="0.001056823">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; recordPendingDocument &gt; should increment attempts and update lastProbedAt on subsequent calls" time="0.002131124">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; recordPendingDocument &gt; should compute doubling back-off on second attempt" time="0.001697795">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; recordPendingDocument &gt; should not update a RESOLVED document" time="0.004677591">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; recordPendingDocument &gt; should handle multiple distinct docIds independently" time="0.003703841">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; markDocumentResolved &gt; should set status to RESOLVED" time="0.001978455">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; markDocumentResolved &gt; should update lastProbedAt on resolution" time="0.003365965">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; markDocumentResolved &gt; should be a no-op for unknown docIds" time="0.001273188">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; getPendingDocumentsForReprobe &gt; should return docIds due for reprobe" time="0.001659056">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; getPendingDocumentsForReprobe &gt; should return empty array when no docs are due" time="0.002035511">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; getPendingDocumentsForReprobe &gt; should exclude ESCALATED and RESOLVED documents" time="0.002499997">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; escalateExpiredDocuments &gt; should escalate PENDING docs older than MAX_AGE_MS" time="0.002957271">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; escalateExpiredDocuments &gt; should return empty array when no docs are expired" time="0.002157573">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; getPendingDocumentsSummary &gt; should return &quot;0 tracked&quot; for an empty store" time="0.000740089">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; getPendingDocumentsSummary &gt; should include counts for each status" time="0.001288031">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; constants &gt; INITIAL_BACKOFF_MS should be 24 hours" time="0.000391937">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; constants &gt; MAX_BACKOFF_MS should be 72 hours" time="0.000385237">
        </testcase>
        <testcase classname="test/unit/pending-documents.test.js" name="pending-documents &gt; constants &gt; MAX_AGE_MS should be 14 days" time="0.000432198">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/political-intelligence-copy.test.js" timestamp="2026-04-28T00:15:08.348Z" hostname="runnervmeorf1" tests="64" failures="0" errors="0" skipped="0" time="0.048116454">
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="DEFAULT_COPY &gt; exposes every required PICopy key" time="0.004533565">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="DEFAULT_COPY &gt; English `sourceInEnglishNote` is empty (only emitted on translated pages)" time="0.000289784">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="DEFAULT_COPY &gt; plural label includes the {count} placeholder" time="0.000649133">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="DEFAULT_COPY &gt; singular label does NOT contain the {count} placeholder" time="0.000451267">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; declares every supported language" time="0.000634561">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; sv overrides at least title, breadcrumbCurrent, and home" time="0.001327249">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; da overrides at least title, breadcrumbCurrent, and home" time="0.000339199">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; no overrides at least title, breadcrumbCurrent, and home" time="0.00034677">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; fi overrides at least title, breadcrumbCurrent, and home" time="0.000365878">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; de overrides at least title, breadcrumbCurrent, and home" time="0.000348061">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; fr overrides at least title, breadcrumbCurrent, and home" time="0.000370956">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; es overrides at least title, breadcrumbCurrent, and home" time="0.000387351">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; nl overrides at least title, breadcrumbCurrent, and home" time="0.000363615">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; ar overrides at least title, breadcrumbCurrent, and home" time="0.000355242">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; he overrides at least title, breadcrumbCurrent, and home" time="0.000314972">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; ja overrides at least title, breadcrumbCurrent, and home" time="0.000312578">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; ko overrides at least title, breadcrumbCurrent, and home" time="0.000384726">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; zh overrides at least title, breadcrumbCurrent, and home" time="0.000356504">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; sv ships a non-empty sourceInEnglishNote" time="0.000246129">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; da ships a non-empty sourceInEnglishNote" time="0.000199339">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; no ships a non-empty sourceInEnglishNote" time="0.000188543">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; fi ships a non-empty sourceInEnglishNote" time="0.000305498">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; de ships a non-empty sourceInEnglishNote" time="0.000122764">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; fr ships a non-empty sourceInEnglishNote" time="0.000268062">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; es ships a non-empty sourceInEnglishNote" time="0.000145608">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; nl ships a non-empty sourceInEnglishNote" time="0.000135153">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; ar ships a non-empty sourceInEnglishNote" time="0.000193279">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; he ships a non-empty sourceInEnglishNote" time="0.000177396">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; ja ships a non-empty sourceInEnglishNote" time="0.000214081">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; ko ships a non-empty sourceInEnglishNote" time="0.000179099">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; zh ships a non-empty sourceInEnglishNote" time="0.000139179">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; sv plural labels keep the {count} placeholder" time="0.000350456">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; da plural labels keep the {count} placeholder" time="0.000428673">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; no plural labels keep the {count} placeholder" time="0.000224537">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; fi plural labels keep the {count} placeholder" time="0.000274672">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; de plural labels keep the {count} placeholder" time="0.000299719">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; fr plural labels keep the {count} placeholder" time="0.000296164">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; es plural labels keep the {count} placeholder" time="0.000257787">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; nl plural labels keep the {count} placeholder" time="0.000196064">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; ar plural labels keep the {count} placeholder" time="0.000319649">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; he plural labels keep the {count} placeholder" time="0.000180631">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; ja plural labels keep the {count} placeholder" time="0.000228713">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; ko plural labels keep the {count} placeholder" time="0.000217897">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; zh plural labels keep the {count} placeholder" time="0.000199139">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="PI_COPY &gt; English entry is the empty-overrides marker (defaults apply)" time="0.000442353">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="getPICopy &gt; returns DEFAULT_COPY for English" time="0.000385317">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="getPICopy &gt; merges Swedish overrides on top of English defaults" time="0.001535952">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="getPICopy &gt; en gets a fully-populated PICopy (no missing keys)" time="0.002840888">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="getPICopy &gt; sv gets a fully-populated PICopy (no missing keys)" time="0.001149563">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="getPICopy &gt; da gets a fully-populated PICopy (no missing keys)" time="0.001873799">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="getPICopy &gt; no gets a fully-populated PICopy (no missing keys)" time="0.001854319">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="getPICopy &gt; fi gets a fully-populated PICopy (no missing keys)" time="0.002167369">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="getPICopy &gt; de gets a fully-populated PICopy (no missing keys)" time="0.001766388">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="getPICopy &gt; fr gets a fully-populated PICopy (no missing keys)" time="0.001386428">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="getPICopy &gt; es gets a fully-populated PICopy (no missing keys)" time="0.001271365">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="getPICopy &gt; nl gets a fully-populated PICopy (no missing keys)" time="0.00111432">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="getPICopy &gt; ar gets a fully-populated PICopy (no missing keys)" time="0.001433749">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="getPICopy &gt; he gets a fully-populated PICopy (no missing keys)" time="0.001779046">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="getPICopy &gt; ja gets a fully-populated PICopy (no missing keys)" time="0.001464274">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="getPICopy &gt; ko gets a fully-populated PICopy (no missing keys)" time="0.001250274">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="getPICopy &gt; zh gets a fully-populated PICopy (no missing keys)" time="0.001444465">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="getPICopy &gt; falls back to English defaults for unknown codes" time="0.000514231">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="getPICopy &gt; does not leak prototype properties via prototype-pollution payloads" time="0.000205778">
        </testcase>
        <testcase classname="test/unit/political-intelligence-copy.test.js" name="getPICopy &gt; returned object does not share identity with DEFAULT_COPY" time="0.000518728">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/political-intelligence-data.test.js" timestamp="2026-04-28T00:15:08.356Z" hostname="runnervmeorf1" tests="10" failures="0" errors="0" skipped="0" time="0.045147355">
        <testcase classname="test/unit/political-intelligence-data.test.js" name="collectPoliticalIntelligenceData &gt; collects methodologies with README first" time="0.019380937">
        </testcase>
        <testcase classname="test/unit/political-intelligence-data.test.js" name="collectPoliticalIntelligenceData &gt; collects templates" time="0.001992777">
        </testcase>
        <testcase classname="test/unit/political-intelligence-data.test.js" name="collectPoliticalIntelligenceData &gt; collects reference docs from reference/imf/worldbank with source-prefixed stems" time="0.002578614">
        </testcase>
        <testcase classname="test/unit/political-intelligence-data.test.js" name="collectPoliticalIntelligenceData &gt; groups daily runs by date, newest first" time="0.001739588">
        </testcase>
        <testcase classname="test/unit/political-intelligence-data.test.js" name="collectPoliticalIntelligenceData &gt; skips empty run directories (no .md files)" time="0.001451125">
        </testcase>
        <testcase classname="test/unit/political-intelligence-data.test.js" name="collectPoliticalIntelligenceData &gt; skips non-date-shaped subdirectories" time="0.002750372">
        </testcase>
        <testcase classname="test/unit/political-intelligence-data.test.js" name="collectPoliticalIntelligenceData &gt; counts artifacts recursively (includes subdirectories)" time="0.002503222">
        </testcase>
        <testcase classname="test/unit/political-intelligence-data.test.js" name="collectPoliticalIntelligenceData &gt; attaches an icon to every PIDocument and PIDailyRun" time="0.001269332">
        </testcase>
        <testcase classname="test/unit/political-intelligence-data.test.js" name="collectPoliticalIntelligenceData &gt; handles a missing analysis/ tree gracefully (returns empty arrays)" time="0.000847179">
        </testcase>
        <testcase classname="test/unit/political-intelligence-data.test.js" name="collectPoliticalIntelligenceData &gt; returns POSIX-style relative paths even on path-separator-flexible platforms" time="0.001130845">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/political-intelligence-icons.test.js" timestamp="2026-04-28T00:15:08.358Z" hostname="runnervmeorf1" tests="11" failures="0" errors="0" skipped="0" time="0.010626596">
        <testcase classname="test/unit/political-intelligence-icons.test.js" name="pickDocumentIcon &gt; returns the SWOT icon for a swot stem" time="0.003724212">
        </testcase>
        <testcase classname="test/unit/political-intelligence-icons.test.js" name="pickDocumentIcon &gt; matches case-insensitively" time="0.000376684">
        </testcase>
        <testcase classname="test/unit/political-intelligence-icons.test.js" name="pickDocumentIcon &gt; matches by includes (substring), not equality" time="0.000291177">
        </testcase>
        <testcase classname="test/unit/political-intelligence-icons.test.js" name="pickDocumentIcon &gt; respects rule precedence — intelligence-brief beats intelligence" time="0.000226219">
        </testcase>
        <testcase classname="test/unit/political-intelligence-icons.test.js" name="pickDocumentIcon &gt; returns the default icon for unknown stems" time="0.000328913">
        </testcase>
        <testcase classname="test/unit/political-intelligence-icons.test.js" name="pickDocumentIcon &gt; returns expected icons for the most common artifact types" time="0.000623835">
        </testcase>
        <testcase classname="test/unit/political-intelligence-icons.test.js" name="pickDocumentIcon &gt; handles ZWJ-joined emoji (mep/parliamentarian icon)" time="0.000622653">
        </testcase>
        <testcase classname="test/unit/political-intelligence-icons.test.js" name="pickRunIcon &gt; matches by startsWith, not includes" time="0.000427922">
        </testcase>
        <testcase classname="test/unit/political-intelligence-icons.test.js" name="pickRunIcon &gt; matches case-insensitively" time="0.00024687">
        </testcase>
        <testcase classname="test/unit/political-intelligence-icons.test.js" name="pickRunIcon &gt; returns expected icons for every canonical run type" time="0.000494">
        </testcase>
        <testcase classname="test/unit/political-intelligence-icons.test.js" name="pickRunIcon &gt; returns the default icon for unknown run prefixes" time="0.000269805">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/political-intelligence-markdown.test.js" timestamp="2026-04-28T00:15:08.360Z" hostname="runnervmeorf1" tests="22" failures="0" errors="0" skipped="0" time="0.015308413">
        <testcase classname="test/unit/political-intelligence-markdown.test.js" name="stripLeadingEmoji &gt; returns plain text unchanged" time="0.003121298">
        </testcase>
        <testcase classname="test/unit/political-intelligence-markdown.test.js" name="stripLeadingEmoji &gt; strips a single leading emoji and surrounding whitespace" time="0.000525117">
        </testcase>
        <testcase classname="test/unit/political-intelligence-markdown.test.js" name="stripLeadingEmoji &gt; strips multiple leading emoji repeatedly" time="0.000244076">
        </testcase>
        <testcase classname="test/unit/political-intelligence-markdown.test.js" name="stripLeadingEmoji &gt; handles ZWJ sequences (e.g. 👨‍💻)" time="0.000354271">
        </testcase>
        <testcase classname="test/unit/political-intelligence-markdown.test.js" name="stripLeadingEmoji &gt; does not strip emoji from the middle of the heading" time="0.000228803">
        </testcase>
        <testcase classname="test/unit/political-intelligence-markdown.test.js" name="stripLeadingEmoji &gt; returns empty string when the input is only emoji" time="0.000394652">
        </testcase>
        <testcase classname="test/unit/political-intelligence-markdown.test.js" name="stripLeadingEmoji &gt; returns empty string when the input is empty" time="0.000196955">
        </testcase>
        <testcase classname="test/unit/political-intelligence-markdown.test.js" name="extractH1Title &gt; returns the first H1 heading" time="0.000498938">
        </testcase>
        <testcase classname="test/unit/political-intelligence-markdown.test.js" name="extractH1Title &gt; strips a leading emoji from the H1" time="0.000730044">
        </testcase>
        <testcase classname="test/unit/political-intelligence-markdown.test.js" name="extractH1Title &gt; returns the fallback when no H1 is present" time="0.000246319">
        </testcase>
        <testcase classname="test/unit/political-intelligence-markdown.test.js" name="extractH1Title &gt; skips lines until it finds the first H1" time="0.000250535">
        </testcase>
        <testcase classname="test/unit/political-intelligence-markdown.test.js" name="extractH1Title &gt; does not treat ## as an H1" time="0.000194021">
        </testcase>
        <testcase classname="test/unit/political-intelligence-markdown.test.js" name="humanize &gt; replaces dashes with spaces" time="0.000336905">
        </testcase>
        <testcase classname="test/unit/political-intelligence-markdown.test.js" name="humanize &gt; replaces underscores with spaces" time="0.000211517">
        </testcase>
        <testcase classname="test/unit/political-intelligence-markdown.test.js" name="humanize &gt; handles mixed separators" time="0.000203164">
        </testcase>
        <testcase classname="test/unit/political-intelligence-markdown.test.js" name="humanize &gt; collapses runs of separators into a single space" time="0.000182133">
        </testcase>
        <testcase classname="test/unit/political-intelligence-markdown.test.js" name="humanize &gt; title-cases the first letter of each word" time="0.000176905">
        </testcase>
        <testcase classname="test/unit/political-intelligence-markdown.test.js" name="humanize &gt; returns empty for empty input" time="0.000202504">
        </testcase>
        <testcase classname="test/unit/political-intelligence-markdown.test.js" name="parseMarkdownMeta &gt; returns the H1 as title with leading emoji stripped" time="0.000455773">
        </testcase>
        <testcase classname="test/unit/political-intelligence-markdown.test.js" name="parseMarkdownMeta &gt; falls back to humanized stem when the file has no H1" time="0.000380049">
        </testcase>
        <testcase classname="test/unit/political-intelligence-markdown.test.js" name="parseMarkdownMeta &gt; returns humanized fallback when the file does not exist" time="0.000328342">
        </testcase>
        <testcase classname="test/unit/political-intelligence-markdown.test.js" name="parseMarkdownMeta &gt; always returns an empty description (curated table is the source of truth)" time="0.000375543">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/political-intelligence.test.js" timestamp="2026-04-28T00:15:08.363Z" hostname="runnervmeorf1" tests="28" failures="0" errors="0" skipped="0" time="0.118229302">
        <testcase classname="test/unit/political-intelligence.test.js" name="political-intelligence generator &gt; getPoliticalIntelligenceFilename &gt; returns bare filename for English" time="0.00343639">
        </testcase>
        <testcase classname="test/unit/political-intelligence.test.js" name="political-intelligence generator &gt; getPoliticalIntelligenceFilename &gt; returns language-suffixed filenames for all 13 non-English locales" time="0.000945017">
        </testcase>
        <testcase classname="test/unit/political-intelligence.test.js" name="political-intelligence generator &gt; pickDocumentIcon &gt; returns themed icons for common artifact concepts" time="0.000934791">
        </testcase>
        <testcase classname="test/unit/political-intelligence.test.js" name="political-intelligence generator &gt; pickDocumentIcon &gt; returns a neutral fallback icon for unknown stems" time="0.000316354">
        </testcase>
        <testcase classname="test/unit/political-intelligence.test.js" name="political-intelligence generator &gt; pickRunIcon &gt; maps run slug prefixes to recognizable icons" time="0.000778036">
        </testcase>
        <testcase classname="test/unit/political-intelligence.test.js" name="political-intelligence generator &gt; pickRunIcon &gt; returns a neutral icon for unknown run slugs" time="0.000165147">
        </testcase>
        <testcase classname="test/unit/political-intelligence.test.js" name="political-intelligence generator &gt; parseMarkdownMeta &gt; extracts H1 title and leaves description empty (curated-table drives description)" time="0.002330122">
        </testcase>
        <testcase classname="test/unit/political-intelligence.test.js" name="political-intelligence generator &gt; parseMarkdownMeta &gt; falls back to a humanized stem if no H1 is present" time="0.000945537">
        </testcase>
        <testcase classname="test/unit/political-intelligence.test.js" name="political-intelligence generator &gt; parseMarkdownMeta &gt; returns safe defaults when the file cannot be read" time="0.001504545">
        </testcase>
        <testcase classname="test/unit/political-intelligence.test.js" name="political-intelligence generator &gt; collectPoliticalIntelligenceData + generatePoliticalIntelligenceHTML &gt; collects methodologies, templates, and daily runs correctly" time="0.01781498">
        </testcase>
        <testcase classname="test/unit/political-intelligence.test.js" name="political-intelligence generator &gt; collectPoliticalIntelligenceData + generatePoliticalIntelligenceHTML &gt; prunes empty-run directories and non-date directories" time="0.005953753">
        </testcase>
        <testcase classname="test/unit/political-intelligence.test.js" name="political-intelligence generator &gt; collectPoliticalIntelligenceData + generatePoliticalIntelligenceHTML &gt; renders a complete HTML document with canonical, hreflang alternates, JSON-LD and footer cross-links" time="0.013433884">
        </testcase>
        <testcase classname="test/unit/political-intelligence.test.js" name="political-intelligence generator &gt; collectPoliticalIntelligenceData + generatePoliticalIntelligenceHTML &gt; renders rich, localized run cards + per-artifact cards (not bare filename links)" time="0.018066146">
        </testcase>
        <testcase classname="test/unit/political-intelligence.test.js" name="political-intelligence generator &gt; collectPoliticalIntelligenceData + generatePoliticalIntelligenceHTML &gt; ships distinct localized SEO keywords for all 14 language pages" time="0.01947019">
        </testcase>
        <testcase classname="test/unit/political-intelligence.test.js" name="political-intelligence generator &gt; collectPoliticalIntelligenceData + generatePoliticalIntelligenceHTML &gt; emits a valid English variant with the bare filename in canonical + JSON-LD urls" time="0.004996188">
        </testcase>
        <testcase classname="test/unit/political-intelligence.test.js" name="political-intelligence generator &gt; collectPoliticalIntelligenceData + generatePoliticalIntelligenceHTML &gt; sets dir=&quot;rtl&quot; for Arabic and Hebrew" time="0.005546913">
        </testcase>
        <testcase classname="test/unit/political-intelligence.test.js" name="political-intelligence generator &gt; getCuratedDescription (curated per-file, per-language descriptions) &gt; returns the curated English description for a known methodology path" time="0.000259329">
        </testcase>
        <testcase classname="test/unit/political-intelligence.test.js" name="political-intelligence generator &gt; getCuratedDescription (curated per-file, per-language descriptions) &gt; returns the localized description when a per-language overlay exists" time="0.000305588">
        </testcase>
        <testcase classname="test/unit/political-intelligence.test.js" name="political-intelligence generator &gt; getCuratedDescription (curated per-file, per-language descriptions) &gt; falls back to a localized sentence (not raw English) when a non-English language overlay is missing" time="0.000453079">
        </testcase>
        <testcase classname="test/unit/political-intelligence.test.js" name="political-intelligence generator &gt; getCuratedDescription (curated per-file, per-language descriptions) &gt; returns a fully-localized card title for every curated methodology across all 14 languages" time="0.002211524">
        </testcase>
        <testcase classname="test/unit/political-intelligence.test.js" name="political-intelligence generator &gt; getCuratedDescription (curated per-file, per-language descriptions) &gt; falls back to the H1 title when neither the curated title overlay nor description entry has a localized title" time="0.000279539">
        </testcase>
        <testcase classname="test/unit/political-intelligence.test.js" name="political-intelligence generator &gt; getCuratedDescription (curated per-file, per-language descriptions) &gt; returns a localized generic fallback for unmapped methodology / template files" time="0.000422873">
        </testcase>
        <testcase classname="test/unit/political-intelligence.test.js" name="political-intelligence generator &gt; getCuratedDescription (curated per-file, per-language descriptions) &gt; never returns an empty string — every file+lang combo yields a renderable description" time="0.005205442">
        </testcase>
        <testcase classname="test/unit/political-intelligence.test.js" name="political-intelligence generator &gt; getArtifactInfo (feed-prefix + synonym + orphan coverage) &gt; collapses every feed-prefixed artifact into a single localized per-item label" time="0.002813076">
        </testcase>
        <testcase classname="test/unit/political-intelligence.test.js" name="political-intelligence generator &gt; getArtifactInfo (feed-prefix + synonym + orphan coverage) &gt; applies synonyms so ai-/political- variants share the curated template entry" time="0.000559699">
        </testcase>
        <testcase classname="test/unit/political-intelligence.test.js" name="political-intelligence generator &gt; getArtifactInfo (feed-prefix + synonym + orphan coverage) &gt; ships orphan artifact stems in all 14 languages" time="0.003279736">
        </testcase>
        <testcase classname="test/unit/political-intelligence.test.js" name="political-intelligence generator &gt; getArtifactInfo (feed-prefix + synonym + orphan coverage) &gt; falls back to the daily-artifact kind word (not &quot;template&quot;) for unmapped stems" time="0.000424376">
        </testcase>
        <testcase classname="test/unit/political-intelligence.test.js" name="political-intelligence generator &gt; getArtifactInfo (feed-prefix + synonym + orphan coverage) &gt; is immune to prototype-key lookups (__proto__, constructor)" time="0.00072683">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/prior-run-diff.test.js" timestamp="2026-04-28T00:15:08.367Z" hostname="runnervmeorf1" tests="23" failures="0" errors="0" skipped="0" time="0.221379495">
        <testcase classname="test/unit/prior-run-diff.test.js" name="scripts/aggregator/prior-run-diff.js &gt; CLI &gt; exits 2 with no arguments" time="0.047027972">
        </testcase>
        <testcase classname="test/unit/prior-run-diff.test.js" name="scripts/aggregator/prior-run-diff.js &gt; CLI &gt; exits 1 when runDir does not exist" time="0.04491844">
        </testcase>
        <testcase classname="test/unit/prior-run-diff.test.js" name="scripts/aggregator/prior-run-diff.js &gt; CLI &gt; emits valid JSON to stdout when feature is disabled (no env flag)" time="0.048230494">
        </testcase>
        <testcase classname="test/unit/prior-run-diff.test.js" name="scripts/aggregator/prior-run-diff.js &gt; CLI &gt; emits valid JSON with enabled=true when ENABLE_PRIOR_RUN_MERGE=true" time="0.046114502">
        </testcase>
        <testcase classname="test/unit/prior-run-diff.test.js" name="scripts/aggregator/prior-run-diff.js &gt; classifyArtifact &gt; returns atFloor=false with reason=missing when file absent" time="0.001179498">
        </testcase>
        <testcase classname="test/unit/prior-run-diff.test.js" name="scripts/aggregator/prior-run-diff.js &gt; classifyArtifact &gt; returns atFloor=false when file is shorter than floor" time="0.001637715">
        </testcase>
        <testcase classname="test/unit/prior-run-diff.test.js" name="scripts/aggregator/prior-run-diff.js &gt; classifyArtifact &gt; returns atFloor=true when file meets floor with no placeholders or mermaid required" time="0.001399858">
        </testcase>
        <testcase classname="test/unit/prior-run-diff.test.js" name="scripts/aggregator/prior-run-diff.js &gt; classifyArtifact &gt; returns atFloor=false when placeholder found" time="0.001182633">
        </testcase>
        <testcase classname="test/unit/prior-run-diff.test.js" name="scripts/aggregator/prior-run-diff.js &gt; classifyArtifact &gt; returns atFloor=false when mermaid is required but missing" time="0.001718336">
        </testcase>
        <testcase classname="test/unit/prior-run-diff.test.js" name="scripts/aggregator/prior-run-diff.js &gt; classifyArtifact &gt; returns atFloor=true when mermaid is required and present" time="0.001197755">
        </testcase>
        <testcase classname="test/unit/prior-run-diff.test.js" name="scripts/aggregator/prior-run-diff.js &gt; classifyArtifact &gt; returns atFloor=false for intelligence/ artifact lacking mermaid (dir heuristic)" time="0.001562642">
        </testcase>
        <testcase classname="test/unit/prior-run-diff.test.js" name="scripts/aggregator/prior-run-diff.js &gt; buildPriorRunDiff &gt; returns enabled=false when disabled flag is passed" time="0.00139465">
        </testcase>
        <testcase classname="test/unit/prior-run-diff.test.js" name="scripts/aggregator/prior-run-diff.js &gt; buildPriorRunDiff &gt; returns empty carryForward and rewrite when history is empty" time="0.001352177">
        </testcase>
        <testcase classname="test/unit/prior-run-diff.test.js" name="scripts/aggregator/prior-run-diff.js &gt; buildPriorRunDiff &gt; returns empty carryForward and rewrite when manifest is absent" time="0.00239555">
        </testcase>
        <testcase classname="test/unit/prior-run-diff.test.js" name="scripts/aggregator/prior-run-diff.js &gt; buildPriorRunDiff &gt; all artifacts at-floor → all in carryForward, rewrite empty" time="0.003035229">
        </testcase>
        <testcase classname="test/unit/prior-run-diff.test.js" name="scripts/aggregator/prior-run-diff.js &gt; buildPriorRunDiff &gt; mixed: at-floor artifact carried forward, below-floor in rewrite" time="0.002432516">
        </testcase>
        <testcase classname="test/unit/prior-run-diff.test.js" name="scripts/aggregator/prior-run-diff.js &gt; buildPriorRunDiff &gt; uses the last history entry as priorRunId" time="0.002056772">
        </testcase>
        <testcase classname="test/unit/prior-run-diff.test.js" name="scripts/aggregator/prior-run-diff.js &gt; buildPriorRunDiff &gt; works with null thresholdsJson (falls back to DEFAULT_MIN_LINES)" time="0.001416553">
        </testcase>
        <testcase classname="test/unit/prior-run-diff.test.js" name="scripts/aggregator/prior-run-diff.js &gt; buildPriorRunDiff &gt; resolves articleType from legacy manifest.articleTypes[] schema" time="0.001098136">
        </testcase>
        <testcase classname="test/unit/prior-run-diff.test.js" name="scripts/aggregator/prior-run-diff.js &gt; buildPriorRunDiff &gt; resolves articleType from legacy manifest.runType schema" time="0.001007981">
        </testcase>
        <testcase classname="test/unit/prior-run-diff.test.js" name="scripts/aggregator/prior-run-diff.js &gt; buildPriorRunDiff &gt; handles manifest.files entries that are bare strings (e.g. &quot;executiveBrief&quot;: &quot;executive-brief.md&quot;)" time="0.001569232">
        </testcase>
        <testcase classname="test/unit/prior-run-diff.test.js" name="scripts/aggregator/prior-run-diff.js &gt; buildPriorRunDiff &gt; does not treat arbitrary object keys (e.g. language codes) as artifact paths" time="0.002202861">
        </testcase>
        <testcase classname="test/unit/prior-run-diff.test.js" name="scripts/aggregator/prior-run-diff.js &gt; buildPriorRunDiff &gt; snapshot: plan shape is stable" time="0.002516932">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/procedure-seen-cache.test.js" timestamp="2026-04-28T00:15:08.370Z" hostname="runnervmeorf1" tests="25" failures="0" errors="0" skipped="0" time="0.022347283">
        <testcase classname="test/unit/procedure-seen-cache.test.js" name="ProcedureSeenCache &gt; constructor &gt; should create an empty cache when the file does not exist" time="0.003189932">
        </testcase>
        <testcase classname="test/unit/procedure-seen-cache.test.js" name="ProcedureSeenCache &gt; constructor &gt; should export DEFAULT_PROCEDURE_SEEN_CACHE_PATH" time="0.000664486">
        </testcase>
        <testcase classname="test/unit/procedure-seen-cache.test.js" name="ProcedureSeenCache &gt; constructor &gt; should load existing entries from disk" time="0.000886448">
        </testcase>
        <testcase classname="test/unit/procedure-seen-cache.test.js" name="ProcedureSeenCache &gt; constructor &gt; should return empty cache when file is malformed JSON" time="0.000772568">
        </testcase>
        <testcase classname="test/unit/procedure-seen-cache.test.js" name="ProcedureSeenCache &gt; constructor &gt; should return empty cache when file has wrong version" time="0.000670094">
        </testcase>
        <testcase classname="test/unit/procedure-seen-cache.test.js" name="ProcedureSeenCache &gt; constructor &gt; should return empty cache when file is an array" time="0.00059366">
        </testcase>
        <testcase classname="test/unit/procedure-seen-cache.test.js" name="ProcedureSeenCache &gt; constructor &gt; should skip entries with missing required fields" time="0.000747881">
        </testcase>
        <testcase classname="test/unit/procedure-seen-cache.test.js" name="ProcedureSeenCache &gt; upsert &gt; should add a new entry" time="0.000812868">
        </testcase>
        <testcase classname="test/unit/procedure-seen-cache.test.js" name="ProcedureSeenCache &gt; upsert &gt; should update an existing entry when dateLastActivity changes" time="0.000610244">
        </testcase>
        <testcase classname="test/unit/procedure-seen-cache.test.js" name="ProcedureSeenCache &gt; upsert &gt; should not mark dirty when dateLastActivity is unchanged" time="0.000872628">
        </testcase>
        <testcase classname="test/unit/procedure-seen-cache.test.js" name="ProcedureSeenCache &gt; getDateLastActivity &gt; should return undefined for unknown procedure ID" time="0.000593059">
        </testcase>
        <testcase classname="test/unit/procedure-seen-cache.test.js" name="ProcedureSeenCache &gt; getDateLastActivity &gt; should return the stored dateLastActivity" time="0.000402643">
        </testcase>
        <testcase classname="test/unit/procedure-seen-cache.test.js" name="ProcedureSeenCache &gt; has &gt; should return false for unknown ID" time="0.000463134">
        </testcase>
        <testcase classname="test/unit/procedure-seen-cache.test.js" name="ProcedureSeenCache &gt; has &gt; should return true after upsert" time="0.000439909">
        </testcase>
        <testcase classname="test/unit/procedure-seen-cache.test.js" name="ProcedureSeenCache &gt; getNewOrUpdatedIds &gt; should return all IDs when cache is empty" time="0.001735592">
        </testcase>
        <testcase classname="test/unit/procedure-seen-cache.test.js" name="ProcedureSeenCache &gt; getNewOrUpdatedIds &gt; should exclude IDs whose dateLastActivity is unchanged" time="0.000525668">
        </testcase>
        <testcase classname="test/unit/procedure-seen-cache.test.js" name="ProcedureSeenCache &gt; getNewOrUpdatedIds &gt; should include IDs whose dateLastActivity has changed" time="0.000527971">
        </testcase>
        <testcase classname="test/unit/procedure-seen-cache.test.js" name="ProcedureSeenCache &gt; getNewOrUpdatedIds &gt; should return empty array when all items are unchanged" time="0.000530896">
        </testcase>
        <testcase classname="test/unit/procedure-seen-cache.test.js" name="ProcedureSeenCache &gt; save &gt; should persist entries to disk" time="0.0007805">
        </testcase>
        <testcase classname="test/unit/procedure-seen-cache.test.js" name="ProcedureSeenCache &gt; save &gt; should create parent directories if they do not exist" time="0.000856153">
        </testcase>
        <testcase classname="test/unit/procedure-seen-cache.test.js" name="ProcedureSeenCache &gt; save &gt; should be idempotent when not dirty" time="0.000671457">
        </testcase>
        <testcase classname="test/unit/procedure-seen-cache.test.js" name="ProcedureSeenCache &gt; save &gt; should round-trip correctly (save then reload)" time="0.000806379">
        </testcase>
        <testcase classname="test/unit/procedure-seen-cache.test.js" name="ProcedureSeenCache &gt; size &gt; should return 0 for a new empty cache" time="0.000371276">
        </testcase>
        <testcase classname="test/unit/procedure-seen-cache.test.js" name="ProcedureSeenCache &gt; size &gt; should reflect the number of upserted entries" time="0.00038039">
        </testcase>
        <testcase classname="test/unit/procedure-seen-cache.test.js" name="ProcedureSeenCache &gt; size &gt; should not double-count when upserting the same ID" time="0.000439038">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/runs.test.js" timestamp="2026-04-28T00:15:08.374Z" hostname="runnervmeorf1" tests="25" failures="0" errors="0" skipped="0" time="0.04632551">
        <testcase classname="test/unit/runs.test.js" name="dateFromPath &gt; extracts ISO date from a typical run dir" time="0.003300196">
        </testcase>
        <testcase classname="test/unit/runs.test.js" name="dateFromPath &gt; falls back to epoch when no ISO date is present" time="0.000465348">
        </testcase>
        <testcase classname="test/unit/runs.test.js" name="dateFromPath &gt; picks the first match when several are present" time="0.00024652">
        </testcase>
        <testcase classname="test/unit/runs.test.js" name="readRunCandidate &gt; returns null when manifest is missing" time="0.001305487">
        </testcase>
        <testcase classname="test/unit/runs.test.js" name="readRunCandidate &gt; returns null on malformed JSON without throwing" time="0.000962302">
        </testcase>
        <testcase classname="test/unit/runs.test.js" name="readRunCandidate &gt; returns null when articleType resolves to &quot;unknown&quot;" time="0.000733068">
        </testcase>
        <testcase classname="test/unit/runs.test.js" name="readRunCandidate &gt; reads a canonical articleType manifest" time="0.00188184">
        </testcase>
        <testcase classname="test/unit/runs.test.js" name="readRunCandidate &gt; reads a legacy articleTypes[] manifest" time="0.000687581">
        </testcase>
        <testcase classname="test/unit/runs.test.js" name="readRunCandidate &gt; reads a very-legacy runType manifest" time="0.001203414">
        </testcase>
        <testcase classname="test/unit/runs.test.js" name="readRunCandidate &gt; falls back to directory basename when runId is missing" time="0.00081416">
        </testcase>
        <testcase classname="test/unit/runs.test.js" name="readRunCandidate &gt; coerces numeric runId to string" time="0.000892578">
        </testcase>
        <testcase classname="test/unit/runs.test.js" name="readRunCandidate &gt; falls back to dateFromPath when manifest date is missing" time="0.001044906">
        </testcase>
        <testcase classname="test/unit/runs.test.js" name="discoverAnalysisRuns &gt; returns [] when analysis/daily does not exist" time="0.000661001">
        </testcase>
        <testcase classname="test/unit/runs.test.js" name="discoverAnalysisRuns &gt; discovers a flat run directory" time="0.00288212">
        </testcase>
        <testcase classname="test/unit/runs.test.js" name="discoverAnalysisRuns &gt; sorts results by date ascending then by path lexically" time="0.015304508">
        </testcase>
        <testcase classname="test/unit/runs.test.js" name="discoverAnalysisRuns &gt; skips dirs whose manifest is malformed JSON" time="0.00228862">
        </testcase>
        <testcase classname="test/unit/runs.test.js" name="discoverAnalysisRuns &gt; skips dirs without a manifest, descending into their children" time="0.001542632">
        </testcase>
        <testcase classname="test/unit/runs.test.js" name="discoverAnalysisRuns &gt; does not descend once a manifest is found (no nested-run pollution)" time="0.001885836">
        </testcase>
        <testcase classname="test/unit/runs.test.js" name="discoverAnalysisRuns &gt; handles legacy schema variants in the same walk" time="0.002769991">
        </testcase>
        <testcase classname="test/unit/runs.test.js" name="collisionKey &gt; joins date and articleType with a pipe" time="0.000495773">
        </testcase>
        <testcase classname="test/unit/runs.test.js" name="groupRunsForCollision &gt; returns empty map for empty input" time="0.000271537">
        </testcase>
        <testcase classname="test/unit/runs.test.js" name="groupRunsForCollision &gt; groups one run into its own bucket" time="0.000361062">
        </testcase>
        <testcase classname="test/unit/runs.test.js" name="groupRunsForCollision &gt; detects 2-way collisions on shared (date, articleType)" time="0.000319539">
        </testcase>
        <testcase classname="test/unit/runs.test.js" name="groupRunsForCollision &gt; separates distinct (date, articleType) tuples" time="0.000670445">
        </testcase>
        <testcase classname="test/unit/runs.test.js" name="groupRunsForCollision &gt; preserves insertion order within a bucket" time="0.000297976">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/section-builders.test.js" timestamp="2026-04-28T00:15:08.378Z" hostname="runnervmeorf1" tests="48" failures="0" errors="0" skipped="0" time="0.028989828">
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; computeArticleQualityScore &gt; should return needs-improvement for empty content" time="0.006537859">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; computeArticleQualityScore &gt; should strip HTML tags when counting words" time="0.000467121">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; computeArticleQualityScore &gt; should count section elements as analysisSections" time="0.000304607">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; computeArticleQualityScore &gt; should count dashboard, mindmap, and SWOT as visualizations not analysis sections" time="0.000506569">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; computeArticleQualityScore &gt; should detect multi-class SWOT sections like swot-multidimensional" time="0.000314431">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; computeArticleQualityScore &gt; should not count nested dashboard-grid/dashboard-panel as dashboard sections" time="0.000419579">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; computeArticleQualityScore &gt; should rate excellent for rich content" time="0.000678357">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; computeArticleQualityScore &gt; should rate good for medium content" time="0.000609553">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; computeArticleQualityScore &gt; should exclude script content from word count" time="0.0003005">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; computeArticleQualityScore &gt; should count EP document links as evidence references" time="0.00034718">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; computeArticleQualityScore &gt; should not count bare EP homepage link as evidence" time="0.000322613">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; computeArticleQualityScore &gt; should not count europarl links inside script blocks as evidence" time="0.000277606">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; computeArticleQualityScore &gt; should not count section tags inside script blocks" time="0.000290025">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildTableOfContents &gt; should return empty string for empty entries" time="0.000441091">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildTableOfContents &gt; should render nav with list items" time="0.000991636">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildTableOfContents &gt; should use localised aria-label for non-English languages" time="0.000332288">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildTableOfContents &gt; should add toc-sub class for level-2 entries" time="0.000243896">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildTableOfContents &gt; should escape HTML in labels" time="0.000471427">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildTableOfContents &gt; should strip leading # from entry ids" time="0.000370876">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildQualityScoreBadge &gt; should return empty string for needs-improvement score" time="0.000262884">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildQualityScoreBadge &gt; should render badge for good score" time="0.000371757">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildQualityScoreBadge &gt; should include aria-hidden attribute" time="0.000201583">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildTimelineSection &gt; should return empty string for empty items" time="0.000326128">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildTimelineSection &gt; should render a timeline section with items" time="0.000552448">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildTimelineSection &gt; should use localized heading for German" time="0.00023344">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildTimelineSection &gt; should use English fallback for unknown language" time="0.000220481">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildTimelineSection &gt; should escape HTML in date and label" time="0.000462203">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildTimelineSection &gt; should include aria-label on section" time="0.000281763">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildTimelineSection &gt; should render an ordered list" time="0.000218548">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildTimelineSection &gt; should render optional description when provided" time="0.000356114">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildTimelineSection &gt; should not render description element when not provided" time="0.000239729">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildComparisonTable &gt; should return empty string for empty before array" time="0.000405658">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildComparisonTable &gt; should return empty string for empty after array" time="0.000201482">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildComparisonTable &gt; should render a comparison table" time="0.00048675">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildComparisonTable &gt; should use localized column headers" time="0.000328783">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildComparisonTable &gt; should escape HTML in cell content" time="0.000332338">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildComparisonTable &gt; should include scope attributes for accessibility" time="0.000235473">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildComparisonTable &gt; should include role=&quot;region&quot; on wrapper" time="0.000249403">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildComparisonTable &gt; should handle mismatched array lengths using max length" time="0.001502172">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildKeyFiguresBar &gt; should return empty string for empty figures" time="0.000338677">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildKeyFiguresBar &gt; should render a key figures bar" time="0.000598547">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildKeyFiguresBar &gt; should use localized heading" time="0.000284747">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildKeyFiguresBar &gt; should include sr-only heading" time="0.00022691">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildKeyFiguresBar &gt; should include aria-label on figure cards" time="0.000322974">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildKeyFiguresBar &gt; should render optional description as sr-only" time="0.000524646">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildKeyFiguresBar &gt; should escape HTML in labels and values" time="0.000334852">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildKeyFiguresBar &gt; should include unit with aria-hidden" time="0.00026028">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildKeyFiguresBar &gt; should not render unit span when unit is not provided" time="0.000306539">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/shell-safety.test.js" timestamp="2026-04-28T00:15:08.385Z" hostname="runnervmeorf1" tests="57" failures="0" errors="0" skipped="0" time="0.012375027">
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; finds at least one shell script to check" time="0.002577994">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/awf-firewall-diagnostic.sh — no nested-parameter-expansion" time="0.000677156">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/awf-firewall-diagnostic.sh — no indirect-expansion" time="0.000301521">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/awf-firewall-diagnostic.sh — no parameter-transformation" time="0.000187511">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/awf-firewall-diagnostic.sh — no nested-command-substitution" time="0.000200911">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/awf-firewall-diagnostic.sh — no default-with-command-substitution" time="0.000228893">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/awf-firewall-diagnostic.sh — no redirection-in-command-substitution" time="0.00013341">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/awf-firewall-diagnostic.sh — no adjacent-random" time="0.000196675">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/awf-firewall-diagnostic.sh — no eval" time="0.000243154">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/checkpoint-analysis-to-memory.sh — no nested-parameter-expansion" time="0.000123235">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/checkpoint-analysis-to-memory.sh — no indirect-expansion" time="0.000159769">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/checkpoint-analysis-to-memory.sh — no parameter-transformation" time="0.000101302">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/checkpoint-analysis-to-memory.sh — no nested-command-substitution" time="0.000136344">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/checkpoint-analysis-to-memory.sh — no default-with-command-substitution" time="0.000069794">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/checkpoint-analysis-to-memory.sh — no redirection-in-command-substitution" time="0.000074962">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/checkpoint-analysis-to-memory.sh — no adjacent-random" time="0.000174972">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/checkpoint-analysis-to-memory.sh — no eval" time="0.000069955">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/gh-aw-pat-pr-fallback.sh — no nested-parameter-expansion" time="0.00012736">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/gh-aw-pat-pr-fallback.sh — no indirect-expansion" time="0.000118057">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/gh-aw-pat-pr-fallback.sh — no parameter-transformation" time="0.000170946">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/gh-aw-pat-pr-fallback.sh — no nested-command-substitution" time="0.00024048">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/gh-aw-pat-pr-fallback.sh — no default-with-command-substitution" time="0.000143976">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/gh-aw-pat-pr-fallback.sh — no redirection-in-command-substitution" time="0.00023391">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/gh-aw-pat-pr-fallback.sh — no adjacent-random" time="0.000076936">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/gh-aw-pat-pr-fallback.sh — no eval" time="0.000099359">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/imf-mcp-probe.sh — no nested-parameter-expansion" time="0.000062594">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/imf-mcp-probe.sh — no indirect-expansion" time="0.000048803">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/imf-mcp-probe.sh — no parameter-transformation" time="0.000079059">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/imf-mcp-probe.sh — no nested-command-substitution" time="0.000051418">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/imf-mcp-probe.sh — no default-with-command-substitution" time="0.000049414">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/imf-mcp-probe.sh — no redirection-in-command-substitution" time="0.000051988">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/imf-mcp-probe.sh — no adjacent-random" time="0.000056154">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/imf-mcp-probe.sh — no eval" time="0.000108012">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/mcp-setup.sh — no nested-parameter-expansion" time="0.000055493">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/mcp-setup.sh — no indirect-expansion" time="0.000076895">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/mcp-setup.sh — no parameter-transformation" time="0.000048192">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/mcp-setup.sh — no nested-command-substitution" time="0.000044597">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/mcp-setup.sh — no default-with-command-substitution" time="0.000072559">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/mcp-setup.sh — no redirection-in-command-substitution" time="0.000045027">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/mcp-setup.sh — no adjacent-random" time="0.000068873">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/mcp-setup.sh — no eval" time="0.000046369">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/resolve-analysis-dir.sh — no nested-parameter-expansion" time="0.000043926">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/resolve-analysis-dir.sh — no indirect-expansion" time="0.000067681">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/resolve-analysis-dir.sh — no parameter-transformation" time="0.000043375">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/resolve-analysis-dir.sh — no nested-command-substitution" time="0.000147911">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/resolve-analysis-dir.sh — no default-with-command-substitution" time="0.000120701">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/resolve-analysis-dir.sh — no redirection-in-command-substitution" time="0.000502373">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/resolve-analysis-dir.sh — no adjacent-random" time="0.000107931">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/resolve-analysis-dir.sh — no eval" time="0.000107521">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/wb-mcp-probe.sh — no nested-parameter-expansion" time="0.00012063">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/wb-mcp-probe.sh — no indirect-expansion" time="0.000052118">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/wb-mcp-probe.sh — no parameter-transformation" time="0.000138618">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/wb-mcp-probe.sh — no nested-command-substitution" time="0.000132459">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/wb-mcp-probe.sh — no default-with-command-substitution" time="0.000063455">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/wb-mcp-probe.sh — no redirection-in-command-substitution" time="0.000089334">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/wb-mcp-probe.sh — no adjacent-random" time="0.000060961">
        </testcase>
        <testcase classname="test/unit/shell-safety.test.js" name="shell-safety drift-guard (scripts/**.sh) &gt; scripts/wb-mcp-probe.sh — no eval" time="0.000060009">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/sitemap-html.test.js" timestamp="2026-04-28T00:15:08.393Z" hostname="runnervmeorf1" tests="18" failures="0" errors="0" skipped="0" time="0.019841997">
        <testcase classname="test/unit/sitemap-html.test.js" name="getSitemapFilename &gt; returns sitemap.html for English" time="0.002544493">
        </testcase>
        <testcase classname="test/unit/sitemap-html.test.js" name="getSitemapFilename &gt; returns sitemap_&lt;lang&gt;.html for non-English" time="0.000311747">
        </testcase>
        <testcase classname="test/unit/sitemap-html.test.js" name="getIndexFilename &gt; returns index.html for English" time="0.000341632">
        </testcase>
        <testcase classname="test/unit/sitemap-html.test.js" name="getIndexFilename &gt; returns index-&lt;lang&gt;.html (note dash, not underscore) for non-English" time="0.000202283">
        </testcase>
        <testcase classname="test/unit/sitemap-html.test.js" name="generateSitemapHTML &gt; emits a valid HTML5 document with the right lang/dir" time="0.003180367">
        </testcase>
        <testcase classname="test/unit/sitemap-html.test.js" name="generateSitemapHTML &gt; emits dir=&quot;rtl&quot; for Arabic" time="0.00062713">
        </testcase>
        <testcase classname="test/unit/sitemap-html.test.js" name="generateSitemapHTML &gt; emits dir=&quot;rtl&quot; for Hebrew" time="0.000478106">
        </testcase>
        <testcase classname="test/unit/sitemap-html.test.js" name="generateSitemapHTML &gt; emits 14 hreflang alternates plus x-default in &lt;head&gt;" time="0.001257155">
        </testcase>
        <testcase classname="test/unit/sitemap-html.test.js" name="generateSitemapHTML &gt; embeds JSON-LD CollectionPage with the article count" time="0.000929092">
        </testcase>
        <testcase classname="test/unit/sitemap-html.test.js" name="generateSitemapHTML &gt; escapes `&lt;` inside JSON-LD as \u003c" time="0.001047049">
        </testcase>
        <testcase classname="test/unit/sitemap-html.test.js" name="generateSitemapHTML &gt; renders the skip link and theme toggle" time="0.000725687">
        </testcase>
        <testcase classname="test/unit/sitemap-html.test.js" name="generateSitemapHTML &gt; marks the current language with aria-current=&quot;page&quot; in the language switcher" time="0.000833018">
        </testcase>
        <testcase classname="test/unit/sitemap-html.test.js" name="generateSitemapHTML &gt; omits the docs section when hasDocsDir is false" time="0.000619158">
        </testcase>
        <testcase classname="test/unit/sitemap-html.test.js" name="generateSitemapHTML &gt; renders the docs section when hasDocsDir is true" time="0.000474982">
        </testcase>
        <testcase classname="test/unit/sitemap-html.test.js" name="generateSitemapHTML &gt; escapes article titles, descriptions, and filenames" time="0.000495582">
        </testcase>
        <testcase classname="test/unit/sitemap-html.test.js" name="generateSitemapHTML &gt; shows the empty-state stats when no articles are supplied" time="0.000442994">
        </testcase>
        <testcase classname="test/unit/sitemap-html.test.js" name="generateSitemapHTML &gt; groups articles by editorial category in canonical order" time="0.000574161">
        </testcase>
        <testcase classname="test/unit/sitemap-html.test.js" name="generateSitemapHTML &gt; emits canonical URL using the BASE_URL constant" time="0.002195661">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/sitemap-rss-and-xml-utils.test.js" timestamp="2026-04-28T00:15:08.395Z" hostname="runnervmeorf1" tests="16" failures="0" errors="0" skipped="0" time="0.010589711">
        <testcase classname="test/unit/sitemap-rss-and-xml-utils.test.js" name="escapeXML &gt; escapes the five predefined XML entities" time="0.002788219">
        </testcase>
        <testcase classname="test/unit/sitemap-rss-and-xml-utils.test.js" name="escapeXML &gt; escapes a mix of entities in one pass without double-encoding" time="0.000499368">
        </testcase>
        <testcase classname="test/unit/sitemap-rss-and-xml-utils.test.js" name="escapeXML &gt; returns empty string unchanged" time="0.000223875">
        </testcase>
        <testcase classname="test/unit/sitemap-rss-and-xml-utils.test.js" name="escapeXML &gt; passes alphanumeric input through unchanged" time="0.000170475">
        </testcase>
        <testcase classname="test/unit/sitemap-rss-and-xml-utils.test.js" name="escapeXML &gt; always escapes the literal `&amp;`, even inside an existing entity reference" time="0.000154611">
        </testcase>
        <testcase classname="test/unit/sitemap-rss-and-xml-utils.test.js" name="escapeXML &gt; handles long strings with many special characters" time="0.000390335">
        </testcase>
        <testcase classname="test/unit/sitemap-rss-and-xml-utils.test.js" name="generateRssFeed &gt; returns a valid RSS 2.0 envelope with required channel elements" time="0.000517806">
        </testcase>
        <testcase classname="test/unit/sitemap-rss-and-xml-utils.test.js" name="generateRssFeed &gt; declares the required XML namespaces (atom + dc)" time="0.000221582">
        </testcase>
        <testcase classname="test/unit/sitemap-rss-and-xml-utils.test.js" name="generateRssFeed &gt; renders one &lt;item&gt; per article with all required elements" time="0.000686429">
        </testcase>
        <testcase classname="test/unit/sitemap-rss-and-xml-utils.test.js" name="generateRssFeed &gt; escapes XML entities in titles, descriptions, and links" time="0.000321682">
        </testcase>
        <testcase classname="test/unit/sitemap-rss-and-xml-utils.test.js" name="generateRssFeed &gt; escapes the lang code (defensive — language is technically untrusted input)" time="0.000218427">
        </testcase>
        <testcase classname="test/unit/sitemap-rss-and-xml-utils.test.js" name="generateRssFeed &gt; produces an empty &lt;items&gt; section for an empty input array" time="0.000199249">
        </testcase>
        <testcase classname="test/unit/sitemap-rss-and-xml-utils.test.js" name="generateRssFeed &gt; preserves item order (caller is responsible for sorting)" time="0.000225969">
        </testcase>
        <testcase classname="test/unit/sitemap-rss-and-xml-utils.test.js" name="generateRssFeed &gt; uses now() for buildDate when no override is provided" time="0.000723004">
        </testcase>
        <testcase classname="test/unit/sitemap-rss-and-xml-utils.test.js" name="generateRssFeed &gt; with an override is fully deterministic across calls" time="0.00021357">
        </testcase>
        <testcase classname="test/unit/sitemap-rss-and-xml-utils.test.js" name="generateRssFeed &gt; embeds the production BASE_URL in the channel &lt;link&gt;" time="0.000398327">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/sitemap-xml.test.js" timestamp="2026-04-28T00:15:08.398Z" hostname="runnervmeorf1" tests="11" failures="0" errors="0" skipped="0" time="0.028681577">
        <testcase classname="test/unit/sitemap-xml.test.js" name="collectDocsHtmlFiles &gt; returns an empty array when the directory does not exist" time="0.002832466">
        </testcase>
        <testcase classname="test/unit/sitemap-xml.test.js" name="collectDocsHtmlFiles &gt; finds nested HTML files and ignores non-HTML" time="0.002126748">
        </testcase>
        <testcase classname="test/unit/sitemap-xml.test.js" name="collectDocsHtmlFiles &gt; returns paths sorted alphabetically" time="0.000711607">
        </testcase>
        <testcase classname="test/unit/sitemap-xml.test.js" name="collectDocsHtmlFiles &gt; uses POSIX separators even on Windows-style paths" time="0.00073448">
        </testcase>
        <testcase classname="test/unit/sitemap-xml.test.js" name="generateSitemap &gt; returns a well-formed XML document with the required namespaces" time="0.003687266">
        </testcase>
        <testcase classname="test/unit/sitemap-xml.test.js" name="generateSitemap &gt; emits 14 index URLs + 14 sitemap HTML URLs + 14 PI URLs + 1 RSS URL when no articles supplied" time="0.001265797">
        </testcase>
        <testcase classname="test/unit/sitemap-xml.test.js" name="generateSitemap &gt; emits hreflang alternates for every multilingual surface" time="0.001576162">
        </testcase>
        <testcase classname="test/unit/sitemap-xml.test.js" name="generateSitemap &gt; embeds the RSS feed URL with daily changefreq" time="0.001577314">
        </testcase>
        <testcase classname="test/unit/sitemap-xml.test.js" name="generateSitemap &gt; appends docs URLs without hreflang alternates" time="0.004004391">
        </testcase>
        <testcase classname="test/unit/sitemap-xml.test.js" name="generateSitemap &gt; escapes XML entities in URLs" time="0.002107899">
        </testcase>
        <testcase classname="test/unit/sitemap-xml.test.js" name="generateSitemap &gt; points x-default at the English variant" time="0.002119667">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/slug.test.js" timestamp="2026-04-28T00:15:08.399Z" hostname="runnervmeorf1" tests="15" failures="0" errors="0" skipped="0" time="0.0092411">
        <testcase classname="test/unit/slug.test.js" name="buildArticleSlug &gt; builds a base slug without runSuffix" time="0.002639116">
        </testcase>
        <testcase classname="test/unit/slug.test.js" name="buildArticleSlug &gt; appends a runSuffix when provided" time="0.000257066">
        </testcase>
        <testcase classname="test/unit/slug.test.js" name="buildArticleSlug &gt; treats empty runSuffix as falsy and omits the suffix" time="0.000199218">
        </testcase>
        <testcase classname="test/unit/slug.test.js" name="buildArticleSlug &gt; treats undefined runSuffix as no suffix" time="0.000176064">
        </testcase>
        <testcase classname="test/unit/slug.test.js" name="buildArticleSlug &gt; matches the legacy article-generator export byte-for-byte" time="0.000247601">
        </testcase>
        <testcase classname="test/unit/slug.test.js" name="sanitizeRunSuffix &gt; returns clean ASCII run-id unchanged" time="0.000344546">
        </testcase>
        <testcase classname="test/unit/slug.test.js" name="sanitizeRunSuffix &gt; keeps dots and dashes" time="0.000277556">
        </testcase>
        <testcase classname="test/unit/slug.test.js" name="sanitizeRunSuffix &gt; replaces spaces with dashes" time="0.000196865">
        </testcase>
        <testcase classname="test/unit/slug.test.js" name="sanitizeRunSuffix &gt; strips non-word characters" time="0.000197215">
        </testcase>
        <testcase classname="test/unit/slug.test.js" name="sanitizeRunSuffix &gt; collapses runs of separators into a single dash" time="0.000175924">
        </testcase>
        <testcase classname="test/unit/slug.test.js" name="sanitizeRunSuffix &gt; trims leading and trailing dashes" time="0.00017345">
        </testcase>
        <testcase classname="test/unit/slug.test.js" name="sanitizeRunSuffix &gt; caps length at the documented maximum" time="0.000353891">
        </testcase>
        <testcase classname="test/unit/slug.test.js" name="sanitizeRunSuffix &gt; uses &quot;run&quot; for inputs that sanitise to empty" time="0.000281161">
        </testcase>
        <testcase classname="test/unit/slug.test.js" name="sanitizeRunSuffix &gt; matches the legacy article-generator export byte-for-byte" time="0.000223695">
        </testcase>
        <testcase classname="test/unit/slug.test.js" name="sanitizeRunSuffix &gt; produces a filename-safe round-trip via buildArticleSlug" time="0.000764726">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/validate-analysis-completeness.test.js" timestamp="2026-04-28T00:15:08.402Z" hostname="runnervmeorf1" tests="33" failures="0" errors="0" skipped="0" time="1.659768462">
        <testcase classname="test/unit/validate-analysis-completeness.test.js" name="scripts/validate-analysis-completeness.js &gt; exits 2 with usage when no runDir given" time="0.049444072">
        </testcase>
        <testcase classname="test/unit/validate-analysis-completeness.test.js" name="scripts/validate-analysis-completeness.js &gt; returns RED when manifest.json is missing" time="0.036974364">
        </testcase>
        <testcase classname="test/unit/validate-analysis-completeness.test.js" name="scripts/validate-analysis-completeness.js &gt; flags missing artifacts listed in manifest" time="0.046214703">
        </testcase>
        <testcase classname="test/unit/validate-analysis-completeness.test.js" name="scripts/validate-analysis-completeness.js &gt; flags artifacts under intelligence/ that lack mermaid" time="0.049864141">
        </testcase>
        <testcase classname="test/unit/validate-analysis-completeness.test.js" name="scripts/validate-analysis-completeness.js &gt; flags placeholder markers" time="0.048382532">
        </testcase>
        <testcase classname="test/unit/validate-analysis-completeness.test.js" name="scripts/validate-analysis-completeness.js &gt; passes GREEN when every requirement is met" time="0.046474983">
        </testcase>
        <testcase classname="test/unit/validate-analysis-completeness.test.js" name="scripts/validate-analysis-completeness.js &gt; emits machine-readable JSON when --json passed" time="0.05049645">
        </testcase>
        <testcase classname="test/unit/validate-analysis-completeness.test.js" name="scripts/validate-analysis-completeness.js &gt; flags artifacts shorter than per-articleType floor" time="0.051058702">
        </testcase>
        <testcase classname="test/unit/validate-analysis-completeness.test.js" name="scripts/validate-analysis-completeness.js &gt; reports orphans (on-disk artifacts not listed in manifest) as warnings, not blockers" time="0.064821149">
        </testcase>
        <testcase classname="test/unit/validate-analysis-completeness.test.js" name="scripts/validate-analysis-completeness.js &gt; returns RED when economic-context cites IMF figures with knowledge-only provenance" time="0.049681749">
        </testcase>
        <testcase classname="test/unit/validate-analysis-completeness.test.js" name="scripts/validate-analysis-completeness.js &gt; returns RED when economic-context cites live IMF figures without an IMF cache file" time="0.052972491">
        </testcase>
        <testcase classname="test/unit/validate-analysis-completeness.test.js" name="scripts/validate-analysis-completeness.js &gt; passes GREEN when economic-context cites live IMF figures with cached probe JSON" time="0.049590843">
        </testcase>
        <testcase classname="test/unit/validate-analysis-completeness.test.js" name="scripts/validate-analysis-completeness.js &gt; returns RED when IMF Source field holds an unrecognised template placeholder" time="0.047302513">
        </testcase>
        <testcase classname="test/unit/validate-analysis-completeness.test.js" name="scripts/validate-analysis-completeness.js &gt; returns RED when only a non-WEO json sits in cache/imf (failed probe summary)" time="0.048802802">
        </testcase>
        <testcase classname="test/unit/validate-analysis-completeness.test.js" name="scripts/validate-analysis-completeness.js &gt; returns RED when WEO file exists but probe summary reports available:false" time="0.085715022">
        </testcase>
        <testcase classname="test/unit/validate-analysis-completeness.test.js" name="scripts/validate-analysis-completeness.js &gt; Pass 2 skipped heuristic &gt; warns when pass2 block is absent and an artifact sits exactly at its floor" time="0.048273108">
        </testcase>
        <testcase classname="test/unit/validate-analysis-completeness.test.js" name="scripts/validate-analysis-completeness.js &gt; Pass 2 skipped heuristic &gt; warns when pass2.rewriteCount === 0 and an artifact is exactly at its floor" time="0.051618161">
        </testcase>
        <testcase classname="test/unit/validate-analysis-completeness.test.js" name="scripts/validate-analysis-completeness.js &gt; Pass 2 skipped heuristic &gt; does NOT warn when pass2.rewriteCount === 0 but artifact is strictly above its floor" time="0.039730315">
        </testcase>
        <testcase classname="test/unit/validate-analysis-completeness.test.js" name="scripts/validate-analysis-completeness.js &gt; Pass 2 skipped heuristic &gt; does NOT warn when pass2.rewriteCount &gt; 0 even if artifact is at its floor" time="0.048039147">
        </testcase>
        <testcase classname="test/unit/validate-analysis-completeness.test.js" name="scripts/validate-analysis-completeness.js &gt; Pass 2 skipped heuristic &gt; does NOT warn when pass2 block is absent but artifact is strictly above its floor" time="0.04682678">
        </testcase>
        <testcase classname="test/unit/validate-analysis-completeness.test.js" name="scripts/validate-analysis-completeness.js &gt; Pass 2 skipped heuristic &gt; treats malformed pass2.rewriteCount (non-numeric) as invalid schema and still triggers heuristic at-floor" time="0.055672867">
        </testcase>
        <testcase classname="test/unit/validate-analysis-completeness.test.js" name="scripts/validate-analysis-completeness.js &gt; Pass 2 skipped heuristic &gt; treats missing rewriteCount field as invalid schema" time="0.048700037">
        </testcase>
        <testcase classname="test/unit/validate-analysis-completeness.test.js" name="scripts/validate-analysis-completeness.js &gt; Pass 2 skipped heuristic &gt; treats negative rewriteCount as invalid schema" time="0.047060029">
        </testcase>
        <testcase classname="test/unit/validate-analysis-completeness.test.js" name="scripts/validate-analysis-completeness.js &gt; Pass 2 skipped heuristic &gt; treats non-integer rewriteCount as invalid schema" time="0.042059836">
        </testcase>
        <testcase classname="test/unit/validate-analysis-completeness.test.js" name="scripts/validate-analysis-completeness.js &gt; Pass 2 skipped heuristic &gt; treats missing startedAt as invalid schema" time="0.052617218">
        </testcase>
        <testcase classname="test/unit/validate-analysis-completeness.test.js" name="scripts/validate-analysis-completeness.js &gt; Pass 2 skipped heuristic &gt; treats missing endedAt as invalid schema" time="0.041209421">
        </testcase>
        <testcase classname="test/unit/validate-analysis-completeness.test.js" name="scripts/validate-analysis-completeness.js &gt; passes GREEN for week-ahead when no forward-statements-open.json exists" time="0.039585868">
        </testcase>
        <testcase classname="test/unit/validate-analysis-completeness.test.js" name="scripts/validate-analysis-completeness.js &gt; passes GREEN for week-ahead when forward-statements-open.json is empty array" time="0.047122022">
        </testcase>
        <testcase classname="test/unit/validate-analysis-completeness.test.js" name="scripts/validate-analysis-completeness.js &gt; returns RED for week-ahead when open items exist but synthesis lacks the carried-forward section" time="0.054653911">
        </testcase>
        <testcase classname="test/unit/validate-analysis-completeness.test.js" name="scripts/validate-analysis-completeness.js &gt; returns RED for week-ahead when forward-statements-open.json is non-array JSON" time="0.05819069">
        </testcase>
        <testcase classname="test/unit/validate-analysis-completeness.test.js" name="scripts/validate-analysis-completeness.js &gt; reports forward-registry failures once and includes them in --json results" time="0.050564011">
        </testcase>
        <testcase classname="test/unit/validate-analysis-completeness.test.js" name="scripts/validate-analysis-completeness.js &gt; passes GREEN for week-ahead when open items exist and synthesis has the carried-forward section" time="0.050218192">
        </testcase>
        <testcase classname="test/unit/validate-analysis-completeness.test.js" name="scripts/validate-analysis-completeness.js &gt; does NOT apply forward-registry check to breaking article type" time="0.056253067">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/wb-mcp-client.test.js" timestamp="2026-04-28T00:15:08.406Z" hostname="runnervmeorf1" tests="18" failures="0" errors="0" skipped="0" time="0.023993229">
        <testcase classname="test/unit/wb-mcp-client.test.js" name="wb-mcp-client &gt; WorldBankMCPClient &gt; Constructor &gt; should initialize with default options" time="0.003926365">
        </testcase>
        <testcase classname="test/unit/wb-mcp-client.test.js" name="wb-mcp-client &gt; WorldBankMCPClient &gt; Constructor &gt; should accept custom options" time="0.000405508">
        </testcase>
        <testcase classname="test/unit/wb-mcp-client.test.js" name="wb-mcp-client &gt; WorldBankMCPClient &gt; getIndicatorForCountry &gt; should return fallback when not connected" time="0.000906448">
        </testcase>
        <testcase classname="test/unit/wb-mcp-client.test.js" name="wb-mcp-client &gt; WorldBankMCPClient &gt; getIndicatorForCountry &gt; should return fallback when countryId is empty" time="0.000430575">
        </testcase>
        <testcase classname="test/unit/wb-mcp-client.test.js" name="wb-mcp-client &gt; WorldBankMCPClient &gt; getIndicatorForCountry &gt; should return fallback when indicatorId is empty" time="0.000316585">
        </testcase>
        <testcase classname="test/unit/wb-mcp-client.test.js" name="wb-mcp-client &gt; WorldBankMCPClient &gt; getIndicatorForCountry &gt; should call callTool with correct tool name and arguments" time="0.003859584">
        </testcase>
        <testcase classname="test/unit/wb-mcp-client.test.js" name="wb-mcp-client &gt; WorldBankMCPClient &gt; getIndicatorForCountry &gt; should gracefully handle callTool errors" time="0.000849764">
        </testcase>
        <testcase classname="test/unit/wb-mcp-client.test.js" name="wb-mcp-client &gt; Singleton lifecycle &gt; closeWBMCPClient should be safe to call when no instance exists" time="0.000246169">
        </testcase>
        <testcase classname="test/unit/wb-mcp-client.test.js" name="wb-mcp-client &gt; Singleton lifecycle &gt; closeWBMCPClient should be safe to call multiple times" time="0.000345998">
        </testcase>
        <testcase classname="test/unit/wb-mcp-client.test.js" name="wb-mcp-client &gt; getIndicatorForCountry edge cases &gt; should handle non-Error exceptions in callTool" time="0.000415372">
        </testcase>
        <testcase classname="test/unit/wb-mcp-client.test.js" name="wb-mcp-client &gt; getIndicatorForCountry edge cases &gt; should warn when countryId is empty" time="0.000502934">
        </testcase>
        <testcase classname="test/unit/wb-mcp-client.test.js" name="wb-mcp-client &gt; getIndicatorForCountry edge cases &gt; should warn when indicatorId is empty" time="0.000427941">
        </testcase>
        <testcase classname="test/unit/wb-mcp-client.test.js" name="wb-mcp-client &gt; getIndicatorForCountry edge cases &gt; should return fallback content with correct structure" time="0.002431744">
        </testcase>
        <testcase classname="test/unit/wb-mcp-client.test.js" name="wb-mcp-client &gt; WorldBankMCPClient env var configuration &gt; should use WB_MCP_GATEWAY_URL env var when set" time="0.001113258">
        </testcase>
        <testcase classname="test/unit/wb-mcp-client.test.js" name="wb-mcp-client &gt; WorldBankMCPClient env var configuration &gt; should use WB_MCP_GATEWAY_API_KEY env var when set" time="0.000912437">
        </testcase>
        <testcase classname="test/unit/wb-mcp-client.test.js" name="wb-mcp-client &gt; WorldBankMCPClient env var configuration &gt; should not enable gateway mode without gateway URL" time="0.001053729">
        </testcase>
        <testcase classname="test/unit/wb-mcp-client.test.js" name="wb-mcp-client &gt; WorldBankMCPClient env var configuration &gt; should prefer explicit options over env vars" time="0.001279608">
        </testcase>
        <testcase classname="test/unit/wb-mcp-client.test.js" name="wb-mcp-client &gt; WorldBankMCPClient env var configuration &gt; should pass custom serverLabel" time="0.000839749">
        </testcase>
    </testsuite>
    <testsuite name="test/integration/mcp/ep-mcp.test.js" timestamp="2026-04-28T00:15:08.409Z" hostname="runnervmeorf1" tests="4" failures="0" errors="0" skipped="0" time="0.008089133">
        <testcase classname="test/integration/mcp/ep-mcp.test.js" name="EP MCP tool surface (drift guard) &gt; exports a non-empty canonical tool list" time="0.002637373">
        </testcase>
        <testcase classname="test/integration/mcp/ep-mcp.test.js" name="EP MCP tool surface (drift guard) &gt; EP_MCP_TOOLS equals the set of tools actually wrapped by ep-mcp-client.ts" time="0.001740559">
        </testcase>
        <testcase classname="test/integration/mcp/ep-mcp.test.js" name="EP MCP tool surface (drift guard) &gt; every EP_MCP_TOOLS entry is documented in .github/prompts/07-mcp-reference.md" time="0.001038507">
        </testcase>
        <testcase classname="test/integration/mcp/ep-mcp.test.js" name="EP MCP tool surface (drift guard) &gt; EP_MCP_TOOLS is sorted alphabetically (stable review diffs)" time="0.000398237">
        </testcase>
    </testsuite>
    <testsuite name="test/integration/mcp/imf-mcp.test.js" timestamp="2026-04-28T00:15:08.410Z" hostname="runnervmeorf1" tests="7" failures="0" errors="0" skipped="0" time="0.015982374">
        <testcase classname="test/integration/mcp/imf-mcp.test.js" name="integration — IMF REST client surface &gt; imf-list-databases hits /dataflow/IMF" time="0.006244208">
        </testcase>
        <testcase classname="test/integration/mcp/imf-mcp.test.js" name="integration — IMF REST client surface &gt; imf-search-databases reuses /dataflow/IMF and filters client-side" time="0.002187679">
        </testcase>
        <testcase classname="test/integration/mcp/imf-mcp.test.js" name="integration — IMF REST client surface &gt; imf-get-parameter-defs hits /datastructure/{id}" time="0.000997815">
        </testcase>
        <testcase classname="test/integration/mcp/imf-mcp.test.js" name="integration — IMF REST client surface &gt; imf-get-parameter-codes hits /datastructure/{id}?references=codelist" time="0.000631466">
        </testcase>
        <testcase classname="test/integration/mcp/imf-mcp.test.js" name="integration — IMF REST client surface &gt; imf-fetch-data builds the canonical SDMX key and query string" time="0.001309813">
        </testcase>
        <testcase classname="test/integration/mcp/imf-mcp.test.js" name="integration — IMF REST client surface &gt; non-2xx responses surface as the empty fallback (caller-friendly)" time="0.00110759">
        </testcase>
        <testcase classname="test/integration/mcp/imf-mcp.test.js" name="integration — IMF REST client surface &gt; covers all canonical IMF virtual tools exported by the client" time="0.000807921">
        </testcase>
    </testsuite>
    <testsuite name="test/integration/mcp/worldbank-mcp.test.js" timestamp="2026-04-28T00:15:08.411Z" hostname="runnervmeorf1" tests="10" failures="0" errors="0" skipped="0" time="0.016331346">
        <testcase classname="test/integration/mcp/worldbank-mcp.test.js" name="integration — World Bank MCP tool surface &gt; invokes search-indicators with a keyword argument" time="0.007120241">
        </testcase>
        <testcase classname="test/integration/mcp/worldbank-mcp.test.js" name="integration — World Bank MCP tool surface &gt; invokes get-countries with no arguments" time="0.00072774">
        </testcase>
        <testcase classname="test/integration/mcp/worldbank-mcp.test.js" name="integration — World Bank MCP tool surface &gt; invokes get-country-info with an ISO country code" time="0.000508222">
        </testcase>
        <testcase classname="test/integration/mcp/worldbank-mcp.test.js" name="integration — World Bank MCP tool surface &gt; invokes get-economic-data with countryCode + indicator + years" time="0.000429224">
        </testcase>
        <testcase classname="test/integration/mcp/worldbank-mcp.test.js" name="integration — World Bank MCP tool surface &gt; invokes get-social-data with a population-family indicator" time="0.000405477">
        </testcase>
        <testcase classname="test/integration/mcp/worldbank-mcp.test.js" name="integration — World Bank MCP tool surface &gt; invokes get-education-data with an education indicator" time="0.000424326">
        </testcase>
        <testcase classname="test/integration/mcp/worldbank-mcp.test.js" name="integration — World Bank MCP tool surface &gt; invokes get-health-data with a health indicator" time="0.000369204">
        </testcase>
        <testcase classname="test/integration/mcp/worldbank-mcp.test.js" name="integration — World Bank MCP tool surface &gt; rejects non-object tool arguments before touching the transport" time="0.001675672">
        </testcase>
        <testcase classname="test/integration/mcp/worldbank-mcp.test.js" name="integration — World Bank MCP tool surface &gt; surfaces transport errors from the underlying MCP connection" time="0.001325987">
        </testcase>
        <testcase classname="test/integration/mcp/worldbank-mcp.test.js" name="integration — World Bank MCP tool surface &gt; covers all canonical World Bank MCP tools exported by the client" time="0.000814031">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/constants/footer-labels.test.js" timestamp="2026-04-28T00:15:08.412Z" hostname="runnervmeorf1" tests="32" failures="0" errors="0" skipped="0" time="0.042742289">
        <testcase classname="test/unit/constants/footer-labels.test.js" name="constants/footer-labels &gt; FOOTER_HOME_LABELS &gt; should have entries for all 14 languages" time="0.003737351">
        </testcase>
        <testcase classname="test/unit/constants/footer-labels.test.js" name="constants/footer-labels &gt; FOOTER_HOME_LABELS &gt; should have non-empty string values for all 14 languages" time="0.002032596">
        </testcase>
        <testcase classname="test/unit/constants/footer-labels.test.js" name="constants/footer-labels &gt; FOOTER_SITEMAP_LABELS &gt; should have entries for all 14 languages" time="0.000410405">
        </testcase>
        <testcase classname="test/unit/constants/footer-labels.test.js" name="constants/footer-labels &gt; FOOTER_SITEMAP_LABELS &gt; should have non-empty string values for all 14 languages" time="0.000741501">
        </testcase>
        <testcase classname="test/unit/constants/footer-labels.test.js" name="constants/footer-labels &gt; FOOTER_RSS_LABELS &gt; should have entries for all 14 languages" time="0.000477696">
        </testcase>
        <testcase classname="test/unit/constants/footer-labels.test.js" name="constants/footer-labels &gt; FOOTER_RSS_LABELS &gt; should have non-empty string values for all 14 languages" time="0.000931476">
        </testcase>
        <testcase classname="test/unit/constants/footer-labels.test.js" name="constants/footer-labels &gt; FOOTER_GITHUB_REPO_LABELS &gt; should have entries for all 14 languages" time="0.000461362">
        </testcase>
        <testcase classname="test/unit/constants/footer-labels.test.js" name="constants/footer-labels &gt; FOOTER_GITHUB_REPO_LABELS &gt; should have non-empty string values for all 14 languages" time="0.002013057">
        </testcase>
        <testcase classname="test/unit/constants/footer-labels.test.js" name="constants/footer-labels &gt; FOOTER_LICENSE_LABELS &gt; should have entries for all 14 languages" time="0.000429754">
        </testcase>
        <testcase classname="test/unit/constants/footer-labels.test.js" name="constants/footer-labels &gt; FOOTER_LICENSE_LABELS &gt; should have non-empty string values for all 14 languages" time="0.000883304">
        </testcase>
        <testcase classname="test/unit/constants/footer-labels.test.js" name="constants/footer-labels &gt; FOOTER_EUROPARL_LABELS &gt; should have entries for all 14 languages" time="0.000490245">
        </testcase>
        <testcase classname="test/unit/constants/footer-labels.test.js" name="constants/footer-labels &gt; FOOTER_EUROPARL_LABELS &gt; should have non-empty string values for all 14 languages" time="0.000668732">
        </testcase>
        <testcase classname="test/unit/constants/footer-labels.test.js" name="constants/footer-labels &gt; FOOTER_LINKEDIN_LABELS &gt; should have entries for all 14 languages" time="0.000335303">
        </testcase>
        <testcase classname="test/unit/constants/footer-labels.test.js" name="constants/footer-labels &gt; FOOTER_LINKEDIN_LABELS &gt; should have non-empty string values for all 14 languages" time="0.000483234">
        </testcase>
        <testcase classname="test/unit/constants/footer-labels.test.js" name="constants/footer-labels &gt; FOOTER_SECURITY_POLICY_LABELS &gt; should have entries for all 14 languages" time="0.000390756">
        </testcase>
        <testcase classname="test/unit/constants/footer-labels.test.js" name="constants/footer-labels &gt; FOOTER_SECURITY_POLICY_LABELS &gt; should have non-empty string values for all 14 languages" time="0.000444146">
        </testcase>
        <testcase classname="test/unit/constants/footer-labels.test.js" name="constants/footer-labels &gt; FOOTER_CONTACT_LABELS &gt; should have entries for all 14 languages" time="0.00027358">
        </testcase>
        <testcase classname="test/unit/constants/footer-labels.test.js" name="constants/footer-labels &gt; FOOTER_CONTACT_LABELS &gt; should have non-empty string values for all 14 languages" time="0.000645557">
        </testcase>
        <testcase classname="test/unit/constants/footer-labels.test.js" name="constants/footer-labels &gt; FOOTER_DISCLAIMER_LABELS &gt; should have entries for all 14 languages" time="0.000339529">
        </testcase>
        <testcase classname="test/unit/constants/footer-labels.test.js" name="constants/footer-labels &gt; FOOTER_DISCLAIMER_LABELS &gt; should have non-empty string values for all 14 languages" time="0.000829253">
        </testcase>
        <testcase classname="test/unit/constants/footer-labels.test.js" name="constants/footer-labels &gt; FOOTER_REPORT_ISSUES_LABELS &gt; should have entries for all 14 languages" time="0.000501952">
        </testcase>
        <testcase classname="test/unit/constants/footer-labels.test.js" name="constants/footer-labels &gt; FOOTER_REPORT_ISSUES_LABELS &gt; should have non-empty string values for all 14 languages" time="0.000850735">
        </testcase>
        <testcase classname="test/unit/constants/footer-labels.test.js" name="constants/footer-labels &gt; FOOTER_ARTICLES_AVAILABLE_LABELS &gt; should have entries for all 14 languages" time="0.000456995">
        </testcase>
        <testcase classname="test/unit/constants/footer-labels.test.js" name="constants/footer-labels &gt; FOOTER_ARTICLES_AVAILABLE_LABELS &gt; should have non-empty string values for all 14 languages" time="0.000739889">
        </testcase>
        <testcase classname="test/unit/constants/footer-labels.test.js" name="constants/footer-labels &gt; FOOTER_ARTICLES_AVAILABLE_LABELS &gt; should contain {count} placeholder in all languages" time="0.000667049">
        </testcase>
        <testcase classname="test/unit/constants/footer-labels.test.js" name="constants/footer-labels &gt; buildSiteFooter integration &gt; should export buildSiteFooter from section-builders" time="0.017102141">
        </testcase>
        <testcase classname="test/unit/constants/footer-labels.test.js" name="constants/footer-labels &gt; buildSiteFooter integration &gt; should render localized footer heading for German" time="0.000691516">
        </testcase>
        <testcase classname="test/unit/constants/footer-labels.test.js" name="constants/footer-labels &gt; buildSiteFooter integration &gt; should render localized footer heading for Arabic" time="0.000273931">
        </testcase>
        <testcase classname="test/unit/constants/footer-labels.test.js" name="constants/footer-labels &gt; buildSiteFooter integration &gt; should include articles count line when articleCount is provided" time="0.000215824">
        </testcase>
        <testcase classname="test/unit/constants/footer-labels.test.js" name="constants/footer-labels &gt; buildSiteFooter integration &gt; should omit articles count line when articleCount is not provided" time="0.000377045">
        </testcase>
        <testcase classname="test/unit/constants/footer-labels.test.js" name="constants/footer-labels &gt; buildSiteFooter integration &gt; should use correct pathPrefix for article pages" time="0.000268342">
        </testcase>
        <testcase classname="test/unit/constants/footer-labels.test.js" name="constants/footer-labels &gt; buildSiteFooter integration &gt; should use correct pathPrefix for index pages" time="0.000218458">
        </testcase>
    </testsuite>
</testsuites>
