<?xml version="1.0" encoding="UTF-8" ?>
<testsuites name="vitest tests" tests="2864" failures="0" errors="0" time="4.038220158">
    <testsuite name="test/integration/cross-article-intelligence.test.js" timestamp="2026-04-14T20:47:06.273Z" hostname="runnervm35a4x" tests="6" failures="0" errors="0" skipped="0" time="0.044157169">
        <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.005230571">
        </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.002445981">
        </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.003825016">
        </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.025401082">
        </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.000914775">
        </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.003087022">
        </testcase>
    </testsuite>
    <testsuite name="test/integration/mcp-integration.test.js" timestamp="2026-04-14T20:47:06.328Z" hostname="runnervm35a4x" tests="21" failures="0" errors="0" skipped="0" time="0.341598788">
        <testcase classname="test/integration/mcp-integration.test.js" name="MCP Integration &gt; MCP Client Connection &gt; should connect to mock MCP server" time="0.003065455">
        </testcase>
        <testcase classname="test/integration/mcp-integration.test.js" name="MCP Integration &gt; MCP Client Connection &gt; should handle connection failure gracefully" time="0.001618878">
        </testcase>
        <testcase classname="test/integration/mcp-integration.test.js" name="MCP Integration &gt; MCP Client Connection &gt; should disconnect cleanly" time="0.000476549">
        </testcase>
        <testcase classname="test/integration/mcp-integration.test.js" name="MCP Integration &gt; Data Retrieval from MCP Server &gt; should fetch plenary sessions" time="0.000411941">
        </testcase>
        <testcase classname="test/integration/mcp-integration.test.js" name="MCP Integration &gt; Data Retrieval from MCP Server &gt; should fetch parliamentary questions" time="0.000416007">
        </testcase>
        <testcase classname="test/integration/mcp-integration.test.js" name="MCP Integration &gt; Data Retrieval from MCP Server &gt; should search documents" time="0.000272036">
        </testcase>
        <testcase classname="test/integration/mcp-integration.test.js" name="MCP Integration &gt; Data Retrieval from MCP Server &gt; should fetch MEPs" time="0.000420355">
        </testcase>
        <testcase classname="test/integration/mcp-integration.test.js" name="MCP Integration &gt; Article Generation with MCP Data &gt; should generate article from plenary session data" time="0.01693693">
        </testcase>
        <testcase classname="test/integration/mcp-integration.test.js" name="MCP Integration &gt; Article Generation with MCP Data &gt; should generate article from parliamentary questions" time="0.001036392">
        </testcase>
        <testcase classname="test/integration/mcp-integration.test.js" name="MCP Integration &gt; Article Generation with MCP Data &gt; should generate article from legislative documents" time="0.000895013">
        </testcase>
        <testcase classname="test/integration/mcp-integration.test.js" name="MCP Integration &gt; Fallback Mode &gt; should generate placeholder article when MCP unavailable" time="0.000650195">
        </testcase>
        <testcase classname="test/integration/mcp-integration.test.js" name="MCP Integration &gt; Fallback Mode &gt; should handle partial MCP failure gracefully" time="0.000871324">
        </testcase>
        <testcase classname="test/integration/mcp-integration.test.js" name="MCP Integration &gt; Data Transformation &gt; should transform MCP data for multi-language articles" time="0.003486312">
        </testcase>
        <testcase classname="test/integration/mcp-integration.test.js" name="MCP Integration &gt; Data Transformation &gt; should handle empty MCP responses" time="0.001125368">
        </testcase>
        <testcase classname="test/integration/mcp-integration.test.js" name="MCP Integration &gt; Request Tracking &gt; should track all MCP requests" time="0.000436015">
        </testcase>
        <testcase classname="test/integration/mcp-integration.test.js" name="MCP Integration &gt; Request Tracking &gt; should clear request history" time="0.000261762">
        </testcase>
        <testcase classname="test/integration/mcp-integration.test.js" name="MCP Integration &gt; Error Handling in Integration &gt; should handle malformed MCP responses" time="0.000650607">
        </testcase>
        <testcase classname="test/integration/mcp-integration.test.js" name="MCP Integration &gt; Error Handling in Integration &gt; should handle network timeout" time="0.100977224">
        </testcase>
        <testcase classname="test/integration/mcp-integration.test.js" name="MCP Integration &gt; Error Handling in Integration &gt; should retry failed requests" time="0.20244754">
        </testcase>
        <testcase classname="test/integration/mcp-integration.test.js" name="MCP Integration &gt; Performance &gt; should retrieve data efficiently" time="0.000337285">
        </testcase>
        <testcase classname="test/integration/mcp-integration.test.js" name="MCP Integration &gt; Performance &gt; should handle concurrent requests" time="0.001425647">
        </testcase>
    </testsuite>
    <testsuite name="test/integration/multi-language.test.js" timestamp="2026-04-14T20:47:06.332Z" hostname="runnervm35a4x" tests="18" failures="0" errors="0" skipped="0" time="0.148906269">
        <testcase classname="test/integration/multi-language.test.js" name="Multi-Language Support Integration &gt; Article Generation for All Languages &gt; should generate valid articles for all 14 languages" time="0.049733879">
        </testcase>
        <testcase classname="test/integration/multi-language.test.js" name="Multi-Language Support Integration &gt; Article Generation for All Languages &gt; should use correct text direction for all languages" time="0.008668619">
        </testcase>
        <testcase classname="test/integration/multi-language.test.js" name="Multi-Language Support Integration &gt; Article Generation for All Languages &gt; should save articles in correct filename format" time="0.017745723">
        </testcase>
        <testcase classname="test/integration/multi-language.test.js" name="Multi-Language Support Integration &gt; Language-Specific Labels &gt; should use correct article type labels for each language" time="0.008531249">
        </testcase>
        <testcase classname="test/integration/multi-language.test.js" name="Multi-Language Support Integration &gt; Language-Specific Labels &gt; should use correct read time labels for each language" time="0.003248052">
        </testcase>
        <testcase classname="test/integration/multi-language.test.js" name="Multi-Language Support Integration &gt; Language-Specific Labels &gt; should use correct back navigation labels" time="0.002753622">
        </testcase>
        <testcase classname="test/integration/multi-language.test.js" name="Multi-Language Support Integration &gt; Date Formatting &gt; should format dates according to language locale" time="0.006876503">
        </testcase>
        <testcase classname="test/integration/multi-language.test.js" name="Multi-Language Support Integration &gt; Date Formatting &gt; should use correct month names for each language" time="0.003876842">
        </testcase>
        <testcase classname="test/integration/multi-language.test.js" name="Multi-Language Support Integration &gt; Index Generation for All Languages &gt; should generate index pages for all languages" time="0.002673224">
        </testcase>
        <testcase classname="test/integration/multi-language.test.js" name="Multi-Language Support Integration &gt; Index Generation for All Languages &gt; should use language-specific titles in indexes" time="0.000560506">
        </testcase>
        <testcase classname="test/integration/multi-language.test.js" name="Multi-Language Support Integration &gt; Sitemap Generation for All Languages &gt; should include all language indexes in sitemap" time="0.000902057">
        </testcase>
        <testcase classname="test/integration/multi-language.test.js" name="Multi-Language Support Integration &gt; Sitemap Generation for All Languages &gt; should include articles for all languages in sitemap" time="0.001381921">
        </testcase>
        <testcase classname="test/integration/multi-language.test.js" name="Multi-Language Support Integration &gt; Language Consistency &gt; should maintain language consistency across article" time="0.011883719">
        </testcase>
        <testcase classname="test/integration/multi-language.test.js" name="Multi-Language Support Integration &gt; Language Consistency &gt; should include language in back navigation link" time="0.006706649">
        </testcase>
        <testcase classname="test/integration/multi-language.test.js" name="Multi-Language Support Integration &gt; Character Encoding &gt; should handle special characters in all languages" time="0.002584022">
        </testcase>
        <testcase classname="test/integration/multi-language.test.js" name="Multi-Language Support Integration &gt; SEO for Multi-Language &gt; should set correct locale in Open Graph for each language" time="0.007040733">
        </testcase>
        <testcase classname="test/integration/multi-language.test.js" name="Multi-Language Support Integration &gt; SEO for Multi-Language &gt; should include language in structured data" time="0.006560045">
        </testcase>
        <testcase classname="test/integration/multi-language.test.js" name="Multi-Language Support Integration &gt; Performance Across Languages &gt; should generate articles efficiently for all languages" time="0.004226206">
        </testcase>
    </testsuite>
    <testsuite name="test/integration/news-generation.test.js" timestamp="2026-04-14T20:47:06.334Z" hostname="runnervm35a4x" tests="13" failures="0" errors="0" skipped="0" time="0.063992342">
        <testcase classname="test/integration/news-generation.test.js" name="News Generation Integration &gt; Full Article Generation Flow &gt; should generate complete article from start to finish" time="0.02715829">
        </testcase>
        <testcase classname="test/integration/news-generation.test.js" name="News Generation Integration &gt; Full Article Generation Flow &gt; should generate and save article to filesystem" time="0.001849217">
        </testcase>
        <testcase classname="test/integration/news-generation.test.js" name="News Generation Integration &gt; Full Article Generation Flow &gt; should generate articles for multiple languages" time="0.006218761">
        </testcase>
        <testcase classname="test/integration/news-generation.test.js" name="News Generation Integration &gt; Article Metadata Generation &gt; should generate metadata file alongside article" time="0.001528592">
        </testcase>
        <testcase classname="test/integration/news-generation.test.js" name="News Generation Integration &gt; Article Content Validation &gt; should generate article with all required sections" time="0.000985727">
        </testcase>
        <testcase classname="test/integration/news-generation.test.js" name="News Generation Integration &gt; Article Content Validation &gt; should properly format dates across all sections" time="0.000790674">
        </testcase>
        <testcase classname="test/integration/news-generation.test.js" name="News Generation Integration &gt; Placeholder Content Mode &gt; should generate article with placeholder when MCP unavailable" time="0.003659099">
        </testcase>
        <testcase classname="test/integration/news-generation.test.js" name="News Generation Integration &gt; Error Recovery &gt; should handle missing optional fields gracefully" time="0.00122506">
        </testcase>
        <testcase classname="test/integration/news-generation.test.js" name="News Generation Integration &gt; Error Recovery &gt; should continue generation if one article fails" time="0.002349725">
        </testcase>
        <testcase classname="test/integration/news-generation.test.js" name="News Generation Integration &gt; Performance &gt; should generate article in reasonable time" time="0.000766788">
        </testcase>
        <testcase classname="test/integration/news-generation.test.js" name="News Generation Integration &gt; Performance &gt; should handle batch generation efficiently" time="0.012229902">
        </testcase>
        <testcase classname="test/integration/news-generation.test.js" name="News Generation Integration &gt; File System Integration &gt; should create proper directory structure" time="0.000847039">
        </testcase>
        <testcase classname="test/integration/news-generation.test.js" name="News Generation Integration &gt; File System Integration &gt; should handle existing files correctly" time="0.00216391">
        </testcase>
    </testsuite>
    <testsuite name="test/integration/week-ahead-data.test.js" timestamp="2026-04-14T20:47:06.337Z" hostname="runnervm35a4x" tests="4" failures="0" errors="0" skipped="0" time="0.01228313">
        <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.005477526">
        </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.003182828">
            <system-err>
⚠️ get_committee_info failed [UNKNOWN]: Committee API unavailable
⚠️ 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.000626361">
        </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.00113163">
            <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/analysis-context.test.js" timestamp="2026-04-14T20:47:06.338Z" hostname="runnervm35a4x" tests="71" failures="0" errors="0" skipped="0" time="0.087533035">
        <testcase classname="test/unit/analysis-context.test.js" name="loadAnalysisContext &gt; returns null when the date directory does not exist" time="0.004203477">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="loadAnalysisContext &gt; returns null for path-traversal date values" time="0.000854823">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="loadAnalysisContext &gt; returns null for invalid slug values" time="0.000550382">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="loadAnalysisContext &gt; uses EP_ANALYSIS_DIR env var for base dir when default baseDir is used" time="0.002088344">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="loadAnalysisContext &gt; uses EP_ANALYSIS_SLUG env var to override per-strategy slug" time="0.001718911">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="loadAnalysisContext &gt; prefers explicit non-default baseDir over EP_ANALYSIS_DIR env var" time="0.001034145">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="loadAnalysisContext &gt; returns null when the slug directory does not exist" time="0.000574182">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="loadAnalysisContext &gt; returns null when directory exists but has no manifest or files" time="0.001285228">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="loadAnalysisContext &gt; loads manifest.json from the analysis directory" time="0.001596028">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="loadAnalysisContext &gt; loads analysis markdown files from subdirectories" time="0.001842612">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="loadAnalysisContext &gt; finds suffixed directories (e.g. breaking-2)" time="0.001414578">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="loadAnalysisContext &gt; picks the highest-suffixed directory when multiple exist" time="0.001414613">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="loadAnalysisContext &gt; returns context even with only files and no manifest" time="0.001122751">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="loadAnalysisContext &gt; ignores non-.md files in subdirectories" time="0.001078458">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="loadAnalysisContext &gt; handles corrupted manifest.json gracefully" time="0.001219379">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="loadAnalysisContext &gt; keys files by frontmatter method when filename differs (coalition-dynamics.md → coalition-analysis)" time="0.001126351">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="loadAnalysisContext &gt; keys files by frontmatter method for stakeholder-impact.md → stakeholder-analysis" time="0.001176363">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="loadAnalysisContext &gt; falls back to filename key when frontmatter has no method field" time="0.000944784">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="extractFrontmatterMethod &gt; extracts method from valid frontmatter" time="0.000423384">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="extractFrontmatterMethod &gt; returns null when no frontmatter present" time="0.000409833">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="extractFrontmatterMethod &gt; returns null when frontmatter has no method field" time="0.000379529">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="extractFrontmatterMethod &gt; returns null for empty content" time="0.000348849">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="extractFrontmatterMethod &gt; handles method with extra whitespace" time="0.000386199">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="extractFrontmatterMethod &gt; returns null for unclosed frontmatter" time="0.000390061">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="extractAnalysisSummary &gt; extracts first paragraph from markdown content" time="0.001107774">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="extractAnalysisSummary &gt; strips YAML frontmatter" time="0.000584845">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="extractAnalysisSummary &gt; truncates long summaries to maxLength" time="0.000694206">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="extractAnalysisSummary &gt; returns empty string for empty content" time="0.000359027">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="extractAnalysisSummary &gt; returns empty string for content with only headings" time="0.000360867">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="extractAnalysisSummary &gt; handles content without frontmatter" time="0.000450179">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="extractAnalysisSummary &gt; skips mermaid code blocks" time="0.000475233">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="extractAnalysisSummary &gt; skips table rows" time="0.000448877">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="extractAnalysisSummary &gt; skips table rows without trailing pipe" time="0.000424363">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="extractAnalysisSummary &gt; returns empty for scaffold content with TO BE FILLED markers" time="0.000562045">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="extractAnalysisSummary &gt; strips bold markdown formatting" time="0.00043755">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="isScaffoldContent &gt; detects TO BE FILLED BY AI AGENT marker" time="0.000393703">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="isScaffoldContent &gt; detects AI_ANALYSIS_REQUIRED marker" time="0.000804837">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="isScaffoldContent &gt; detects REQUIRED marker" time="0.000346304">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="isScaffoldContent &gt; detects Instructions for AI Agent prompt" time="0.000354304">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="isScaffoldContent &gt; detects quality gate markers" time="0.000636587">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="isScaffoldContent &gt; returns false for substantive content" time="0.000357988">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="isScaffoldContent &gt; returns false for empty content" time="0.000359581">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="hasSubstantiveAIContent &gt; returns true for content with substantive prose" time="0.000414045">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="hasSubstantiveAIContent &gt; returns false for scaffold content" time="0.000253988">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="hasSubstantiveAIContent &gt; returns false for content with only headings and tables" time="0.000355132">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="hasSubstantiveAIContent &gt; counts words excluding headings, tables, and blockquotes" time="0.000265935">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="extractAnalysisParagraphs &gt; extracts multiple paragraphs from analysis content" time="0.000411452">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="extractAnalysisParagraphs &gt; returns empty array for scaffold content" time="0.000835763">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="extractAnalysisParagraphs &gt; respects maxParagraphs limit" time="0.000308029">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="extractAnalysisParagraphs &gt; skips mermaid blocks and tables" time="0.000359296">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="extractAnalysisParagraphs &gt; truncates overlong first paragraph instead of returning empty" time="0.000294822">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="buildAnalysisInsightsSection &gt; returns empty string for null context" time="0.000372365">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="buildAnalysisInsightsSection &gt; returns empty string for undefined context" time="0.000269588">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="buildAnalysisInsightsSection &gt; returns empty string when no relevant methods have files" time="0.000308164">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="buildAnalysisInsightsSection &gt; builds HTML section when relevant methods have files" time="0.000673885">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="buildAnalysisInsightsSection &gt; only includes methods that have loaded files" time="0.000430916">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="buildAnalysisInsightsSection &gt; filters out scaffold/placeholder content from insights" time="0.000403914">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="buildAnalysisInsightsSection &gt; omits confidence badge when overallConfidence is null" time="0.000475157">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="buildAnalysisInsightsSection &gt; uses localized heading for non-English languages" time="0.00048221">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="Strategy analysis context integration &gt; BreakingNewsStrategy: buildContent includes analysis insights when context is present" time="0.007173336">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="Strategy analysis context integration &gt; BreakingNewsStrategy: buildContent works without analysis context" time="0.001414598">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="Strategy analysis context integration &gt; BreakingNewsStrategy: enriches deep-analysis section with AI content from analysisContext" time="0.001248199">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="Strategy analysis context integration &gt; BreakingNewsStrategy: scaffold analysis files do not override deep-analysis fields" time="0.000978072">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="Strategy analysis context integration &gt; WeekAheadStrategy: buildContent includes insights when context is present" time="0.002769699">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="Strategy analysis context integration &gt; CommitteeReportsStrategy: buildContent includes insights when context is present" time="0.002363538">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="Strategy analysis context integration &gt; MotionsStrategy: buildContent includes insights when context is present" time="0.004019866">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="Strategy analysis context integration &gt; PropositionsStrategy: buildContent includes insights when context is present" time="0.002635872">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="Strategy analysis context integration &gt; WeeklyReviewStrategy: buildContent includes insights when context is present" time="0.001423304">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="Strategy analysis context integration &gt; MonthlyReviewStrategy: buildContent includes insights when context is present" time="0.001358323">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="Strategy analysis context integration &gt; MonthAheadStrategy: buildContent includes insights when context is present" time="0.001130343">
        </testcase>
        <testcase classname="test/unit/analysis-context.test.js" name="Strategy analysis context integration &gt; all strategies degrade gracefully with null analysisContext" time="0.013437052">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/analysis-stage.test.js" timestamp="2026-04-14T20:47:06.347Z" hostname="runnervm35a4x" tests="23" failures="0" errors="0" skipped="0" time="0.030284324">
        <testcase classname="test/unit/analysis-stage.test.js" name="hasSubstantiveData &gt; should return false for empty data" time="0.004239703">
        </testcase>
        <testcase classname="test/unit/analysis-stage.test.js" name="hasSubstantiveData &gt; should return false when all arrays are empty" time="0.00074395">
        </testcase>
        <testcase classname="test/unit/analysis-stage.test.js" name="hasSubstantiveData &gt; should return true when events has data" time="0.000746661">
        </testcase>
        <testcase classname="test/unit/analysis-stage.test.js" name="hasSubstantiveData &gt; should return true when procedures has data" time="0.000431033">
        </testcase>
        <testcase classname="test/unit/analysis-stage.test.js" name="hasSubstantiveData &gt; should return true when documents has data" time="0.000566114">
        </testcase>
        <testcase classname="test/unit/analysis-stage.test.js" name="hasSubstantiveData &gt; should return false for non-array values" time="0.00042219">
        </testcase>
        <testcase classname="test/unit/analysis-stage.test.js" name="runAnalysisStage &gt; should return an AnalysisContext with expected shape" time="0.004616592">
        </testcase>
        <testcase classname="test/unit/analysis-stage.test.js" name="runAnalysisStage &gt; should discover existing analysis files on disk" time="0.001853532">
        </testcase>
        <testcase classname="test/unit/analysis-stage.test.js" name="runAnalysisStage &gt; should write manifest.json when none exists" time="0.002056837">
        </testcase>
        <testcase classname="test/unit/analysis-stage.test.js" name="runAnalysisStage &gt; should not overwrite existing manifest.json" time="0.001221214">
        </testcase>
        <testcase classname="test/unit/analysis-stage.test.js" name="runAnalysisStage &gt; should throw on invalid date format" time="0.002491267">
        </testcase>
        <testcase classname="test/unit/analysis-stage.test.js" name="runAnalysisStage &gt; should throw when requireData is true and no data" time="0.000655035">
        </testcase>
        <testcase classname="test/unit/analysis-stage.test.js" name="runAnalysisStage &gt; should succeed without data when requireData is false" time="0.000687807">
        </testcase>
        <testcase classname="test/unit/analysis-stage.test.js" name="runAnalysisStage &gt; should use articleTypeSlug for scoped output directory" time="0.000869589">
        </testcase>
        <testcase classname="test/unit/analysis-stage.test.js" name="deriveArticleTypeSlug &gt; should return &quot;default&quot; for empty array" time="0.000608492">
        </testcase>
        <testcase classname="test/unit/analysis-stage.test.js" name="deriveArticleTypeSlug &gt; should return single type as slug" time="0.000468297">
        </testcase>
        <testcase classname="test/unit/analysis-stage.test.js" name="deriveArticleTypeSlug &gt; should sort multiple types" time="0.000379156">
        </testcase>
        <testcase classname="test/unit/analysis-stage.test.js" name="deriveArticleTypeSlug &gt; should sanitize special characters" time="0.000320269">
        </testcase>
        <testcase classname="test/unit/analysis-stage.test.js" name="deriveArticleTypeSlug &gt; should lowercase and trim" time="0.000319872">
        </testcase>
        <testcase classname="test/unit/analysis-stage.test.js" name="ALL_ANALYSIS_METHODS &gt; should contain at least 15 methods" time="0.000391668">
        </testcase>
        <testcase classname="test/unit/analysis-stage.test.js" name="ALL_ANALYSIS_METHODS &gt; should include key methods" time="0.000907023">
        </testcase>
        <testcase classname="test/unit/analysis-stage.test.js" name="VALID_ANALYSIS_METHODS &gt; should include document-analysis" time="0.000691536">
        </testcase>
        <testcase classname="test/unit/analysis-stage.test.js" name="VALID_ANALYSIS_METHODS &gt; should be a superset of ALL_ANALYSIS_METHODS" time="0.001450483">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/article-quality-scorer.test.js" timestamp="2026-04-14T20:47:06.351Z" hostname="runnervm35a4x" tests="95" failures="0" errors="0" skipped="0" time="0.052503447">
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessAnalysisDepth &gt; returns all false and score=0 for empty HTML" time="0.003740168">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessAnalysisDepth &gt; detects political context keywords" time="0.001068535">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessAnalysisDepth &gt; detects coalition dynamics keywords" time="0.000349149">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessAnalysisDepth &gt; detects coalition dynamics with HTML-encoded entities (S&amp;amp;D)" time="0.000238741">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessAnalysisDepth &gt; detects historical context keywords" time="0.000279911">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessAnalysisDepth &gt; detects evidence-based keywords" time="0.000150883">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessAnalysisDepth &gt; detects scenario planning keywords" time="0.000131597">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessAnalysisDepth &gt; detects confidence level keywords" time="0.000235586">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessAnalysisDepth &gt; returns score=100 when all dimensions are present" time="0.000248059">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessAnalysisDepth &gt; score is proportional to number of true dimensions" time="0.000381354">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessAnalysisDepth &gt; score is clamped between 0 and 100" time="0.000396587">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessStakeholderCoverage &gt; returns empty present list and full missing list for empty HTML" time="0.003003426">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessStakeholderCoverage &gt; detects MEPs/Parliament stakeholder" time="0.002101027">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessStakeholderCoverage &gt; detects Commission stakeholder" time="0.000427156">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessStakeholderCoverage &gt; detects Council stakeholder" time="0.000279284">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessStakeholderCoverage &gt; detects civil society/NGOs stakeholder" time="0.000318933">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessStakeholderCoverage &gt; detects industry/business stakeholder" time="0.000256073">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessStakeholderCoverage &gt; detects citizens stakeholder" time="0.000249429">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessStakeholderCoverage &gt; detects media stakeholder" time="0.000264617">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessStakeholderCoverage &gt; applies reasoning quality penalty for generic phrases" time="0.000209415">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessStakeholderCoverage &gt; balanceScore is 100 when all stakeholders covered" time="0.000281756">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessStakeholderCoverage &gt; scores are clamped between 0 and 100" time="0.000294387">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessVisualizationQuality &gt; returns all false/zero for empty HTML" time="0.000865596">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessVisualizationQuality &gt; detects SWOT by class" time="0.000321969">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessVisualizationQuality &gt; detects SWOT with multi-class attributes (e.g. swot-multidimensional)" time="0.000173683">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessVisualizationQuality &gt; detects SWOT by id" time="0.000149236">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessVisualizationQuality &gt; counts SWOT dimensions" time="0.000170604">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessVisualizationQuality &gt; detects dashboard by class" time="0.000199443">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessVisualizationQuality &gt; detects dashboard trends via arrow symbols" time="0.000322782">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessVisualizationQuality &gt; detects dashboard trends via class" time="0.000161459">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessVisualizationQuality &gt; does not treat hyphenated dashboard classes as dashboardPresent" time="0.000280787">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessVisualizationQuality &gt; detects mindmap by class" time="0.000381118">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessVisualizationQuality &gt; counts mindmap branches via mindmap-branch classes" time="0.000222262">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessVisualizationQuality &gt; counts mindmap branches from data-branch-count attribute (preferred)" time="0.000175249">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessVisualizationQuality &gt; counts mindmap &lt;li&gt; from mindmap-branches list (fallback when no data-branch-count)" time="0.000578709">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessVisualizationQuality &gt; counts multiple direct &lt;li&gt; branches but not nested subnodes" time="0.000257525">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessVisualizationQuality &gt; counts only analysis-content sections, not generic or non-analysis sections" time="0.005126166">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessVisualizationQuality &gt; detects deep analysis by class" time="0.000253067">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessVisualizationQuality &gt; detects deep analysis by id pattern" time="0.000150359">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessVisualizationQuality &gt; score is &gt; 0 for article with all visual elements" time="0.000335532">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessVisualizationQuality &gt; counts perspective-evidence &lt;li&gt; items inside deep-analysis as deepAnalysisEvidence" time="0.000165534">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessVisualizationQuality &gt; counts evidence across multiple deep-analysis sections" time="0.000139692">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessVisualizationQuality &gt; deduplicates deep-analysis section matching both class and id patterns" time="0.000113643">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessVisualizationQuality &gt; counts &lt;li&gt; items in perspective-evidence &lt;ul&gt; without requiring div/section wrapper" time="0.000933909">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessVisualizationQuality &gt; counts swot-ref-evidence markers in SWOT sections" time="0.000369616">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="assessVisualizationQuality &gt; score is clamped between 0 and 100" time="0.000185792">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="calculateOverallScore &gt; returns 0 for all-zero inputs" time="0.000240162">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="calculateOverallScore &gt; returns 100 for all-maximum inputs" time="0.000653127">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="calculateOverallScore &gt; is clamped to 0 for negative word count" time="0.000156997">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="calculateOverallScore &gt; word count of 1500 contributes maximum word-count component" time="0.000166631">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="calculateOverallScore &gt; evidence count of 10 contributes maximum evidence component" time="0.000156531">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="calculateOverallScore &gt; returns a number between 0 and 100" time="0.000177452">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="scoreArticleQuality &gt; returns a report with all required fields for empty HTML" time="0.001765595">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="scoreArticleQuality &gt; scores empty HTML as grade F with passesQualityGate=false" time="0.000444444">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="scoreArticleQuality &gt; produces recommendations for empty HTML" time="0.000524562">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="scoreArticleQuality &gt; scores minimal HTML with short text as low quality" time="0.000385725">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="scoreArticleQuality &gt; scores rich HTML with all quality signals as C or higher" time="0.001648125">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="scoreArticleQuality &gt; date field is a valid YYYY-MM-DD string" time="0.000523573">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="scoreArticleQuality &gt; derives date from articleId when it contains a date prefix" time="0.000377983">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="scoreArticleQuality &gt; falls back to current date when articleId has no date prefix" time="0.002620986">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="scoreArticleQuality &gt; articleId, lang, type are preserved from inputs" time="0.000429679">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="scoreArticleQuality &gt; non-English articles are not penalised by English-only keyword lists" time="0.001192633">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="scoreArticleQuality &gt; non-English articles receive baseline floors on keyword-dependent scores" time="0.000259847">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="grade boundaries via scoreArticleQuality &gt; rich content produces a high score (B or A)" time="0.000985161">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="grade boundaries via scoreArticleQuality &gt; grade F is assigned for very low quality content" time="0.000354526">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="grade boundaries via scoreArticleQuality &gt; passesQualityGate is false when overallScore &lt; 70" time="0.000214503">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="grade boundaries via scoreArticleQuality &gt; passesQualityGate is true for rich content" time="0.000733226">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="generateRecommendations &gt; recommends expanding word count when below 500" time="0.000239868">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="generateRecommendations &gt; recommends increasing word count when below 1500" time="0.0001397">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="generateRecommendations &gt; recommends adding political context when missing" time="0.000122088">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="generateRecommendations &gt; recommends adding SWOT when missing" time="0.000109409">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="generateRecommendations &gt; recommends adding dashboard when missing" time="0.000094164">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="generateRecommendations &gt; recommends missing stakeholder perspectives" time="0.000086884">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="generateRecommendations &gt; recommends adding evidence references when below 3" time="0.000097689">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="generateRecommendations &gt; returns empty recommendations for a fully scored report" time="0.000193258">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="generateRecommendations &gt; omits keyword-based recommendations for non-English articles" time="0.000394756">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="edge cases &gt; handles HTML with only whitespace gracefully" time="0.001129775">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="edge cases &gt; handles very long HTML without errors" time="0.001898885">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="edge cases &gt; handles HTML with special characters" time="0.000422126">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="edge cases &gt; handles articles without a &lt;main&gt; element" time="0.00028977">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="edge cases &gt; EP document references are counted (known formats TA-, PE-, A9-)" time="0.000307166">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="edge cases &gt; EP document ref pattern excludes generic codes like EU-27" time="0.000283034">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="edge cases &gt; EP doc refs inside script blocks (JSON-LD) are not double-counted" time="0.000326525">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="edge cases &gt; PE-123.456 is not double-counted as both PE-123.456 and PE-123" time="0.000224677">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="scoreTemporalCoverage &gt; should return score=0 for empty text" time="0.000185885">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="scoreTemporalCoverage &gt; should detect past context keywords" time="0.000099595">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="scoreTemporalCoverage &gt; should detect current state keywords" time="0.000407841">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="scoreTemporalCoverage &gt; should detect forward outlook keywords" time="0.000153082">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="scoreTemporalCoverage &gt; should score 100 when all three temporal dimensions are present" time="0.000143801">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="scoreTemporalCoverage &gt; should not false-match &quot;will&quot; inside &quot;William&quot;" time="0.000180566">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="scoreCrossReferenceDensity &gt; should return score=0 for HTML with no references" time="0.000206206">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="scoreCrossReferenceDensity &gt; should count TA-number references" time="0.000100333">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="scoreCrossReferenceDensity &gt; should count procedure references" time="0.000089243">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="scoreCrossReferenceDensity &gt; should include taNumbers in totalReferences" time="0.000130324">
        </testcase>
        <testcase classname="test/unit/article-quality-scorer.test.js" name="scoreCrossReferenceDensity &gt; should not count references inside script blocks" time="0.000410251">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/article-strategies.test.js" timestamp="2026-04-14T20:47:06.363Z" hostname="runnervm35a4x" tests="248" failures="0" errors="0" skipped="0" time="0.258747772">
        <testcase classname="test/unit/article-strategies.test.js" name="WeekAheadStrategy &gt; has the correct article type" time="0.005923529">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="WeekAheadStrategy &gt; declares required MCP tools including feed endpoints" time="0.002194109">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="WeekAheadStrategy &gt; buildContent returns non-empty HTML for the given language" time="0.008385822">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="WeekAheadStrategy &gt; buildContent returns non-empty content for multiple languages" time="0.002635127">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="WeekAheadStrategy &gt; buildContent injects What-to-Watch section inside .article-content when pipeline has bottleneck" time="0.003069719">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="WeekAheadStrategy &gt; getMetadata returns en title containing &quot;Week Ahead&quot; or equivalent" time="0.001092393">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="WeekAheadStrategy &gt; getMetadata subtitle includes event counts from data" time="0.000235692">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="WeekAheadStrategy &gt; getMetadata title includes content-aware suffix when events exist" time="0.000357003">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="WeekAheadStrategy &gt; getMetadata returns different titles for different languages" time="0.001857282">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="WeekAheadStrategy &gt; getMetadata keywords match the weekData keywords" time="0.000335147">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="BreakingNewsStrategy &gt; has the correct article type" time="0.000325814">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="BreakingNewsStrategy &gt; declares required MCP tools" time="0.000727475">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="BreakingNewsStrategy &gt; buildContent returns non-empty HTML for the given language" time="0.00423029">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="BreakingNewsStrategy &gt; buildContent returns valid content for multiple languages" time="0.002460047">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="BreakingNewsStrategy &gt; getMetadata en has title and &quot;breaking&quot; category" time="0.001038316">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="BreakingNewsStrategy &gt; getMetadata title includes content-aware suffix from feed data" time="0.000279292">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="BreakingNewsStrategy &gt; getMetadata subtitle uses most significant feed item" time="0.000224277">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="BreakingNewsStrategy &gt; getMetadata keywords include adopted text titles from feed data" time="0.000245646">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="BreakingNewsStrategy &gt; getMetadata falls back gracefully when feedData is undefined" time="0.000331771">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="BreakingNewsStrategy &gt; getMetadata differs by language" time="0.000412615">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="BreakingNewsStrategy &gt; getMetadata includes significance keyword when feedData is present and score meets threshold" time="0.000418392">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="BreakingNewsStrategy &gt; getMetadata omits significance keyword when feedData is undefined" time="0.000261291">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="BreakingNewsStrategy &gt; getMetadata omits significance keyword when score is below threshold" time="0.000287645">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="CommitteeReportsStrategy &gt; has the correct article type" time="0.000183145">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="CommitteeReportsStrategy &gt; declares required MCP tools including feed endpoints" time="0.000373541">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="CommitteeReportsStrategy &gt; buildContent renders committee name and abbreviation" time="0.003402768">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="CommitteeReportsStrategy &gt; buildContent renders document title" time="0.001428306">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="CommitteeReportsStrategy &gt; buildContent shows &quot;No recent documents available&quot; when committee has real metadata but no docs" time="0.000758589">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="CommitteeReportsStrategy &gt; shouldSkip returns true when committeeDataList is empty (all fetches failed)" time="0.000295616">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="CommitteeReportsStrategy &gt; shouldSkip returns true when all committees are placeholder" time="0.000349182">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="CommitteeReportsStrategy &gt; shouldSkip returns false when committees are all-placeholder but feedData has adoptedTexts" time="0.00022855">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="CommitteeReportsStrategy &gt; shouldSkip returns true when committees are all-placeholder and feedData has no items" time="0.000390974">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="CommitteeReportsStrategy &gt; shouldSkip returns false when there is real committee data" time="0.000181121">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="CommitteeReportsStrategy &gt; buildContent renders committee-card--unavailable for placeholder-shaped committee data" time="0.0003093">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="CommitteeReportsStrategy &gt; buildContent escapes HTML in committee name" time="0.000674735">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="CommitteeReportsStrategy &gt; buildContent renders adopted-texts-overview section when feedData has adoptedTexts" time="0.001306026">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="CommitteeReportsStrategy &gt; buildContent categorizes agri-food titles under AGRI not ENVI" time="0.001072779">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="CommitteeReportsStrategy &gt; buildContent omits adopted-texts-overview section when feedData has no adoptedTexts" time="0.000822366">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="CommitteeReportsStrategy &gt; buildContent uses singular summary when exactly one adopted text" time="0.001365646">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="CommitteeReportsStrategy &gt; buildContent uses plural summary when multiple adopted texts" time="0.000897985">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="CommitteeReportsStrategy &gt; buildContent does not categorize civil aviation under LIBE" time="0.001008855">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="CommitteeReportsStrategy &gt; buildContent does not categorize social security under AFET" time="0.000958444">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="CommitteeReportsStrategy &gt; buildContent categorizes Ukraine defence under AFET" time="0.000981489">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="CommitteeReportsStrategy &gt; buildContent categorizes asylum migration under LIBE" time="0.000802202">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="CommitteeReportsStrategy &gt; buildContent does not categorize &quot;justice&quot; alone under LIBE (too broad)" time="0.000830039">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="CommitteeReportsStrategy &gt; buildContent categorizes justice and home affairs under LIBE" time="0.000800499">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="CommitteeReportsStrategy &gt; buildContent does not categorize &quot;peace&quot; alone under AFET (too broad)" time="0.00112328">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="CommitteeReportsStrategy &gt; getMetadata returns &quot;committee-reports&quot; category" time="0.000736083">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="CommitteeReportsStrategy &gt; getMetadata keywords include committee abbreviations" time="0.000471441">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="CommitteeReportsStrategy &gt; getMetadata subtitle uses analytical content" time="0.000582544">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="CommitteeReportsStrategy &gt; getMetadata title includes content-aware suffix" time="0.00026944">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="CommitteeReportsStrategy &gt; getMetadata includes EP source reference" time="0.00027845">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="PropositionsStrategy &gt; has the correct article type" time="0.000175986">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="PropositionsStrategy &gt; declares required MCP tools including feed endpoints" time="0.00048388">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="PropositionsStrategy &gt; buildContent en includes localized lede text" time="0.002894344">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="PropositionsStrategy &gt; buildContent renders proposals HTML" time="0.001115508">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="PropositionsStrategy &gt; buildContent differs by language (uses localized strings)" time="0.002048399">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="PropositionsStrategy &gt; buildContent handles null pipelineData gracefully" time="0.001061439">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="PropositionsStrategy &gt; getMetadata returns &quot;propositions&quot; category" time="0.00065102">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="PropositionsStrategy &gt; getMetadata subtitle uses analytical content" time="0.000188453">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="PropositionsStrategy &gt; getMetadata keywords include legislative pipeline when pipelineData present" time="0.000304022">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="PropositionsStrategy &gt; getMetadata title may have suffix when feed data provides content" time="0.000388181">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MotionsStrategy &gt; has the correct article type" time="0.000166249">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MotionsStrategy &gt; declares required MCP tools including feed endpoints" time="0.000466553">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MotionsStrategy &gt; buildContent renders voting record title" time="0.005410155">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MotionsStrategy &gt; buildContent renders voting patterns" time="0.001186817">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MotionsStrategy &gt; buildContent renders anomaly type" time="0.000922499">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MotionsStrategy &gt; buildContent renders parliamentary question author" time="0.001097245">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MotionsStrategy &gt; buildContent differs by language" time="0.002119458">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MotionsStrategy &gt; buildContent injects Political Alignment section inside .article-content when voting records are present" time="0.002039489">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MotionsStrategy &gt; buildContent strips marker without injecting alignment when voting records are empty" time="0.000906066">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MotionsStrategy &gt; getMetadata returns &quot;motions&quot; category" time="0.000925231">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MotionsStrategy &gt; getMetadata keywords include voting record titles" time="0.000614049">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MotionsStrategy &gt; getMetadata keywords include anomaly types" time="0.000208793">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MotionsStrategy &gt; getMetadata keywords include question topics" time="0.00019227">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MotionsStrategy &gt; getMetadata subtitle uses most significant adopted text or vote" time="0.00022638">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MotionsStrategy &gt; getMetadata title includes content-aware suffix" time="0.000164305">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MotionsStrategy &gt; getMetadata differs by language" time="0.00041964">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="ArticleStrategy interface contract &gt; WeekAheadStrategy &gt; has a non-empty type string" time="0.000176966">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="ArticleStrategy interface contract &gt; WeekAheadStrategy &gt; has a non-empty requiredMCPTools array" time="0.00016847">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="ArticleStrategy interface contract &gt; WeekAheadStrategy &gt; buildContent returns a non-empty string for &quot;en&quot;" time="0.000804307">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="ArticleStrategy interface contract &gt; WeekAheadStrategy &gt; getMetadata returns valid metadata for &quot;en&quot;" time="0.000291152">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="ArticleStrategy interface contract &gt; WeekAheadStrategy &gt; fetchData is an async function" time="0.000158687">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="ArticleStrategy interface contract &gt; BreakingNewsStrategy &gt; has a non-empty type string" time="0.000140899">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="ArticleStrategy interface contract &gt; BreakingNewsStrategy &gt; has a non-empty requiredMCPTools array" time="0.000117098">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="ArticleStrategy interface contract &gt; BreakingNewsStrategy &gt; buildContent returns a non-empty string for &quot;en&quot;" time="0.007011635">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="ArticleStrategy interface contract &gt; BreakingNewsStrategy &gt; getMetadata returns valid metadata for &quot;en&quot;" time="0.000423585">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="ArticleStrategy interface contract &gt; BreakingNewsStrategy &gt; fetchData is an async function" time="0.000137115">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="ArticleStrategy interface contract &gt; CommitteeReportsStrategy &gt; has a non-empty type string" time="0.000132763">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="ArticleStrategy interface contract &gt; CommitteeReportsStrategy &gt; has a non-empty requiredMCPTools array" time="0.000115935">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="ArticleStrategy interface contract &gt; CommitteeReportsStrategy &gt; buildContent returns a non-empty string for &quot;en&quot;" time="0.000765386">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="ArticleStrategy interface contract &gt; CommitteeReportsStrategy &gt; getMetadata returns valid metadata for &quot;en&quot;" time="0.012496499">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="ArticleStrategy interface contract &gt; CommitteeReportsStrategy &gt; fetchData is an async function" time="0.000152086">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="ArticleStrategy interface contract &gt; PropositionsStrategy &gt; has a non-empty type string" time="0.001274689">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="ArticleStrategy interface contract &gt; PropositionsStrategy &gt; has a non-empty requiredMCPTools array" time="0.000167035">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="ArticleStrategy interface contract &gt; PropositionsStrategy &gt; buildContent returns a non-empty string for &quot;en&quot;" time="0.000789777">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="ArticleStrategy interface contract &gt; PropositionsStrategy &gt; getMetadata returns valid metadata for &quot;en&quot;" time="0.000206524">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="ArticleStrategy interface contract &gt; PropositionsStrategy &gt; fetchData is an async function" time="0.000102056">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="ArticleStrategy interface contract &gt; MotionsStrategy &gt; has a non-empty type string" time="0.000234533">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="ArticleStrategy interface contract &gt; MotionsStrategy &gt; has a non-empty requiredMCPTools array" time="0.001830342">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="ArticleStrategy interface contract &gt; MotionsStrategy &gt; buildContent returns a non-empty string for &quot;en&quot;" time="0.001473546">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="ArticleStrategy interface contract &gt; MotionsStrategy &gt; getMetadata returns valid metadata for &quot;en&quot;" time="0.000348727">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="ArticleStrategy interface contract &gt; MotionsStrategy &gt; fetchData is an async function" time="0.000102978">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="WeekAheadStrategy.fetchData with null client &gt; returns valid payload with placeholder events when client is null" time="0.00311321">
            <system-out>
  📆 Date range: 2025-01-16 to 2025-01-23
  ℹ️ MCP unavailable — using placeholder events

            </system-out>
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="WeekAheadStrategy.fetchData with null client &gt; keywords array is non-empty" time="0.00066167">
            <system-out>
  📆 Date range: 2025-01-16 to 2025-01-23
  ℹ️ MCP unavailable — using placeholder events

            </system-out>
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="BreakingNewsStrategy.fetchData with null client &gt; returns empty strings for all raw fields when client is null" time="0.00090446">
            <system-out>
  ⚠️ MCP unavailable — no feed data or analytical context

            </system-out>
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="CommitteeReportsStrategy.fetchData with null client &gt; returns committeeDataList with default entries when client is null" time="0.001175732">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="PropositionsStrategy.fetchData with null client &gt; returns empty proposals and null pipeline when client is null" time="0.001052911">
            <system-out>
  ℹ️ No proposals from MCP — pipeline article will be data-free

            </system-out>
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MotionsStrategy.fetchData with null client &gt; returns fallback data with placeholder arrays when client is null" time="0.001900053">
            <system-out>
  ℹ️ Using placeholder voting records
  ℹ️ Using placeholder voting patterns
  ℹ️ Using placeholder voting anomalies
  ℹ️ Using placeholder parliamentary questions

            </system-out>
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MotionsStrategy.fetchData with null client &gt; dateFromStr is 30 days before date" time="0.000431248">
            <system-out>
  ℹ️ Using placeholder voting records
  ℹ️ Using placeholder voting patterns
  ℹ️ Using placeholder voting anomalies
  ℹ️ Using placeholder parliamentary questions

            </system-out>
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="BreakingNewsStrategy.fetchData with mock client &gt; returns empty raw strings when client returns undefined" time="0.002404105">
            <system-out>
  📡 Fetching EP feed data (primary) and analytical context...
  📡 Fetching adopted texts feed (one-week)...
  📡 Fetching events feed (one-week)...
  📡 Fetching procedures feed (one-week)...
  📡 Fetching MEPs feed (one-week)...

  ⚠️ No feed data available — skipping analytical context fetch

            </system-out>
            <system-err>
⚡ Circuit breaker OPEN after 3 consecutive failures
  ⚠️ Circuit breaker not accepting requests (OPEN) — skipping get_meps_feed
  ⚠️ get_adopted_texts_feed failed: client.getAdoptedTextsFeed is not a function
  ⚠️ get_events_feed failed: client.getEventsFeed is not a function
  ⚠️ get_procedures_feed failed: client.getProceduresFeed is not a function

            </system-err>
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="BreakingNewsStrategy.fetchData with pre-fetched feed data file &gt; uses pre-fetched feed data when EP_FEED_DATA_FILE is set" time="0.002620672">
            <system-out>
  📂 Loading pre-fetched feed data from: /tmp/feed-test-tzUnI8/feed-data.json
  ℹ️ Loaded feed data from file: 1 adopted texts, 0 events, 0 procedures, 0 MEP updates
  📰 Pre-fetched feed data: 1 total items

            </system-out>
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="BreakingNewsStrategy.fetchData with pre-fetched feed data file &gt; filters prefetched breaking feed data to the publication date" time="0.000907254">
            <system-out>
  📂 Loading pre-fetched feed data from: /tmp/feed-date-window-xjxsO5/feed-data.json
  ℹ️ Filtered adopted texts to 1/2 items within 2026-03-04..2026-03-04
  ℹ️ Loaded feed data from file: 1 adopted texts, 0 events, 0 procedures, 0 MEP updates
  📰 Pre-fetched feed data: 1 total items

            </system-out>
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="BreakingNewsStrategy.fetchData with pre-fetched feed data file &gt; falls through to MCP fetch when feed data file does not exist" time="0.000778108">
            <system-out>
  📂 Loading pre-fetched feed data from: /tmp/nonexistent-feed-data.json
  ⚠️ Pre-fetched feed data failed to load — falling through to MCP fetch

  ⚠️ MCP unavailable — no feed data or analytical context

            </system-out>
            <system-err>
  ⚠️ Feed data file not found: /tmp/nonexistent-feed-data.json

            </system-err>
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="PropositionsStrategy.fetchData with mock client &gt; returns empty proposals when client returns undefined" time="0.001060836">
            <system-out>
  📡 Fetching legislative data from MCP server...

  ℹ️ No proposals from MCP — pipeline article will be data-free

            </system-out>
            <system-err>
  ⚠️ Circuit breaker not accepting requests (OPEN) — skipping search_documents(proposals)
  ⚠️ Circuit breaker not accepting requests (OPEN) — skipping monitor_legislative_pipeline
  ⚠️ Circuit breaker OPEN — treating as MCP unavailable for EP feeds

            </system-err>
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="PropositionsStrategy feed fallback &gt; builds proposals from feed procedures when search_documents returns empty" time="0.002098971">
            <system-out>
  ℹ️ Loaded EP feed data from file: 2 total items across 12 keys

  📰 Building procedures/adopted-texts from feed data: 2 procedures, 0 adopted texts

            </system-out>
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="PropositionsStrategy feed fallback &gt; renders proc.stage (not proc.type) as proposal-status in feed fallback" time="0.003386627">
            <system-out>
  ℹ️ Loaded EP feed data from file: 1 total items across 12 keys

  📰 Building procedures/adopted-texts from feed data: 1 procedures, 0 adopted texts

            </system-out>
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="PropositionsStrategy feed fallback &gt; omits proposal-status badge for procedures with no stage" time="0.000848666">
            <system-out>
  ℹ️ Loaded EP feed data from file: 1 total items across 12 keys

  📰 Building procedures/adopted-texts from feed data: 1 procedures, 0 adopted texts

            </system-out>
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="PropositionsStrategy feed fallback &gt; builds proposals from feed adopted texts when procedures list is empty" time="0.000864363">
            <system-out>
  ℹ️ Loaded EP feed data from file: 1 total items across 12 keys

  📰 Building procedures/adopted-texts from feed data: 0 procedures, 1 adopted texts

            </system-out>
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="PropositionsStrategy feed fallback &gt; filters stale prefetched feed procedures outside the recent article window" time="0.002952329">
            <system-out>
  ℹ️ Filtered procedures to 1/2 items within 2026-02-27..2026-03-06
  ℹ️ Loaded EP feed data from file: 1 total items across 12 keys

  📰 Building procedures/adopted-texts from feed data: 1 procedures, 0 adopted texts

            </system-out>
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="WeekAheadStrategy — error branch &gt; fetchData throws on invalid date input" time="0.001928601">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="PropositionsStrategy.fetchData with rejected promises &gt; handles rejected proposals and pipeline gracefully" time="0.000584211">
            <system-out>
  📡 Fetching legislative data from MCP server...

  ℹ️ No proposals from MCP — pipeline article will be data-free

            </system-out>
            <system-err>
  ⚠️ Circuit breaker not accepting requests (OPEN) — skipping search_documents(proposals)
  ⚠️ Circuit breaker not accepting requests (OPEN) — skipping monitor_legislative_pipeline
  ⚠️ Circuit breaker OPEN — treating as MCP unavailable for EP feeds

            </system-err>
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="PropositionsStrategy.buildContent with empty proposals &gt; renders without proposals section when proposalsHtml is empty" time="0.000867046">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="WeekAheadStrategy.buildContent strips marker without watch section &gt; strips the marker when pipeline is empty (no bottleneck)" time="0.000709814">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MonthAheadStrategy &gt; has the correct article type" time="0.00013486">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MonthAheadStrategy &gt; declares required MCP tools including feed endpoints" time="0.000869395">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MonthAheadStrategy &gt; buildContent returns non-empty HTML for the given language" time="0.000810976">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MonthAheadStrategy &gt; buildContent returns non-empty content for multiple languages" time="0.00173999">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MonthAheadStrategy &gt; getMetadata returns en title containing &quot;Month Ahead&quot;" time="0.000502262">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MonthAheadStrategy &gt; getMetadata subtitle includes event counts from data" time="0.000176267">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MonthAheadStrategy &gt; getMetadata title includes content-aware suffix when events exist" time="0.000151076">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MonthAheadStrategy &gt; getMetadata returns localized title for de" time="0.000140575">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MonthAheadStrategy &gt; fetchData returns data with null client (no MCP)" time="0.02947018">
            <system-out>
  📆 Month-ahead range: 2025-01-16 to 2025-02-15
  ℹ️ MCP unavailable — using placeholder events

            </system-out>
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="WeeklyReviewStrategy &gt; has the correct article type" time="0.00018388">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="WeeklyReviewStrategy &gt; declares required MCP tools including feed endpoints" time="0.000345688">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="WeeklyReviewStrategy &gt; buildContent returns non-empty HTML for the given language" time="0.001607574">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="WeeklyReviewStrategy &gt; buildContent injects adopted texts section when feedData is provided" time="0.000774522">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="WeeklyReviewStrategy &gt; buildContent adopted texts count is localized per language" time="0.001440292">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="WeeklyReviewStrategy &gt; buildContent omits adopted texts section when feedData is absent" time="0.001185419">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="WeeklyReviewStrategy &gt; buildContent returns non-empty content for multiple languages" time="0.001617407">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="WeeklyReviewStrategy &gt; getMetadata returns en title containing &quot;Week in Review&quot;" time="0.000790746">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="WeeklyReviewStrategy &gt; getMetadata keywords include voting record titles" time="0.000250427">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="WeeklyReviewStrategy &gt; getMetadata keywords include adopted text titles from feed" time="0.000207135">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="WeeklyReviewStrategy &gt; getMetadata subtitle includes vote and anomaly counts" time="0.000200279">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="WeeklyReviewStrategy &gt; getMetadata title includes content-aware suffix" time="0.000189081">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="WeeklyReviewStrategy &gt; getMetadata returns localized title for sv" time="0.000208926">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="WeeklyReviewStrategy &gt; fetchData returns empty arrays with null client (no MCP)" time="0.001322787">
            <system-out>
  📊 Weekly review range: 2025-01-08 to 2025-01-15

            </system-out>
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="WeeklyReviewStrategy &gt; filters prefetched review feed data to the weekly review window" time="0.001258854">
            <system-out>
  📊 Weekly review range: 2026-02-28 to 2026-03-07
  ℹ️ Filtered adopted texts to 1/2 items within 2026-02-28..2026-03-07
  ℹ️ Filtered committee documents to 0/1 items within 2026-02-28..2026-03-07
  ℹ️ Loaded EP feed data from file: 2 total items across 12 keys

            </system-out>
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MonthlyReviewStrategy &gt; has the correct article type" time="0.000176805">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MonthlyReviewStrategy &gt; declares required MCP tools including feed endpoints" time="0.00042612">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MonthlyReviewStrategy &gt; buildContent returns non-empty HTML for the given language" time="0.001310333">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MonthlyReviewStrategy &gt; buildContent returns non-empty content for multiple languages" time="0.003405416">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MonthlyReviewStrategy &gt; getMetadata returns en title containing &quot;Month in Review&quot;" time="0.000711812">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MonthlyReviewStrategy &gt; getMetadata keywords include voting record titles" time="0.000215641">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MonthlyReviewStrategy &gt; getMetadata keywords include anomaly types" time="0.000187204">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MonthlyReviewStrategy &gt; getMetadata subtitle includes vote and anomaly counts" time="0.000163108">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MonthlyReviewStrategy &gt; getMetadata title includes content-aware suffix" time="0.000151073">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MonthlyReviewStrategy &gt; getMetadata returns localized title for fr" time="0.000149931">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MonthlyReviewStrategy &gt; fetchData returns empty arrays with null client (no MCP)" time="0.001395542">
            <system-out>
  📊 Monthly review range: 2024-12-16 to 2025-01-15

            </system-out>
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="SWOT and Dashboard integration across all strategies &gt; WeekAheadStrategy.buildContent includes SWOT section" time="0.005461562">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="SWOT and Dashboard integration across all strategies &gt; WeekAheadStrategy.buildContent includes Dashboard section" time="0.000743034">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="SWOT and Dashboard integration across all strategies &gt; MonthAheadStrategy.buildContent includes SWOT section" time="0.00075664">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="SWOT and Dashboard integration across all strategies &gt; MonthAheadStrategy.buildContent includes Dashboard section" time="0.001287577">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="SWOT and Dashboard integration across all strategies &gt; BreakingNewsStrategy.buildContent includes SWOT section" time="0.001061761">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="SWOT and Dashboard integration across all strategies &gt; BreakingNewsStrategy.buildContent includes Dashboard section" time="0.001639764">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="SWOT and Dashboard integration across all strategies &gt; CommitteeReportsStrategy.buildContent includes SWOT section" time="0.000768943">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="SWOT and Dashboard integration across all strategies &gt; CommitteeReportsStrategy.buildContent includes Dashboard section" time="0.000758884">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="SWOT and Dashboard integration across all strategies &gt; PropositionsStrategy.buildContent includes SWOT section" time="0.001084475">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="SWOT and Dashboard integration across all strategies &gt; PropositionsStrategy.buildContent includes Dashboard section" time="0.001053894">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="SWOT and Dashboard integration across all strategies &gt; MotionsStrategy.buildContent includes SWOT section" time="0.001091274">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="SWOT and Dashboard integration across all strategies &gt; MotionsStrategy.buildContent includes Dashboard section" time="0.000990031">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="SWOT and Dashboard integration across all strategies &gt; MotionsStrategy.buildContent omits Dashboard section when all votingRecords have placeholder results" time="0.00093379">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="SWOT and Dashboard integration across all strategies &gt; WeeklyReviewStrategy.buildContent includes SWOT section" time="0.00100419">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="SWOT and Dashboard integration across all strategies &gt; WeeklyReviewStrategy.buildContent includes Dashboard section" time="0.001097857">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="SWOT and Dashboard integration across all strategies &gt; MonthlyReviewStrategy.buildContent includes SWOT section" time="0.001017739">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="SWOT and Dashboard integration across all strategies &gt; MonthlyReviewStrategy.buildContent includes Dashboard section" time="0.00095199">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="SWOT and Dashboard integration across all strategies &gt; SWOT section is localized for German" time="0.000846975">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="SWOT and Dashboard integration across all strategies &gt; Dashboard section is localized for French" time="0.001125217">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; WeekAheadStrategy &gt; getMetadata(sv) returns baseTitle without suffix" time="0.000333558">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; WeekAheadStrategy &gt; getMetadata(sv) subtitle uses localized base (not English description)" time="0.000279853">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; WeekAheadStrategy &gt; getMetadata(fr) returns baseTitle without suffix" time="0.000230951">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; WeekAheadStrategy &gt; getMetadata(fr) subtitle uses localized base (not English description)" time="0.000167374">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; WeekAheadStrategy &gt; getMetadata(de) returns baseTitle without suffix" time="0.000201703">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; WeekAheadStrategy &gt; getMetadata(de) subtitle uses localized base (not English description)" time="0.000162836">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; WeekAheadStrategy &gt; getMetadata(ja) returns baseTitle without suffix" time="0.000256481">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; WeekAheadStrategy &gt; getMetadata(ja) subtitle uses localized base (not English description)" time="0.000205821">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; WeekAheadStrategy &gt; getMetadata(ar) returns baseTitle without suffix" time="0.000209002">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; WeekAheadStrategy &gt; getMetadata(ar) subtitle uses localized base (not English description)" time="0.000177458">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; BreakingNewsStrategy &gt; getMetadata(sv) returns localized title without English suffix" time="0.000417395">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; BreakingNewsStrategy &gt; getMetadata(fr) returns localized title without English suffix" time="0.000298087">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; BreakingNewsStrategy &gt; getMetadata(de) returns localized title without English suffix" time="0.000216915">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; BreakingNewsStrategy &gt; getMetadata(ja) returns localized title without English suffix" time="0.000312577">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; BreakingNewsStrategy &gt; getMetadata(ar) returns localized title without English suffix" time="0.000274293">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; CommitteeReportsStrategy &gt; getMetadata(sv) returns baseTitle without suffix" time="0.000299469">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; CommitteeReportsStrategy &gt; getMetadata(fr) returns baseTitle without suffix" time="0.000263856">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; CommitteeReportsStrategy &gt; getMetadata(de) returns baseTitle without suffix" time="0.000291578">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; CommitteeReportsStrategy &gt; getMetadata(ja) returns baseTitle without suffix" time="0.000248102">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; CommitteeReportsStrategy &gt; getMetadata(ar) returns baseTitle without suffix" time="0.000261578">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; PropositionsStrategy &gt; getMetadata(sv) returns baseTitle without suffix" time="0.000345901">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; PropositionsStrategy &gt; getMetadata(fr) returns baseTitle without suffix" time="0.000252697">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; PropositionsStrategy &gt; getMetadata(de) returns baseTitle without suffix" time="0.000226215">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; PropositionsStrategy &gt; getMetadata(ja) returns baseTitle without suffix" time="0.000264127">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; PropositionsStrategy &gt; getMetadata(ar) returns baseTitle without suffix" time="0.000267087">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; MotionsStrategy &gt; getMetadata(sv) returns baseTitle without suffix" time="0.000299981">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; MotionsStrategy &gt; getMetadata(fr) returns baseTitle without suffix" time="0.000238079">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; MotionsStrategy &gt; getMetadata(de) returns baseTitle without suffix" time="0.00027821">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; MotionsStrategy &gt; getMetadata(ja) returns baseTitle without suffix" time="0.000243966">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; MotionsStrategy &gt; getMetadata(ar) returns baseTitle without suffix" time="0.000233808">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; MonthAheadStrategy &gt; getMetadata(sv) returns baseTitle without suffix" time="0.000300822">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; MonthAheadStrategy &gt; getMetadata(fr) returns baseTitle without suffix" time="0.000253829">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; MonthAheadStrategy &gt; getMetadata(de) returns baseTitle without suffix" time="0.000178541">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; MonthAheadStrategy &gt; getMetadata(ja) returns baseTitle without suffix" time="0.000219019">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; MonthAheadStrategy &gt; getMetadata(ar) returns baseTitle without suffix" time="0.000214649">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; WeeklyReviewStrategy &gt; getMetadata(sv) returns baseTitle without suffix" time="0.000350449">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; WeeklyReviewStrategy &gt; getMetadata(fr) returns baseTitle without suffix" time="0.000286612">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; WeeklyReviewStrategy &gt; getMetadata(de) returns baseTitle without suffix" time="0.000270945">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; WeeklyReviewStrategy &gt; getMetadata(ja) returns baseTitle without suffix" time="0.000283159">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; WeeklyReviewStrategy &gt; getMetadata(ar) returns baseTitle without suffix" time="0.000243386">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; MonthlyReviewStrategy &gt; getMetadata(sv) returns baseTitle without suffix" time="0.00031839">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; MonthlyReviewStrategy &gt; getMetadata(fr) returns baseTitle without suffix" time="0.000256579">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; MonthlyReviewStrategy &gt; getMetadata(de) returns baseTitle without suffix" time="0.000222267">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; MonthlyReviewStrategy &gt; getMetadata(ja) returns baseTitle without suffix" time="0.000210912">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata non-English branches &gt; MonthlyReviewStrategy &gt; getMetadata(ar) returns baseTitle without suffix" time="0.000226908">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata with empty data edge cases &gt; WeekAheadStrategy: empty weekData yields no suffix" time="0.000287294">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata with empty data edge cases &gt; MonthAheadStrategy: empty monthData yields no suffix" time="0.000251419">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata with empty data edge cases &gt; MotionsStrategy: empty records yields no suffix" time="0.000271168">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata with empty data edge cases &gt; WeeklyReviewStrategy: empty records yields no suffix" time="0.000235288">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata with empty data edge cases &gt; MonthlyReviewStrategy: empty records yields no suffix" time="0.00026571">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata with empty data edge cases &gt; PropositionsStrategy: empty proposalsHtml yields no suffix" time="0.000217147">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata with enriched data (all suffix branches) &gt; WeekAheadStrategy: committees and pipeline in suffix" time="0.000346481">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata with enriched data (all suffix branches) &gt; MonthAheadStrategy: committees and pipeline in suffix" time="0.000360312">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata with enriched data (all suffix branches) &gt; PropositionsStrategy: feedData procedures and adopted texts used for analytical title" time="0.000513637">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata with enriched data (all suffix branches) &gt; PropositionsStrategy: no feedData yields generic description" time="0.000206907">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata with enriched data (all suffix branches) &gt; WeeklyReviewStrategy: feedData adopted texts contribute to suffix" time="0.000297305">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata with enriched data (all suffix branches) &gt; MotionsStrategy: multiple records produce analytical title suffix" time="0.000294458">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata with enriched data (all suffix branches) &gt; MonthlyReviewStrategy: multiple records in suffix" time="0.000254797">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata with enriched data (all suffix branches) &gt; MotionsStrategy: feedData adoptedTexts used for analytical title and description" time="0.000449172">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata with enriched data (all suffix branches) &gt; CommitteeReportsStrategy: feedData adoptedTexts used for analytical title and description" time="0.000410334">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata with enriched data (all suffix branches) &gt; CommitteeReportsStrategy: committee without docs yields abbreviation in suffix" time="0.000218928">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata with enriched data (all suffix branches) &gt; BreakingNewsStrategy: empty feedData array still produces base keywords" time="0.000303897">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata with enriched data (all suffix branches) &gt; BreakingNewsStrategy: feedData with only mepUpdates falls back to generic description" time="0.000223434">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="getMetadata with enriched data (all suffix branches) &gt; MonthlyReviewStrategy: keywords include voting records but exclude feedData titles" time="0.000559668">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="buildContent feedData absent branches &gt; MotionsStrategy: buildContent without feedData omits adopted-texts section" time="0.001132469">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="buildContent feedData absent branches &gt; WeeklyReviewStrategy: buildContent without feedData omits adopted texts section" time="0.001008708">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="buildContent feedData absent branches &gt; WeeklyReviewStrategy: buildContent with empty adoptedTexts omits section" time="0.001041744">
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MonthAheadStrategy.fetchData with null client &gt; returns valid payload with dateRange spanning 30 days" time="0.001056379">
            <system-out>
  📆 Month-ahead range: 2025-03-02 to 2025-04-01
  ℹ️ MCP unavailable — using placeholder events

            </system-out>
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="WeeklyReviewStrategy.fetchData with null client &gt; returns valid payload with dateRange and placeholder arrays" time="0.000822621">
            <system-out>
  📊 Weekly review range: 2025-02-22 to 2025-03-01

            </system-out>
        </testcase>
        <testcase classname="test/unit/article-strategies.test.js" name="MonthlyReviewStrategy.fetchData with null client &gt; returns valid payload with dateRange and monthLabel" time="0.000877665">
            <system-out>
  📊 Monthly review range: 2025-01-30 to 2025-03-01

            </system-out>
        </testcase>
    </testsuite>
    <testsuite name="test/unit/article-template.test.js" timestamp="2026-04-14T20:47:06.395Z" hostname="runnervm35a4x" tests="128" failures="0" errors="0" skipped="0" time="0.198878707">
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; HTML Generation &gt; should generate valid HTML structure" time="0.034050496">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; HTML Generation &gt; should include DOCTYPE declaration" time="0.001298649">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; HTML Generation &gt; should include all required meta tags" time="0.001195432">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; HTML Generation &gt; should include article title in multiple places" time="0.000978423">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; HTML Generation &gt; should include article subtitle" time="0.001222086">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; HTML Generation &gt; should include article content" time="0.001433059">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Language Support &gt; should set correct lang attribute for English" time="0.000976749">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Language Support &gt; should set correct lang attribute for German" time="0.001836458">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Language Support &gt; should set correct lang attribute for Greek" time="0.002110948">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Language Support &gt; should use correct language name for display" time="0.013744925">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; RTL Support &gt; should set RTL direction for Arabic" time="0.001673414">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; RTL Support &gt; should set RTL direction for Hebrew" time="0.00132268">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; RTL Support &gt; should set LTR direction for all EU languages" time="0.013308636">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Article Metadata &gt; should include article type label in English" time="0.000872489">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Article Metadata &gt; should include article type label in German" time="0.002023029">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Article Metadata &gt; should fall back to raw category string for unknown article categories" time="0.000733436">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Article Metadata &gt; should format date according to language" time="0.000877283">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Article Metadata &gt; should include read time with correct label" time="0.000472934">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Article Metadata &gt; should include read time in German" time="0.00051656">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; SEO Optimization &gt; should include Open Graph meta tags" time="0.00073791">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; SEO Optimization &gt; should include Twitter Card meta tags" time="0.000694852">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; SEO Optimization &gt; should include Schema.org structured data" time="0.000736103">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; SEO Optimization &gt; should include keywords in meta tags" time="0.000887918">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; SEO Optimization &gt; should include keywords in structured data" time="0.000620099">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; SEO Optimization &gt; should include article:section Open Graph meta tag" time="0.000638401">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; SEO Optimization &gt; should include article:tag Open Graph meta tags for keywords" time="0.000684503">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; SEO Optimization &gt; should include article:modified_time meta tag" time="0.000618896">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; SEO Optimization &gt; should include dateModified in structured data" time="0.000630293">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; SEO Optimization &gt; should include articleSection in structured data" time="0.000650326">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; SEO Optimization &gt; should include mainEntityOfPage in structured data" time="0.000666461">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Sources Section &gt; should include sources when provided" time="0.000808137">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Sources Section &gt; should not include sources section when empty" time="0.000731769">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Sources Section &gt; should use rel=&quot;noopener noreferrer&quot; for external links" time="0.000997997">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Navigation &gt; should include back to news link at bottom" time="0.000694707">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Navigation &gt; should include back to news link at top" time="0.000680146">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Navigation &gt; should use correct back link for language" time="0.001007216">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Language Switcher &gt; should include language switcher navigation" time="0.000672008">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Language Switcher &gt; should include lang-link elements for all 14 languages" time="0.001049961">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Language Switcher &gt; should mark the current language as active" time="0.000774773">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Language Switcher &gt; should link to same article in other languages using filename pattern" time="0.001234313">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Language Switcher &gt; should include flag emojis in language links" time="0.00099486">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Language Switcher &gt; should throw on invalid date format in language switcher" time="0.001436563">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Language Switcher &gt; should throw on date with HTML injection" time="0.000498494">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Language Switcher &gt; should throw on slug with HTML injection characters" time="0.000553262">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Language Switcher &gt; should throw on slug with angle brackets" time="0.000629082">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Language Switcher &gt; should throw on empty slug" time="0.000627606">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Language Switcher &gt; should throw on whitespace-only slug" time="0.000562658">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Language Switcher &gt; should throw on empty date" time="0.000452499">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Language Switcher &gt; should throw on whitespace-only date" time="0.000403046">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Language Switcher &gt; should escape language names in title attributes" time="0.000808364">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Enhanced Footer &gt; should include full footer with multiple sections" time="0.000796894">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Enhanced Footer &gt; should include footer language grid" time="0.000592113">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Enhanced Footer &gt; should include footer language grid with correct index links" time="0.001533652">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Enhanced Footer &gt; should mark current language as active in footer language grid" time="0.000833153">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Enhanced Footer &gt; should include Hack23 AB copyright with organization details" time="0.000695612">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Enhanced Footer &gt; should include links to GitHub, European Parliament, and license" time="0.000873744">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Enhanced Footer &gt; should use footer-section divs for each section" time="0.000637332">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Enhanced Footer &gt; should include app version in footer" time="0.001019753">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Enhanced Footer &gt; should include disclaimer with link to GitHub issues" time="0.000633759">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Security - XSS Prevention &gt; should not include executable script tags in content" time="0.001762717">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Security - XSS Prevention &gt; should properly escape special characters in title" time="0.001667195">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Security - XSS Prevention &gt; should not allow javascript: URLs in sources" time="0.000732246">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Accessibility &gt; should include proper semantic HTML" time="0.000734363">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Accessibility &gt; should include lang attribute on article element" time="0.000727878">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Accessibility &gt; should include skip navigation link" time="0.000582876">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Accessibility &gt; should include site header with branding" time="0.00061731">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Accessibility &gt; should include main element with id for skip link target" time="0.000590264">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Accessibility &gt; should include site footer" time="0.000633666">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Accessibility &gt; should include security meta tags" time="0.000880845">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Accessibility &gt; should include CSP script-src hash matching the JSON-LD content" time="0.000967466">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Accessibility &gt; should include SRI integrity attribute on stylesheet when stylesHash is provided" time="0.000739968">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Accessibility &gt; should not include integrity attribute on stylesheet when stylesHash is omitted" time="0.00065793">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Accessibility &gt; should omit SRI attributes when stylesHash has invalid format" time="0.000761382">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Error Handling &gt; should handle missing optional fields gracefully" time="0.001241836">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Error Handling &gt; should use default values for undefined language" time="0.001364334">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Article Validation (validateArticleHTML) &gt; should pass validation for a correctly generated article" time="0.001082563">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Article Validation (validateArticleHTML) &gt; should pass validation for all 14 languages" time="0.014497915">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Article Validation (validateArticleHTML) &gt; should fail validation for HTML missing only language switcher" time="0.00089649">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Article Validation (validateArticleHTML) &gt; should fail validation for HTML missing only article-top-nav" time="0.000690703">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Article Validation (validateArticleHTML) &gt; should fail validation for HTML missing only site-header" time="0.000782882">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Article Validation (validateArticleHTML) &gt; should fail validation for HTML missing only skip-link" time="0.000669852">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Article Validation (validateArticleHTML) &gt; should fail validation for HTML missing only reading-progress" time="0.000907262">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Article Validation (validateArticleHTML) &gt; should fail validation for HTML missing only main content wrapper" time="0.001914448">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Article Validation (validateArticleHTML) &gt; should fail validation for HTML missing only site-footer" time="0.000723724">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Article Validation (validateArticleHTML) &gt; should fail validation for HTML missing all required elements" time="0.000271956">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Article Validation (validateArticleHTML) &gt; should report all missing elements in errors array" time="0.000899614">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Localized header subtitle and footer sections &gt; should render English header subtitle in English articles" time="0.005749109">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Localized header subtitle and footer sections &gt; should render German header subtitle in German articles" time="0.000811362">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Localized header subtitle and footer sections &gt; should render localized footer &quot;About&quot; heading in English" time="0.000643256">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Localized header subtitle and footer sections &gt; should render localized footer &quot;Quick Links&quot; heading in English" time="0.000623475">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Localized header subtitle and footer sections &gt; should render localized footer &quot;Built by Hack23 AB&quot; heading in English" time="0.002359056">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Localized header subtitle and footer sections &gt; should render localized footer &quot;Languages&quot; heading in English" time="0.000615136">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Localized header subtitle and footer sections &gt; should render localized footer heading in Swedish" time="0.001064118">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Localized header subtitle and footer sections &gt; should render localized footer heading in French" time="0.001065622">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Localized header subtitle and footer sections &gt; should render localized header subtitle for all 14 languages" time="0.007242427">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Chart.js conditional inclusion &gt; should NOT include Chart.js scripts when content has no charts" time="0.001256467">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Chart.js conditional inclusion &gt; should include Chart.js scripts when content has data-chart-config" time="0.000664175">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Chart.js conditional inclusion &gt; should use defer attribute on Chart.js scripts" time="0.000608465">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; D3.js conditional inclusion &gt; should NOT include D3.js scripts when content has no mindmaps or SWOT" time="0.000654497">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; D3.js conditional inclusion &gt; should include D3.js scripts when content has mindmap-container" time="0.000622401">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; D3.js conditional inclusion &gt; should include D3.js scripts when content has swot-matrix" time="0.000595667">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; D3.js conditional inclusion &gt; should include both Chart.js and D3.js when content has both" time="0.000853099">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; D3.js conditional inclusion &gt; should use defer attribute on D3.js scripts" time="0.000692545">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Schema.org structured data &gt; should include NewsArticle JSON-LD" time="0.000965776">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Schema.org structured data &gt; should include hasPart in NewsArticle JSON-LD conditionally based on content" time="0.001680409">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Schema.org structured data &gt; should include BreadcrumbList JSON-LD" time="0.000699622">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Schema.org structured data &gt; should localize breadcrumb names for non-English languages" time="0.000714299">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Schema.org structured data &gt; should escape &lt;/script&gt; sequences in JSON-LD to prevent XSS" time="0.000708705">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Schema.org structured data &gt; should use &quot;Related Articles&quot; heading not &quot;Related Analysis&quot;" time="0.000630891">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Schema.org structured data &gt; should include BreadcrumbList hash in CSP header" time="0.000494635">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Schema.org structured data &gt; should include timeRequired in Schema.org markup" time="0.000427929">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Schema.org structured data &gt; should auto-compute read time from content when readTime is 0" time="0.00057896">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Cross-article navigation &gt; should not render related articles nav when relatedArticles is empty" time="0.000416858">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Cross-article navigation &gt; should not render related articles nav when relatedArticles is omitted" time="0.000389782">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Cross-article navigation &gt; should render related articles nav when articles are provided" time="0.000506823">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Cross-article navigation &gt; should escape HTML in related article titles" time="0.000442489">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Cross-article navigation &gt; should render multiple related articles" time="0.000455011">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Cross-article navigation &gt; should filter out articles with invalid date/slug/lang patterns" time="0.000581449">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Cross-article navigation &gt; should use relative path prefix in href" time="0.000585506">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Analysis transparency - dynamic analysisFiles &gt; should render dynamic links grouped by subdirectory when analysisFiles provided" time="0.001119992">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Analysis transparency - dynamic analysisFiles &gt; should render fallback links when analysisFiles is undefined" time="0.000719116">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Analysis transparency - dynamic analysisFiles &gt; should render fallback links when analysisFiles is empty" time="0.000598013">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Analysis transparency - dynamic analysisFiles &gt; should handle unknown methods with titleized fallback labels" time="0.000696484">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Analysis transparency - dynamic analysisFiles &gt; should filter out analysis files with path traversal in outputFile" time="0.000979724">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Analysis transparency - dynamic analysisFiles &gt; should URL-encode path segments in analysis file links" time="0.000586853">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Analysis transparency - dynamic analysisFiles &gt; should include documents subdirectory in dynamic links" time="0.000655592">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Analysis transparency - dynamic analysisFiles &gt; should always include manifest.json link regardless of analysisFiles" time="0.000961187">
        </testcase>
        <testcase classname="test/unit/article-template.test.js" name="article-template &gt; generateArticleHTML &gt; Analysis transparency - dynamic analysisFiles &gt; should render analysis files in correct subdirectory order" time="0.000643112">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/breaking-news.test.js" timestamp="2026-04-14T20:47:06.410Z" hostname="runnervm35a4x" tests="71" failures="0" errors="0" skipped="0" time="0.111900394">
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News Generator &gt; buildBreakingNewsContent &gt; should return HTML with placeholder notice when no MCP data" time="0.00369085">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News Generator &gt; buildBreakingNewsContent &gt; should include the date in the breaking banner timestamp" time="0.000314951">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News Generator &gt; buildBreakingNewsContent &gt; should render anomaly section when anomaly data provided" time="0.000630646">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News Generator &gt; buildBreakingNewsContent &gt; should render coalition section when coalition data provided" time="0.000473864">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News Generator &gt; buildBreakingNewsContent &gt; should render report section when report data provided" time="0.000287003">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News Generator &gt; buildBreakingNewsContent &gt; should render key players section when influence data provided" time="0.000273206">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News Generator &gt; buildBreakingNewsContent &gt; should escape HTML in all MCP data fields to prevent XSS" time="0.000315752">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News Generator &gt; buildBreakingNewsContent &gt; should truncate very long MCP data to 2000 characters" time="0.000579534">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News Generator &gt; buildBreakingNewsContent &gt; should render lede section when MCP data is present" time="0.001112463">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News Generator &gt; buildBreakingNewsContent &gt; should include all four sections when all data provided" time="0.000619955">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News Generator &gt; structured intelligence sections &gt; should render intelligence briefing when anomalies array provided" time="0.000733052">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News Generator &gt; structured intelligence sections &gt; should render coalition dynamics section when coalitions array provided" time="0.00039198">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News Generator &gt; structured intelligence sections &gt; should render key players section when mepScores array provided" time="0.000342884">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News Generator &gt; structured intelligence sections &gt; should show non-placeholder lede when only structured intel provided" time="0.000267637">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News Generator &gt; structured intelligence sections &gt; should render all three intel sections when all structured data provided" time="0.000283201">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News Generator &gt; structured intelligence sections &gt; should escape XSS in structured anomaly description" time="0.000288579">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News Generator &gt; Breaking News article HTML generation &gt; should produce valid HTML for breaking news article" time="0.028168028">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News Generator &gt; Breaking News article HTML generation &gt; should generate articles for all 14 EU languages using BREAKING_NEWS_TITLES" time="0.020366827">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News Generator &gt; Breaking News article HTML generation &gt; should generate placeholder breaking news when MCP is unavailable" time="0.000889487">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News editorial quality &gt; should not use &lt;pre&gt; data dumps in anomaly section" time="0.000280742">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News editorial quality &gt; should not use &lt;pre&gt; data dumps in coalition section" time="0.000155878">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News editorial quality &gt; should include source attribution when anomaly data provided" time="0.000143614">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News editorial quality &gt; should not include &quot;Why This Matters&quot; section (replaced by AI-driven analysis)" time="0.000127206">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News editorial quality &gt; should use data-narrative class instead of data-summary" time="0.000142739">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News editorial quality &gt; should include localized editorial strings for French" time="0.000144303">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News editorial quality &gt; should include localized editorial strings for German" time="0.000181124">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News multi-language section headings &gt; should use localized section headings for all 14 languages" time="0.002287207">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News multi-language section headings &gt; should use Japanese section headings" time="0.000263805">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News multi-language section headings &gt; should use Korean section headings" time="0.000250561">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News multi-language section headings &gt; should use Chinese section headings" time="0.000225665">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News multi-language section headings &gt; should have BREAKING_STRINGS for all 14 languages" time="0.002840462">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News feed-based sections &gt; should render adopted texts section when feed data is provided" time="0.001395645">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News feed-based sections &gt; should render events section when feed data is provided" time="0.000330095">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News feed-based sections &gt; should render procedures section when feed data is provided" time="0.000284448">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News feed-based sections &gt; should render MEP updates section when feed data is provided" time="0.000384703">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News feed-based sections &gt; should include publish dates in MEP updates section" time="0.000312209">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News feed-based sections &gt; should show feed-first lede when only feed data is present (no analytical data)" time="0.000329791">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News feed-based sections &gt; should show placeholder when MCP is truly unavailable (no feedData, no analytical data)" time="0.000209242">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News feed-based sections &gt; should render noFeedDataNotice when feedData is present but empty" time="0.000278848">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News feed-based sections &gt; should not render feed sections when feedData is undefined" time="0.000317595">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News feed-based sections &gt; should not render empty feed sections" time="0.000307177">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News feed-based sections &gt; should escape XSS in feed item titles" time="0.000234347">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News feed-based sections &gt; should render feed sections before analytical sections" time="0.01723481">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News feed-based sections &gt; should have BREAKING_STRINGS with feed-related fields for all 14 languages" time="0.005781291">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News feed-based sections &gt; should use localized feed headings for German" time="0.000207455">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News feed-based sections &gt; should use localized feed headings for French" time="0.000226139">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News feed-based sections &gt; should use localized feed headings for Japanese" time="0.000174578">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News feed-based sections &gt; should render feed data alongside analytical context" time="0.000232743">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News adoptedTextItemLabelFn &gt; should render adopted-text label directly without duplication for English" time="0.000167944">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News adoptedTextItemLabelFn &gt; should render adopted-text identifier when label is absent" time="0.000119618">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News adoptedTextItemLabelFn &gt; should have adoptedTextTypeLabel and adoptedTextItemLabelFn for all 14 languages" time="0.00166619">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News adoptedTextItemLabelFn &gt; should render adopted-text items with label across all 14 languages" time="0.00110287">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News feed truncation &gt; should have showingXofNFn for all 14 languages that returns a localized string with both counts" time="0.001914876">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News feed truncation &gt; should show truncation note when adopted texts exceed MAX_FEED_ITEMS for all 14 languages" time="0.001166576">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News feed truncation &gt; should show truncation note when MEP updates exceed MAX_FEED_ITEMS for all 14 languages" time="0.001208809">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News feed truncation &gt; should show truncation note using totalMEPUpdates even when fetched items fit within limit" time="0.00033324">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="Breaking News feed truncation &gt; should not show truncation note when feed items are within limit" time="0.000287738">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="scoreBreakingNewsSignificance &gt; should return zero scores for empty feed data" time="0.000412604">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="scoreBreakingNewsSignificance &gt; should score adopted texts (20 pts each, capped at 100)" time="0.000252578">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="scoreBreakingNewsSignificance &gt; should cap adopted texts sub-score at 100" time="0.000244094">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="scoreBreakingNewsSignificance &gt; should score MEP updates (10 pts each, capped at 100)" time="0.000172162">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="scoreBreakingNewsSignificance &gt; should prefer totalMEPUpdates over mepUpdates.length when available" time="0.000158348">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="scoreBreakingNewsSignificance &gt; should fall back to mepUpdates.length when totalMEPUpdates is undefined" time="0.000156328">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="scoreBreakingNewsSignificance &gt; should score procedures with final stage higher than non-final" time="0.000305178">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="scoreBreakingNewsSignificance &gt; should score events for committee involvement (15 pts each)" time="0.000222081">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="scoreBreakingNewsSignificance &gt; should compute correct weighted overall score" time="0.000411857">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="scoreBreakingNewsSignificance &gt; should handle null/undefined fields gracefully" time="0.000206051">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="scoreBreakingNewsSignificance &gt; should recognise trilogue as a final stage" time="0.00016031">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="scoreBreakingNewsSignificance &gt; should produce score above SIGNIFICANCE_THRESHOLD for rich feed data" time="0.000362572">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="scoreBreakingNewsSignificance &gt; should produce score below SIGNIFICANCE_THRESHOLD for minimal feed data" time="0.000165551">
        </testcase>
        <testcase classname="test/unit/breaking-news.test.js" name="SIGNIFICANCE_THRESHOLD constant &gt; should be a positive number" time="0.000170967">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/committee-indicator-map.test.js" timestamp="2026-04-14T20:47:06.418Z" hostname="runnervm35a4x" tests="32" failures="0" errors="0" skipped="0" time="0.028208786">
        <testcase classname="test/unit/committee-indicator-map.test.js" name="committee-indicator-map &gt; WB_INDICATORS &gt; should contain all core macro-economic indicators" time="0.00224479">
        </testcase>
        <testcase classname="test/unit/committee-indicator-map.test.js" name="committee-indicator-map &gt; WB_INDICATORS &gt; should contain environment indicators" time="0.000229646">
        </testcase>
        <testcase classname="test/unit/committee-indicator-map.test.js" name="committee-indicator-map &gt; WB_INDICATORS &gt; should contain trade indicators" time="0.000171744">
        </testcase>
        <testcase classname="test/unit/committee-indicator-map.test.js" name="committee-indicator-map &gt; WB_INDICATORS &gt; should be consistent with existing POLICY_INDICATORS" time="0.000287344">
        </testcase>
        <testcase classname="test/unit/committee-indicator-map.test.js" name="committee-indicator-map &gt; WB_INDICATORS &gt; should have at least 30 distinct indicator IDs" time="0.000261462">
        </testcase>
        <testcase classname="test/unit/committee-indicator-map.test.js" name="committee-indicator-map &gt; COMMITTEE_INDICATOR_MAP &gt; should cover all 20 EP standing committees and sub-committees" time="0.000235944">
        </testcase>
        <testcase classname="test/unit/committee-indicator-map.test.js" name="committee-indicator-map &gt; COMMITTEE_INDICATOR_MAP &gt; should include the 5 featured committees" time="0.003688885">
        </testcase>
        <testcase classname="test/unit/committee-indicator-map.test.js" name="committee-indicator-map &gt; COMMITTEE_INDICATOR_MAP &gt; should have at least one indicator per committee" time="0.001120908">
        </testcase>
        <testcase classname="test/unit/committee-indicator-map.test.js" name="committee-indicator-map &gt; COMMITTEE_INDICATOR_MAP &gt; should mark ECON indicators with correct priorities" time="0.000309203">
        </testcase>
        <testcase classname="test/unit/committee-indicator-map.test.js" name="committee-indicator-map &gt; COMMITTEE_INDICATOR_MAP &gt; should include ENVI with environment-relevant indicators" time="0.000962015">
        </testcase>
        <testcase classname="test/unit/committee-indicator-map.test.js" name="committee-indicator-map &gt; COMMITTEE_INDICATOR_MAP &gt; should include AGRI with agriculture-relevant indicators" time="0.000277894">
        </testcase>
        <testcase classname="test/unit/committee-indicator-map.test.js" name="committee-indicator-map &gt; COMMITTEE_INDICATOR_MAP &gt; should include AFET with geopolitical indicators" time="0.000241808">
        </testcase>
        <testcase classname="test/unit/committee-indicator-map.test.js" name="committee-indicator-map &gt; COMMITTEE_INDICATOR_MAP &gt; should have valid analysis perspectives" time="0.002111836">
        </testcase>
        <testcase classname="test/unit/committee-indicator-map.test.js" name="committee-indicator-map &gt; COMMITTEE_INDICATOR_MAP &gt; should have consistent indicator structure" time="0.008201852">
        </testcase>
        <testcase classname="test/unit/committee-indicator-map.test.js" name="committee-indicator-map &gt; CATEGORY_INDICATOR_MAP &gt; should cover all ArticleCategory values" time="0.000421804">
        </testcase>
        <testcase classname="test/unit/committee-indicator-map.test.js" name="committee-indicator-map &gt; CATEGORY_INDICATOR_MAP &gt; should have enrichment strategy description for each category" time="0.000400253">
        </testcase>
        <testcase classname="test/unit/committee-indicator-map.test.js" name="committee-indicator-map &gt; CATEGORY_INDICATOR_MAP &gt; should have maxWBCalls within reasonable bounds" time="0.000760551">
        </testcase>
        <testcase classname="test/unit/committee-indicator-map.test.js" name="committee-indicator-map &gt; CATEGORY_INDICATOR_MAP &gt; should have higher maxWBCalls for deep analysis than breaking news" time="0.000135814">
        </testcase>
        <testcase classname="test/unit/committee-indicator-map.test.js" name="committee-indicator-map &gt; CATEGORY_INDICATOR_MAP &gt; should have primary indicators for PROPOSITIONS" time="0.000148185">
        </testcase>
        <testcase classname="test/unit/committee-indicator-map.test.js" name="committee-indicator-map &gt; CATEGORY_INDICATOR_MAP &gt; should have no primary indicators for BREAKING_NEWS" time="0.000452262">
        </testcase>
        <testcase classname="test/unit/committee-indicator-map.test.js" name="committee-indicator-map &gt; CATEGORY_INDICATOR_MAP &gt; should have COMMITTEE_REPORTS delegate to COMMITTEE_INDICATOR_MAP" time="0.000108374">
        </testcase>
        <testcase classname="test/unit/committee-indicator-map.test.js" name="committee-indicator-map &gt; getCommitteeIndicators &gt; should return indicators for a known committee" time="0.000119942">
        </testcase>
        <testcase classname="test/unit/committee-indicator-map.test.js" name="committee-indicator-map &gt; getCommitteeIndicators &gt; should be case-insensitive" time="0.000726534">
        </testcase>
        <testcase classname="test/unit/committee-indicator-map.test.js" name="committee-indicator-map &gt; getCommitteeIndicators &gt; should return empty array for unknown committee" time="0.000261418">
        </testcase>
        <testcase classname="test/unit/committee-indicator-map.test.js" name="committee-indicator-map &gt; getCommitteePrimaryIndicators &gt; should return only primary indicators" time="0.0002796">
        </testcase>
        <testcase classname="test/unit/committee-indicator-map.test.js" name="committee-indicator-map &gt; getCommitteePrimaryIndicators &gt; should return fewer or equal indicators than getCommitteeIndicators" time="0.000117171">
        </testcase>
        <testcase classname="test/unit/committee-indicator-map.test.js" name="committee-indicator-map &gt; getCategoryIndicators &gt; should return entry for a valid category" time="0.000203925">
        </testcase>
        <testcase classname="test/unit/committee-indicator-map.test.js" name="committee-indicator-map &gt; getIndicatorIdsForCommittees &gt; should return deduplicated indicator IDs for multiple committees" time="0.000192971">
        </testcase>
        <testcase classname="test/unit/committee-indicator-map.test.js" name="committee-indicator-map &gt; getIndicatorIdsForCommittees &gt; should filter to primary-only when requested" time="0.000134288">
        </testcase>
        <testcase classname="test/unit/committee-indicator-map.test.js" name="committee-indicator-map &gt; getIndicatorIdsForCommittees &gt; should handle empty array" time="0.000150107">
        </testcase>
        <testcase classname="test/unit/committee-indicator-map.test.js" name="committee-indicator-map &gt; getAllCategoryIndicatorIds &gt; should return combined primary + secondary indicator IDs" time="0.000178518">
        </testcase>
        <testcase classname="test/unit/committee-indicator-map.test.js" name="committee-indicator-map &gt; getAllCategoryIndicatorIds &gt; should return more IDs for DEEP_ANALYSIS than BREAKING_NEWS" time="0.000099301">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/committee-reports.test.js" timestamp="2026-04-14T20:47:06.422Z" hostname="runnervm35a4x" tests="55" failures="0" errors="0" skipped="0" time="0.025027729">
        <testcase classname="test/unit/committee-reports.test.js" name="committee-reports helpers &gt; applyCommitteeInfo &gt; should populate name, chair and members from MCP response" time="0.004055541">
            <system-out>
  ✅ Committee info: Environment (42 members)

            </system-out>
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="committee-reports helpers &gt; applyCommitteeInfo &gt; should coerce string memberCount to number" time="0.000449014">
            <system-out>
  ✅ Committee info: TEST Committee (27 members)

            </system-out>
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="committee-reports helpers &gt; applyCommitteeInfo &gt; should default members to 0 for non-numeric memberCount" time="0.000363814">
            <system-out>
  ✅ Committee info: TEST Committee (0 members)

            </system-out>
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="committee-reports helpers &gt; applyCommitteeInfo &gt; should leave data unchanged when committee key is absent" time="0.000234324">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="committee-reports helpers &gt; applyCommitteeInfo &gt; should degrade gracefully on invalid JSON" time="0.000448991">
            <system-err>
  ⚠️ Failed to parse committee info: Unexpected token &apos;o&apos;, &quot;not-json&quot; is not valid JSON

            </system-err>
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="committee-reports helpers &gt; applyCommitteeInfo &gt; should degrade gracefully on empty result" time="0.000223554">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="committee-reports helpers &gt; applyCommitteeInfo &gt; should populate data from flat EP MCP response format (no committee wrapper)" time="0.000686028">
            <system-out>
  ✅ Committee info: ENVI Committee (88 members)

            </system-out>
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="committee-reports helpers &gt; applyCommitteeInfo &gt; should fall back to parameter abbreviation when response has org/-prefixed abbreviation" time="0.000452461">
            <system-out>
  ✅ Committee info: ENVI Committee (0 members)

            </system-out>
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="committee-reports helpers &gt; applyCommitteeInfo &gt; should compute memberCount from members array length in flat format" time="0.000361335">
            <system-out>
  ✅ Committee info: ENVI Committee (3 members)

            </system-out>
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="committee-reports helpers &gt; applyCommitteeInfo &gt; should set chair to PLACEHOLDER_CHAIR when flat format has empty chair string" time="0.000299512">
            <system-out>
  ✅ Committee info: ENVI Committee (0 members)

            </system-out>
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="committee-reports helpers &gt; applyCommitteeInfo &gt; should ignore flat format when both name and abbreviation are absent" time="0.000248083">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="committee-reports helpers &gt; applyDocuments &gt; should map documents using d.type field" time="0.002088397">
            <system-out>
  ✅ Fetched 1 documents from MCP

            </system-out>
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="committee-reports helpers &gt; applyDocuments &gt; should fall back to documentType when type is absent" time="0.000333659">
            <system-out>
  ✅ Fetched 1 documents from MCP

            </system-out>
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="committee-reports helpers &gt; applyDocuments &gt; should use &quot;Document&quot; when both type and documentType are absent" time="0.000441938">
            <system-out>
  ✅ Fetched 1 documents from MCP

            </system-out>
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="committee-reports helpers &gt; applyDocuments &gt; should leave documents empty when response has no documents array" time="0.000294126">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="committee-reports helpers &gt; applyDocuments &gt; should degrade gracefully on invalid JSON" time="0.000398422">
            <system-err>
  ⚠️ Failed to parse documents: Expected property name or &apos;}&apos; in JSON at position 1 (line 1 column 2)

            </system-err>
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="committee-reports helpers &gt; applyDocuments &gt; should populate documents from EP MCP data[] response format" time="0.000512502">
            <system-out>
  ✅ Fetched 2 documents from MCP

            </system-out>
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="committee-reports helpers &gt; applyEffectiveness &gt; should format effectiveness score as string" time="0.000341975">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="committee-reports helpers &gt; applyEffectiveness &gt; should trim trailing whitespace when rank is empty" time="0.000205269">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="committee-reports helpers &gt; applyEffectiveness &gt; should set effectiveness to null for non-number score" time="0.000216302">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="committee-reports helpers &gt; applyEffectiveness &gt; should set effectiveness to null for NaN score" time="0.000194225">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="committee-reports helpers &gt; applyEffectiveness &gt; should leave effectiveness null when effectiveness key is absent" time="0.000159041">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="committee-reports helpers &gt; applyEffectiveness &gt; should degrade gracefully on invalid JSON" time="0.000292717">
            <system-err>
  ⚠️ Failed to parse effectiveness: Unexpected token &apos;o&apos;, &quot;not-json&quot; is not valid JSON

            </system-err>
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="isPlaceholderCommitteeData &gt; returns true when all committees have chair=N/A, members=0, docs=[]" time="0.000273957">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="isPlaceholderCommitteeData &gt; returns false for an empty array" time="0.00022143">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="isPlaceholderCommitteeData &gt; returns false when at least one committee has a real chair" time="0.000196965">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="isPlaceholderCommitteeData &gt; returns false when at least one committee has members &gt; 0" time="0.000167499">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="isPlaceholderCommitteeData &gt; returns false when at least one committee has documents" time="0.000197269">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="isPlaceholderCommitteeData &gt; returns false for a single committee with real data" time="0.000197016">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="categorizeAdoptedText &gt; AFET precedence (guards against AGRI false-positives, checked after LIBE) &gt; classifies &quot;Post-election situation in Uganda and threats against opposition leader Bobi Wine&quot; as AFET not AGRI" time="0.000296826">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="categorizeAdoptedText &gt; AFET precedence (guards against AGRI false-positives, checked after LIBE) &gt; classifies &quot;Post-election situation&quot; as AFET" time="0.000165798">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="categorizeAdoptedText &gt; AFET precedence (guards against AGRI false-positives, checked after LIBE) &gt; classifies &quot;threats against opposition leader&quot; as AFET" time="0.000172048">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="categorizeAdoptedText &gt; AFET precedence (guards against AGRI false-positives, checked after LIBE) &gt; classifies &quot;Ukraine Support Loan 2026&quot; as AFET" time="0.000174598">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="categorizeAdoptedText &gt; AFET precedence (guards against AGRI false-positives, checked after LIBE) &gt; classifies &quot;EU strategic defence partnerships&quot; as AFET" time="0.000192872">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="categorizeAdoptedText &gt; LIBE precedence (checked before AFET) &gt; classifies &quot;Safe countries of origin list&quot; as LIBE" time="0.000253815">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="categorizeAdoptedText &gt; LIBE precedence (checked before AFET) &gt; classifies &quot;Safe third country concept&quot; as LIBE" time="0.000170189">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="categorizeAdoptedText &gt; LIBE precedence (checked before AFET) &gt; classifies &quot;Human rights defenders&quot; as LIBE" time="0.000200634">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="categorizeAdoptedText &gt; LIBE precedence (checked before AFET) &gt; classifies human trafficking title mentioning Ukraine as LIBE not AFET" time="0.000126844">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="categorizeAdoptedText &gt; AGRI matches (no AFET/LIBE keywords present) &gt; classifies &quot;EU-Mercosur safeguard clause&quot; as AGRI" time="0.000168617">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="categorizeAdoptedText &gt; AGRI matches (no AFET/LIBE keywords present) &gt; classifies &quot;Agri-food supply chain enforcement&quot; as AGRI" time="0.00016001">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="categorizeAdoptedText &gt; AGRI matches (no AFET/LIBE keywords present) &gt; classifies &quot;Rural development fund&quot; as AGRI" time="0.000168776">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="categorizeAdoptedText &gt; AGRI matches (no AFET/LIBE keywords present) &gt; classifies &quot;wine&quot; keyword alone as AGRI when no AFET/LIBE match" time="0.0002169">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="categorizeAdoptedText &gt; AGRI matches (no AFET/LIBE keywords present) &gt; classifies fisheries-related title as AGRI" time="0.00017306">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="categorizeAdoptedText &gt; ENVI matches &gt; classifies &quot;GMO soybean DBN-09004-6&quot; as ENVI" time="0.00018673">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="categorizeAdoptedText &gt; ENVI matches &gt; classifies &quot;climate targets&quot; as ENVI" time="0.000332336">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="categorizeAdoptedText &gt; ENVI matches &gt; classifies emission-related title as ENVI" time="0.000193911">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="categorizeAdoptedText &gt; ECON matches &gt; classifies &quot;ECB Vice-President appointment&quot; as ECON (central bank keyword)" time="0.000208068">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="categorizeAdoptedText &gt; ECON matches &gt; classifies &quot;European Semester 2026&quot; as ECON" time="0.000145604">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="categorizeAdoptedText &gt; OTHER fallback &gt; classifies unmatched titles as OTHER" time="0.000156745">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="categorizeAdoptedText &gt; OTHER fallback &gt; classifies empty string as OTHER" time="0.000154984">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="categorizeAdoptedText &gt; keyword arrays are pre-normalized to lowercase &gt; AFET_KEYWORDS contains only lowercase strings" time="0.000572761">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="categorizeAdoptedText &gt; keyword arrays are pre-normalized to lowercase &gt; LIBE_KEYWORDS contains only lowercase strings" time="0.000503609">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="categorizeAdoptedText &gt; keyword arrays are pre-normalized to lowercase &gt; AGRI_KEYWORDS contains only lowercase strings" time="0.000409893">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="categorizeAdoptedText &gt; keyword arrays are pre-normalized to lowercase &gt; ENVI_KEYWORDS contains only lowercase strings" time="0.000555245">
        </testcase>
        <testcase classname="test/unit/committee-reports.test.js" name="categorizeAdoptedText &gt; keyword arrays are pre-normalized to lowercase &gt; ECON_KEYWORDS contains only lowercase strings" time="0.000332578">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/content-metadata.test.js" timestamp="2026-04-14T20:47:06.430Z" hostname="runnervm35a4x" tests="15" failures="0" errors="0" skipped="0" time="0.015039736">
        <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.005679424">
        </testcase>
        <testcase classname="test/unit/content-metadata.test.js" name="content-metadata &gt; enrichMetadataFromContent &gt; should use lede paragraph as description" time="0.000971656">
        </testcase>
        <testcase classname="test/unit/content-metadata.test.js" name="content-metadata &gt; enrichMetadataFromContent &gt; should use section lede paragraph as description" time="0.000407764">
        </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.000705315">
        </testcase>
        <testcase classname="test/unit/content-metadata.test.js" name="content-metadata &gt; enrichMetadataFromContent &gt; should extract committee abbreviations as keywords" time="0.000954648">
        </testcase>
        <testcase classname="test/unit/content-metadata.test.js" name="content-metadata &gt; enrichMetadataFromContent &gt; should extract political group names as keywords" time="0.000699252">
        </testcase>
        <testcase classname="test/unit/content-metadata.test.js" name="content-metadata &gt; enrichMetadataFromContent &gt; should extract headings as keywords" time="0.000257404">
        </testcase>
        <testcase classname="test/unit/content-metadata.test.js" name="content-metadata &gt; enrichMetadataFromContent &gt; should extract headings with nested markup" time="0.000369216">
        </testcase>
        <testcase classname="test/unit/content-metadata.test.js" name="content-metadata &gt; enrichMetadataFromContent &gt; should preserve base keywords" time="0.000638549">
        </testcase>
        <testcase classname="test/unit/content-metadata.test.js" name="content-metadata &gt; enrichMetadataFromContent &gt; should preserve base category" time="0.00023469">
        </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.000185905">
        </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.000285216">
        </testcase>
        <testcase classname="test/unit/content-metadata.test.js" name="content-metadata &gt; enrichMetadataFromContent &gt; should limit description to 200 characters" time="0.000411627">
        </testcase>
        <testcase classname="test/unit/content-metadata.test.js" name="content-metadata &gt; enrichMetadataFromContent &gt; should limit keywords to 15" time="0.000246006">
        </testcase>
        <testcase classname="test/unit/content-metadata.test.js" name="content-metadata &gt; enrichMetadataFromContent &gt; should deduplicate keywords" time="0.00014461">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/content-validator.test.js" timestamp="2026-04-14T20:47:06.431Z" hostname="runnervm35a4x" tests="72" failures="0" errors="0" skipped="0" time="0.057501911">
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; valid content &gt; should return valid=true for well-formed article meeting word count" time="0.009326258">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; valid content &gt; should pass for breaking-news with 300 words" time="0.000839914">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; valid content &gt; should pass for monthly-review with 600 words" time="0.000746215">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; valid content &gt; should pass for unknown article type using default threshold" time="0.000541558">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; too-short content (warn) &gt; should warn when week-ahead article has fewer than 500 words" time="0.00096286">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; too-short content (warn) &gt; should warn when committee-reports article has fewer than 400 words" time="0.000459433">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; too-short content (warn) &gt; should include word count in warning message" time="0.000475177">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; placeholder text detection (fail) &gt; should fail when {{mustache}} placeholders are present" time="0.0008438">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; placeholder text detection (fail) &gt; should fail when [TODO] markers are present" time="0.000895527">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; placeholder text detection (fail) &gt; should fail when PLACEHOLDER word is present" time="0.000949709">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; placeholder text detection (fail) &gt; should fail for case-insensitive [todo] marker" time="0.000735379">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; missing required HTML elements (fail) &gt; should fail when language switcher is missing" time="0.001099771">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; missing required HTML elements (fail) &gt; should fail when article-top-nav is missing" time="0.000660511">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; missing required HTML elements (fail) &gt; should fail when site-header is missing" time="0.000678911">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; missing required HTML elements (fail) &gt; should fail when main content wrapper is missing" time="0.000687578">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; missing required HTML elements (fail) &gt; should list all missing elements in the error" time="0.000702706">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; language attribute validation &gt; should pass when lang attribute matches expected language" time="0.000679614">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; language attribute validation &gt; should warn when lang attribute does not match expected language" time="0.000742576">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; language attribute validation &gt; should warn when lang attribute is missing" time="0.00069455">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; RTL direction validation &gt; should pass for Arabic with dir=&quot;rtl&quot;" time="0.000747093">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; RTL direction validation &gt; should pass for Hebrew with dir=&quot;rtl&quot;" time="0.000779616">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; RTL direction validation &gt; should warn for Arabic without dir=&quot;rtl&quot;" time="0.00090761">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; RTL direction validation &gt; should pass for LTR language with dir=&quot;ltr&quot;" time="0.000777957">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; read-time validation &gt; should compute correct read-time from word count" time="0.000826558">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; read-time validation &gt; should warn when claimed read-time is significantly wrong" time="0.001133129">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; read-time validation &gt; should not warn when claimed read-time is close enough" time="0.000537372">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; meta tag synchronization &gt; should pass when all meta tags are synchronized" time="0.000850363">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; meta tag synchronization &gt; should warn when og:title mismatches page title" time="0.00058322">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; meta tag synchronization &gt; should warn when og:description mismatches description" time="0.000493489">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; keyword localization &gt; should pass for English articles with English keywords" time="0.000493972">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; keyword localization &gt; should warn for German article with entirely English keywords" time="0.0005763">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; keyword localization &gt; should pass for German article with localized keywords" time="0.000648825">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; keyword localization &gt; should pass for Japanese article with localized keywords" time="0.001237424">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; keyword localization &gt; should warn for Arabic article with English-only keywords" time="0.00052046">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; keyword localization &gt; should pass when no keywords meta tag is present" time="0.00097104">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; metrics &gt; should report word count in metrics" time="0.000805008">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; metrics &gt; should report htmlValid=true when all elements present" time="0.000770728">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; metrics &gt; should report hasPlaceholders=false for clean content" time="0.000754163">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateArticleContent &gt; metrics &gt; should include all new metrics fields" time="0.001138896">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateTranslationCompleteness &gt; English (source language) &gt; should return valid=true and skip all checks for English" time="0.001231407">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateTranslationCompleteness &gt; RTL validation (ar, he) &gt; should pass for Arabic article with dir=&quot;rtl&quot;" time="0.000430889">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateTranslationCompleteness &gt; RTL validation (ar, he) &gt; should warn for Arabic article with dir=&quot;ltr&quot; instead of dir=&quot;rtl&quot;" time="0.000255925">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateTranslationCompleteness &gt; RTL validation (ar, he) &gt; should warn for Arabic article with missing dir attribute" time="0.000218906">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateTranslationCompleteness &gt; RTL validation (ar, he) &gt; should pass for Hebrew article with dir=&quot;rtl&quot;" time="0.000197766">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateTranslationCompleteness &gt; RTL validation (ar, he) &gt; should warn for Hebrew article with dir=&quot;ltr&quot; instead of dir=&quot;rtl&quot;" time="0.000293094">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateTranslationCompleteness &gt; CJK density detection (ja, ko, zh) &gt; should pass for Japanese article with actual Japanese content" time="0.000561575">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateTranslationCompleteness &gt; CJK density detection (ja, ko, zh) &gt; should warn for Japanese article with mostly ASCII (untranslated)" time="0.000578054">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateTranslationCompleteness &gt; CJK density detection (ja, ko, zh) &gt; should pass for Korean article with actual Korean content" time="0.000457686">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateTranslationCompleteness &gt; CJK density detection (ja, ko, zh) &gt; should warn for Korean article with only English content" time="0.000678389">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateTranslationCompleteness &gt; CJK density detection (ja, ko, zh) &gt; should pass for Chinese article with actual Chinese content" time="0.000416267">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateTranslationCompleteness &gt; CJK density detection (ja, ko, zh) &gt; should warn for Chinese article with only English content" time="0.00044454">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateTranslationCompleteness &gt; CJK density detection (ja, ko, zh) &gt; should not false-positive on CJK content with numeric HTML entities" time="0.000311463">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateTranslationCompleteness &gt; untranslated English phrase detection &gt; should warn when &quot;European Parliament&quot; appears in non-English article" time="0.000500812">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateTranslationCompleteness &gt; untranslated English phrase detection &gt; should warn when &quot;Read more&quot; appears in non-English article" time="0.000210852">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateTranslationCompleteness &gt; untranslated English phrase detection &gt; should not warn when no English phrases are found" time="0.000314013">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateTranslationCompleteness &gt; untranslated English phrase detection &gt; should detect multiple untranslated phrases" time="0.000216484">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateTranslationCompleteness &gt; edge cases &gt; should handle empty content gracefully" time="0.004886693">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateTranslationCompleteness &gt; edge cases &gt; should handle mixed-language articles" time="0.000294499">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateTranslationCompleteness &gt; edge cases &gt; should not flag non-CJK non-RTL languages for script density" time="0.000313093">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="utils/content-validator &gt; validateTranslationCompleteness &gt; edge cases &gt; should include all metrics fields" time="0.000439428">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="validateCrossReferenceDensity &gt; should return null when enough EP references are present" time="0.00021038">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="validateCrossReferenceDensity &gt; should warn when fewer than minimum references found" time="0.000131268">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="validateCrossReferenceDensity &gt; should count procedure references" time="0.000120895">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="validateCrossReferenceDensity &gt; should not count references inside script blocks" time="0.000126573">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="validateCrossReferenceDensity &gt; should respect custom minRefs parameter" time="0.000146918">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="validateStakeholderGroupBalance &gt; should return null for balanced group mentions" time="0.00022321">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="validateStakeholderGroupBalance &gt; should warn when a single group dominates" time="0.000218774">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="validateStakeholderGroupBalance &gt; should return null for too few mentions to assess" time="0.000160003">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="validateTemporalCoverage &gt; should return null when forward-looking content is present" time="0.000110354">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="validateTemporalCoverage &gt; should warn when no forward-looking language is found" time="0.000104859">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="validateTemporalCoverage &gt; should detect &quot;will&quot; with word boundary (not matching &quot;William&quot;)" time="0.000163134">
        </testcase>
        <testcase classname="test/unit/content-validator.test.js" name="validateTemporalCoverage &gt; should match &quot;expected&quot; as forward-looking" time="0.000110598">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/dashboard-content.test.js" timestamp="2026-04-14T20:47:06.439Z" hostname="runnervm35a4x" tests="102" failures="0" errors="0" skipped="0" time="0.048919802">
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; buildDashboardSection &gt; should return empty string for null input" time="0.010127157">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; buildDashboardSection &gt; should return empty string for undefined input" time="0.000280417">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; buildDashboardSection &gt; should return empty string for dashboard with no panels" time="0.000274971">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; buildDashboardSection &gt; should generate valid dashboard HTML with panels" time="0.001278807">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; buildDashboardSection &gt; should include dashboard title in heading" time="0.000378645">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; buildDashboardSection &gt; should use custom heading when provided" time="0.000360718">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; buildDashboardSection &gt; should default heading to &quot;Dashboard&quot; when no title or heading" time="0.0003222">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; buildDashboardSection &gt; should render metric cards with labels and values" time="0.000520897">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; buildDashboardSection &gt; should render trend indicators" time="0.00057079">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; buildDashboardSection &gt; should render change percentages" time="0.000380121">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; buildDashboardSection &gt; should render metric units when provided" time="0.000624548">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; buildDashboardSection &gt; should render chart containers with canvas elements" time="0.000426389">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; buildDashboardSection &gt; should include chart title" time="0.000323944">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; buildDashboardSection &gt; should embed chart configuration as escaped JSON" time="0.00035961">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; buildDashboardSection &gt; should include noscript fallback table" time="0.000763198">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; buildDashboardSection &gt; should include accessible category column header in fallback table" time="0.000342066">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; buildDashboardSection &gt; should escape HTML in metric values" time="0.000407361">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; buildDashboardSection &gt; should include accessible ARIA attributes" time="0.000374044">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; buildDashboardSection &gt; should render metrics-only panels without chart container" time="0.000226559">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; buildDashboardSection &gt; should render chart-only panels without metrics grid" time="0.00033452">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; buildDashboardSection &gt; should generate unique canvas IDs per panel" time="0.000495227">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; buildDashboardSection &gt; should generate distinct canvas IDs for multi-chart dashboards" time="0.000393011">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; buildDashboardSection &gt; should render multiple panels" time="0.000418889">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; buildDashboardSection &gt; should skip empty panels" time="0.00040342">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; buildDashboardSection &gt; should localize section heading when lang is provided" time="0.000236044">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; buildDashboardSection &gt; should localize trend prefix in aria-label" time="0.000332046">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; buildDashboardSection &gt; should not include raw trend enum value in aria-label" time="0.000442765">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; buildDashboardSection &gt; should localize no-data message in fallback" time="0.000323892">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; dashboardHasCharts &gt; should return false for null input" time="0.000300416">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; dashboardHasCharts &gt; should return false for undefined input" time="0.000190729">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; dashboardHasCharts &gt; should return true when dashboard has charts" time="0.000195443">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; dashboardHasCharts &gt; should return false when dashboard has no charts" time="0.000290149">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; dashboardHasCharts &gt; should return true for chart-only dashboard" time="0.000201069">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; extended chart types &gt; should render polarArea chart config as data attribute" time="0.000377007">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; extended chart types &gt; should render scatter chart config as data attribute" time="0.000360502">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="dashboard-content &gt; extended chart types &gt; should render bubble chart config as data attribute" time="0.000292109">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildCoalitionPanel &gt; should return empty string for null coalition" time="0.000374221">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildCoalitionPanel &gt; should return empty string for undefined coalition" time="0.000169596">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildCoalitionPanel &gt; should return empty string for coalition with no blocs" time="0.000277168">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildCoalitionPanel &gt; should render coalition panel with alignment score" time="0.000617255">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildCoalitionPanel &gt; should render voting blocs count" time="0.000246039">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildCoalitionPanel &gt; should render shift indicator as strengthening" time="0.000287588">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildCoalitionPanel &gt; should render shift indicator as weakening" time="0.000240514">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildCoalitionPanel &gt; should render shift indicator as stable" time="0.000279704">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildCoalitionPanel &gt; should embed radar chart configuration as JSON data attribute" time="0.000401826">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildCoalitionPanel &gt; should include noscript fallback table with blocs" time="0.000372262">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildCoalitionPanel &gt; should include accessible ARIA attributes" time="0.000274333">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildCoalitionPanel &gt; should generate unique canvas ID using panelIndex" time="0.000421895">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildCoalitionPanel &gt; should escape HTML in group names" time="0.000228626">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildCoalitionPanel &gt; should localize labels when lang is provided" time="0.000185106">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildPipelinePanel &gt; should return empty string for null pipeline" time="0.000237683">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildPipelinePanel &gt; should return empty string for undefined pipeline" time="0.000159074">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildPipelinePanel &gt; should return empty string for pipeline with zero total" time="0.000333489">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildPipelinePanel &gt; should render pipeline panel with health score" time="0.000263252">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildPipelinePanel &gt; should render on-track, delayed, blocked, fast-tracked counts" time="0.000212929">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildPipelinePanel &gt; should apply healthy CSS class for high health score" time="0.00012498">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildPipelinePanel &gt; should apply moderate CSS class for mid-range health score" time="0.000213297">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildPipelinePanel &gt; should apply critical CSS class for low health score" time="0.000157564">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildPipelinePanel &gt; should embed bar chart configuration as JSON data attribute" time="0.000165942">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildPipelinePanel &gt; should include noscript fallback list" time="0.000194879">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildPipelinePanel &gt; should include accessible ARIA attributes" time="0.000356193">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildPipelinePanel &gt; should generate unique canvas ID using panelIndex" time="0.000244017">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildPipelinePanel &gt; should localize labels when lang is provided" time="0.000160382">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildTrendPanel &gt; should return empty string for null trend" time="0.000245604">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildTrendPanel &gt; should return empty string for undefined trend" time="0.00013797">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildTrendPanel &gt; should return empty string for trend with no metrics" time="0.000142026">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildTrendPanel &gt; should render trend panel with direction label" time="0.000260247">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildTrendPanel &gt; should render declining direction" time="0.000186952">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildTrendPanel &gt; should render stable direction" time="0.00021063">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildTrendPanel &gt; should render week-over-week change when provided" time="0.000173272">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildTrendPanel &gt; should render month-over-month change when provided" time="0.000189661">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildTrendPanel &gt; should embed line chart configuration as JSON data attribute" time="0.000207642">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildTrendPanel &gt; should include noscript fallback table with period data" time="0.000187033">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildTrendPanel &gt; should include accessible ARIA attributes" time="0.000249724">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildTrendPanel &gt; should generate unique canvas ID using panelIndex" time="0.000239699">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildTrendPanel &gt; should localize labels when lang is provided" time="0.000179192">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildTrendPanel &gt; should not render week-over-week when undefined" time="0.000165452">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildStakeholderScorecardPanel &gt; should return empty string for null stakeholders" time="0.000225649">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildStakeholderScorecardPanel &gt; should return empty string for undefined stakeholders" time="0.000198566">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildStakeholderScorecardPanel &gt; should return empty string for empty stakeholders array" time="0.000248048">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildStakeholderScorecardPanel &gt; should render stakeholder scorecard panel" time="0.00053952">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildStakeholderScorecardPanel &gt; should render all stakeholder names" time="0.000266099">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildStakeholderScorecardPanel &gt; should render impact scores" time="0.000303423">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildStakeholderScorecardPanel &gt; should apply positive CSS class for positive impact" time="0.000265567">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildStakeholderScorecardPanel &gt; should apply negative CSS class for negative impact" time="0.000620536">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildStakeholderScorecardPanel &gt; should apply neutral CSS class for neutral impact" time="0.000161504">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildStakeholderScorecardPanel &gt; should render direction labels (Positive, Negative, Neutral)" time="0.000236516">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildStakeholderScorecardPanel &gt; should render description when provided" time="0.000192928">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildStakeholderScorecardPanel &gt; should include noscript fallback table" time="0.000448722">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildStakeholderScorecardPanel &gt; should include accessible ARIA attributes" time="0.000371417">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildStakeholderScorecardPanel &gt; should generate unique ID using panelIndex" time="0.000362347">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildStakeholderScorecardPanel &gt; should escape HTML in stakeholder names" time="0.000439584">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildStakeholderScorecardPanel &gt; should localize labels when lang is provided" time="0.000280312">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildStakeholderScorecardPanel &gt; should render stakeholder-grid with list role" time="0.000305299">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildEconomicContextPanel &gt; should return null for null context" time="0.000242938">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildEconomicContextPanel &gt; should return null for undefined context" time="0.000145398">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildEconomicContextPanel &gt; should return null when indicators array is empty" time="0.000110022">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildEconomicContextPanel &gt; should return null when all indicator values are null" time="0.000265106">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildEconomicContextPanel &gt; should return a panel with metrics and chart for valid data" time="0.002890251">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildEconomicContextPanel &gt; should limit metrics to 6 indicators max" time="0.000560548">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildEconomicContextPanel &gt; should filter out NaN and Infinity indicator values" time="0.000625602">
        </testcase>
        <testcase classname="test/unit/dashboard-content.test.js" name="buildEconomicContextPanel &gt; should return null when all indicator values are non-finite" time="0.000200138">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/deep-analysis.test.js" timestamp="2026-04-14T20:47:06.453Z" hostname="runnervm35a4x" tests="148" failures="0" errors="0" skipped="0" time="0.09644135">
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should return empty string for null analysis" time="0.003992628">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should return empty string for undefined analysis" time="0.00147841">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should produce a section with class deep-analysis" time="0.001630558">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should include all 5W headings" time="0.000711824">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should include stakeholder section with winners and losers" time="0.000859436">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should include impact grid with all 5 perspectives" time="0.000569458">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should include consequences table" time="0.000498704">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should include mistakes section" time="0.00039426">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should include outlook section" time="0.0004269">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should escape HTML in actor names" time="0.000491876">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should produce localized headings for German" time="0.000342244">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should produce localized headings for Swedish" time="0.000338619">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should produce localized headings for French" time="0.000339592">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should produce localized headings for Japanese" time="0.000248119">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should handle analysis with empty arrays gracefully" time="0.000257455">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should fall back to English for unknown language" time="0.000297095">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should render EnhancedDeepAnalysis with executive summary section" time="0.001059758">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should render executive summary before What section" time="0.001067478">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should render confidence badge for high confidence" time="0.000734332">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should render confidence badge for medium confidence" time="0.000873442">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should render confidence badge for low confidence" time="0.000394371">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should render reasoning chains section after Why" time="0.000438855">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should render reasoning chain with premise, inference and conclusion" time="0.001136919">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should render evidence reference with hyperlink when URL present" time="0.000664072">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should render counter-arguments list" time="0.000760932">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should render scenario planning section after Outlook" time="0.00729745">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should render all three scenario cards" time="0.000478636">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should render probability bars with correct values" time="0.000643408">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should render wildcards list" time="0.00045082">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should render analysis methodology section last" time="0.000446065">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should render iteration timeline with pass details" time="0.000491006">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should render methodology stats in dl element" time="0.000432011">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should handle EnhancedDeepAnalysis with zero iterations gracefully" time="0.000392613">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should fall back gracefully when optional enhanced fields are undefined" time="0.000505941">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should escape HTML in enhanced analysis content" time="0.000613427">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should reject unsafe URLs (javascript: scheme) in evidence references" time="0.000473002">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should reject unsafe URLs (data: scheme) in evidence references" time="0.000417018">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should render safe https URLs as hyperlinks with target=&quot;_blank&quot;" time="0.000341285">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should clamp probability bar to 0-100 range" time="0.000479493">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should include aria-label on probability bars for accessibility" time="0.000500489">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should use overallConfidenceLabel (not section heading) as dt in methodology dl" time="0.001212798">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should use h4 (not h5) for evidence and counter-argument headings" time="0.000473912">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should not add lang attribute to content elements (AI translates all content)" time="0.000472427">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should handle NaN probability gracefully" time="0.000437596">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should handle Infinity probability gracefully" time="0.000739809">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep-analysis-content &gt; buildDeepAnalysisSection &gt; should not check comparativeContext in type guard" time="0.000442801">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildVotingAnalysis &gt; should produce a complete DeepAnalysis from voting data" time="0.001643054">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildVotingAnalysis &gt; should identify high-cohesion groups as winners" time="0.000373725">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildVotingAnalysis &gt; should identify low-cohesion groups as losers" time="0.00037686">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildVotingAnalysis &gt; should derive consequences from voting records" time="0.000587307">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildVotingAnalysis &gt; should derive mistakes from high-severity anomalies" time="0.000331212">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildVotingAnalysis &gt; should include anomaly count in the &quot;what&quot; field" time="0.000321303">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildVotingAnalysis &gt; should handle empty data gracefully" time="0.000715538">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildVotingAnalysis &gt; should exclude placeholder records from actionConsequences" time="0.000425827">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildVotingAnalysis &gt; should exclude placeholder anomalies from actionConsequences" time="0.009852528">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildVotingAnalysis &gt; should include voting intensity metrics in &quot;what&quot; when records have vote data" time="0.000288731">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildVotingAnalysis &gt; should use AI_MARKER for &quot;why&quot; text (AI-driven analysis)" time="0.00028085">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildVotingAnalysis &gt; should use AI_MARKER for stakeholder outcome reasons (AI-driven analysis)" time="0.000286099">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildVotingAnalysis &gt; should use AI_MARKER for political impact (AI-driven analysis)" time="0.000220496">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildVotingAnalysis &gt; should use AI_MARKER for outlook (AI-driven analysis)" time="0.000219194">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildProspectiveAnalysis &gt; should produce a complete DeepAnalysis from week-ahead data" time="0.000824493">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildProspectiveAnalysis &gt; should use AI_MARKER for &quot;why&quot; in prospective analysis" time="0.000271598">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildProspectiveAnalysis &gt; should include events in timeline" time="0.000205031">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildProspectiveAnalysis &gt; should produce month label when appropriate" time="0.000182233">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildProspectiveAnalysis &gt; should handle empty data gracefully" time="0.000291125">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildBreakingAnalysis &gt; should produce analysis from feed data" time="0.001548927">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildBreakingAnalysis &gt; should use AI_MARKER for why in breaking news (AI-driven analysis)" time="0.000179142">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildBreakingAnalysis &gt; should handle undefined feedData" time="0.000202773">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildBreakingAnalysis &gt; should produce consequences from adopted texts" time="0.000252596">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildBreakingAnalysis &gt; should include publish dates in all feed item references" time="0.000475255">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildPropositionsAnalysis &gt; should produce analysis from pipeline data" time="0.00060083">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildPropositionsAnalysis &gt; should use AI_MARKER for why in propositions" time="0.000269006">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildPropositionsAnalysis &gt; should mark high health as winner" time="0.000264293">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildPropositionsAnalysis &gt; should use AI_MARKER for outlook in propositions" time="0.000179588">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildPropositionsAnalysis &gt; should keep factual what when no proposals detected" time="0.000244035">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildPropositionsAnalysis &gt; should detect proposals from adoptedTextsHtml when proposalsHtml is empty" time="0.000195259">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildCommitteeAnalysis &gt; should produce analysis from committee data" time="0.000936447">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildCommitteeAnalysis &gt; should include committee names in who" time="0.000316262">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildCommitteeAnalysis &gt; should label active committees as winners" time="0.000226769">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildCommitteeAnalysis &gt; should generate data-driven descriptions for inactive committee mistakes" time="0.000275269">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildCommitteeAnalysis &gt; should use AI_MARKER for why in committee analysis" time="0.000253432">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildCommitteeAnalysis &gt; should use AI_MARKER for impact in committee analysis" time="0.000238325">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildCommitteeAnalysis &gt; should handle empty committee list" time="0.000268781">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildCommitteeAnalysis &gt; should use whatNoData when no documents are available" time="0.000326402">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="analysis-builders &gt; buildCommitteeAnalysis &gt; should return null when all committees are placeholder (chair=N/A, members=0, docs=[])" time="0.00025509">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep analysis integration &gt; should produce valid HTML when fed buildVotingAnalysis output" time="0.001086785">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep analysis integration &gt; should produce valid HTML when fed buildProspectiveAnalysis output" time="0.000495539">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep analysis integration &gt; should produce valid HTML when fed buildPropositionsAnalysis output" time="0.000415232">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep analysis integration &gt; should produce valid HTML when fed buildCommitteeAnalysis output" time="0.000400084">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="deep analysis integration &gt; should work across all 14 supported languages" time="0.003797805">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="SWOT builders &gt; buildVotingSwot &gt; returns a valid SwotAnalysis without hardcoded title (uses localized heading)" time="0.000813117">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="SWOT builders &gt; buildVotingSwot &gt; includes high-cohesion groups in strengths" time="0.000244509">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="SWOT builders &gt; buildVotingSwot &gt; includes anomalies in weaknesses" time="0.000225093">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="SWOT builders &gt; buildVotingSwot &gt; handles empty inputs gracefully" time="0.000308439">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="SWOT builders &gt; buildProspectiveSwot &gt; returns a valid SwotAnalysis without hardcoded title" time="0.00049811">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="SWOT builders &gt; buildProspectiveSwot &gt; includes bottleneck risk in weaknesses" time="0.000251183">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="SWOT builders &gt; buildBreakingSwot &gt; returns a valid SwotAnalysis with adopted texts as strengths" time="0.000489672">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="SWOT builders &gt; buildBreakingSwot &gt; handles undefined feedData" time="0.000185116">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="SWOT builders &gt; buildPropositionsSwot &gt; returns healthy pipeline as strength" time="0.000460345">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="SWOT builders &gt; buildPropositionsSwot &gt; returns unhealthy pipeline as weakness" time="0.000272941">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="SWOT builders &gt; buildPropositionsSwot &gt; handles null pipeline data" time="0.000183019">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="SWOT builders &gt; buildCommitteeSwot &gt; returns active committees as strengths" time="0.000467607">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="SWOT builders &gt; buildCommitteeSwot &gt; identifies inactive committees as weaknesses" time="0.000237139">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="SWOT builders &gt; buildCommitteeSwot &gt; returns null when all committees are placeholder (chair=N/A, members=0, docs=[])" time="0.000360694">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="Dashboard builders &gt; buildVotingDashboard &gt; returns a valid DashboardConfig with panels (no hardcoded title)" time="0.001587058">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="Dashboard builders &gt; buildVotingDashboard &gt; includes voting overview metrics" time="0.000282803">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="Dashboard builders &gt; buildVotingDashboard &gt; includes cohesion chart when patterns available" time="0.000357673">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="Dashboard builders &gt; buildVotingDashboard &gt; handles empty inputs" time="0.000169362">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="Dashboard builders &gt; buildProspectiveDashboard &gt; returns panels with scheduled activity metrics (no hardcoded title)" time="0.000833904">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="Dashboard builders &gt; buildBreakingDashboard &gt; returns panels with feed activity metrics" time="0.000524703">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="Dashboard builders &gt; buildBreakingDashboard &gt; handles undefined feedData" time="0.000168802">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="Dashboard builders &gt; buildPropositionsDashboard &gt; returns pipeline health metrics" time="0.0006817">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="Dashboard builders &gt; buildPropositionsDashboard &gt; handles null pipeline data" time="0.000226462">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="Dashboard builders &gt; buildCommitteeDashboard &gt; returns committee overview and chart (no hardcoded title)" time="0.000702664">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="Dashboard builders &gt; buildCommitteeDashboard &gt; handles empty committee list" time="0.000119729">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="Dashboard builders &gt; buildCommitteeDashboard &gt; returns null when all committees are placeholder (chair=N/A, members=0, docs=[])" time="0.000103179">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="Multi-stakeholder perspectives in analysis builders &gt; buildVotingAnalysis — stakeholder fields &gt; should populate stakeholderPerspectives with 6 entries" time="0.000983427">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="Multi-stakeholder perspectives in analysis builders &gt; buildVotingAnalysis — stakeholder fields &gt; should cover all 6 stakeholder types in perspectives" time="0.000619155">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="Multi-stakeholder perspectives in analysis builders &gt; buildVotingAnalysis — stakeholder fields &gt; should populate stakeholderOutcomeMatrix with at least 1 row" time="0.000206404">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="Multi-stakeholder perspectives in analysis builders &gt; buildVotingAnalysis — stakeholder fields &gt; should assign high confidence when records are present" time="0.000193014">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="Multi-stakeholder perspectives in analysis builders &gt; buildVotingAnalysis — stakeholder fields &gt; should assign low confidence when no real records" time="0.000153904">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="Multi-stakeholder perspectives in analysis builders &gt; buildVotingAnalysis — stakeholder fields &gt; stakeholderPerspectives should have valid impact and severity for each entry" time="0.00070514">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="Multi-stakeholder perspectives in analysis builders &gt; buildProspectiveAnalysis — stakeholder fields &gt; should populate stakeholderPerspectives with 6 entries" time="0.000253138">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="Multi-stakeholder perspectives in analysis builders &gt; buildProspectiveAnalysis — stakeholder fields &gt; should populate stakeholderOutcomeMatrix" time="0.000194272">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="Multi-stakeholder perspectives in analysis builders &gt; buildProspectiveAnalysis — stakeholder fields &gt; each matrix row should have all 6 stakeholder outcomes" time="0.00040713">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="Multi-stakeholder perspectives in analysis builders &gt; buildBreakingAnalysis — stakeholder fields &gt; should populate stakeholderPerspectives with 6 entries" time="0.000224543">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="Multi-stakeholder perspectives in analysis builders &gt; buildBreakingAnalysis — stakeholder fields &gt; should populate stakeholderOutcomeMatrix" time="0.00011917">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="Multi-stakeholder perspectives in analysis builders &gt; buildBreakingAnalysis — stakeholder fields &gt; should assign high confidence when adopted texts present" time="0.000177877">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="Multi-stakeholder perspectives in analysis builders &gt; buildPropositionsAnalysis — stakeholder fields &gt; should populate stakeholderPerspectives with 6 entries" time="0.000193128">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="Multi-stakeholder perspectives in analysis builders &gt; buildPropositionsAnalysis — stakeholder fields &gt; should populate stakeholderOutcomeMatrix" time="0.000115974">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="Multi-stakeholder perspectives in analysis builders &gt; buildPropositionsAnalysis — stakeholder fields &gt; should assign low confidence when pipelineData is null" time="0.000100559">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="Multi-stakeholder perspectives in analysis builders &gt; buildPropositionsAnalysis — stakeholder fields &gt; should reflect health score in stakeholder perspectives" time="0.000223319">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="Multi-stakeholder perspectives in analysis builders &gt; buildCommitteeAnalysis — stakeholder fields &gt; should populate stakeholderPerspectives with 6 entries for valid data" time="0.000254212">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="Multi-stakeholder perspectives in analysis builders &gt; buildCommitteeAnalysis — stakeholder fields &gt; should populate stakeholderOutcomeMatrix for valid data" time="0.000122257">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="Multi-stakeholder perspectives in analysis builders &gt; buildCommitteeAnalysis — stakeholder fields &gt; should return null for placeholder data (no perspective fields)" time="0.000079929">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="buildDeepAnalysisSection — multi-stakeholder HTML rendering &gt; should render stakeholder perspectives section" time="0.000185765">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="buildDeepAnalysisSection — multi-stakeholder HTML rendering &gt; should render stakeholder group names in perspectives" time="0.000165475">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="buildDeepAnalysisSection — multi-stakeholder HTML rendering &gt; should render impact badges in perspectives" time="0.000182013">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="buildDeepAnalysisSection — multi-stakeholder HTML rendering &gt; should render reasoning text" time="0.000219206">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="buildDeepAnalysisSection — multi-stakeholder HTML rendering &gt; should render evidence items" time="0.000178987">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="buildDeepAnalysisSection — multi-stakeholder HTML rendering &gt; should render stakeholder outcome matrix section" time="0.000446622">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="buildDeepAnalysisSection — multi-stakeholder HTML rendering &gt; should render the action in the matrix" time="0.000171643">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="buildDeepAnalysisSection — multi-stakeholder HTML rendering &gt; should render outcome cells in the matrix" time="0.000215961">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="buildDeepAnalysisSection — multi-stakeholder HTML rendering &gt; should render confidence in the matrix" time="0.000145937">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="buildDeepAnalysisSection — multi-stakeholder HTML rendering &gt; should not render perspectives section when field is absent" time="0.000121773">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="buildDeepAnalysisSection — multi-stakeholder HTML rendering &gt; should not render matrix section when field is absent" time="0.000116207">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="buildDeepAnalysisSection — multi-stakeholder HTML rendering &gt; should escape XSS in perspective reasoning" time="0.000182294">
        </testcase>
        <testcase classname="test/unit/deep-analysis.test.js" name="buildDeepAnalysisSection — multi-stakeholder HTML rendering &gt; should escape XSS in matrix action text" time="0.000179573">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/ep-mcp-client.test.js" timestamp="2026-04-14T20:47:06.470Z" hostname="runnervm35a4x" tests="209" failures="0" errors="0" skipped="0" time="0.640753832">
        <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.003694959">
        </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.000614888">
        </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.000428941">
        </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.000325071">
        </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.000411976">
        </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.000541776">
        </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.508024776">
        </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.000341673">
        </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.002462208">
        </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.001135668">
        </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.003250977">
        </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.000801824">
        </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.001874879">
        </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.000352009">
        </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.000347055">
        </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.001566662">
        </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.000313731">
        </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.000492641">
        </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.000510748">
        </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.000770695">
        </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.000608949">
        </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.000315158">
        </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.000473388">
        </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.000540068">
        </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.000443768">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should normalize dateFrom to startDate in getPlenarySessions" time="0.000284336">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should not overwrite startDate with dateFrom in getPlenarySessions" time="0.000377027">
        </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.001358382">
        </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.000542034">
        </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.003595091">
        </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.000496565">
        </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.00050707">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; EuropeanParliamentMCPClient &gt; European Parliament Data Methods &gt; should map dateFrom to startDate in getParliamentaryQuestions" time="0.000558611">
        </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.00040203">
        </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.001201981">
        </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.00041365">
        </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.000420909">
        </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.000399179">
        </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.001832904">
        </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.000480636">
        </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.00041582">
        </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.000896698">
        </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.000461867">
        </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.000385551">
        </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.000455359">
        </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.000777421">
        </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.000381341">
        </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.00036141">
        </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.000408107">
        </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.000379958">
        </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.000284833">
        </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.00021933">
        </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.000500297">
        </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.000423534">
        </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.000610551">
        </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.000418363">
        </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.000485279">
        </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.000393119">
        </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.000347108">
        </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.001477964">
        </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.000456687">
        </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.00040761">
        </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.000425512">
        </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.000522386">
        </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.000745337">
        </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.000364391">
        </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.000812344">
        </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.000449934">
        </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.00038461">
        </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.000392117">
        </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.000388127">
        </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.000393631">
        </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.000383175">
        </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.000479058">
        </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.000427379">
        </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.00049788">
        </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.000408462">
        </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.000401481">
        </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.000492015">
        </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.000387497">
        </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.000422751">
        </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.000373669">
        </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.000531135">
        </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.000320424">
        </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.000307628">
        </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.000442316">
        </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.000399265">
        </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.000387105">
        </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.000609682">
        </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.000619921">
        </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.001268294">
        </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.000396979">
        </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.000459324">
        </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.000561816">
        </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.000410645">
        </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.00076287">
        </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.000455857">
        </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.000419704">
        </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.000744042">
        </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.000830487">
        </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.000473901">
        </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.000396975">
        </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.000622059">
        </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.000739154">
        </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.00040062">
        </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.002211405">
        </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.00124204">
        </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.001803436">
        </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.000773315">
        </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.000421198">
        </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.000423873">
        </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.000389931">
        </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.00044401">
        </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.000396412">
        </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.000418065">
        </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.000378839">
        </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.000430591">
        </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.000415809">
        </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.000377511">
        </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.00038017">
        </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.000458876">
        </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.000388795">
        </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.000398329">
        </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.000386732">
        </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.000465995">
        </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.000426987">
        </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.000406951">
        </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.000377787">
        </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.000430357">
        </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.000431076">
        </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.000374394">
        </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.000375679">
        </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.000465418">
        </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.001607304">
        </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.000498348">
        </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.000449337">
        </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.000445064">
        </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.000439815">
        </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.000498243">
        </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.000312288">
        </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.00085749">
        </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.000302984">
        </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.000355441">
        </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 correlate_intelligence tool gracefully" time="0.000372053">
        </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.000432792">
        </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.00029443">
        </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.000286102">
        </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.000300051">
        </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.000306685">
        </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.000282764">
        </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.000394883">
        </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.000428134">
        </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.000486166">
        </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.000428499">
        </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.00045245">
        </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.000425988">
        </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.000414385">
        </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.000434337">
        </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.000429489">
        </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.001053826">
        </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.000472483">
        </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.00044349">
        </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.000464998">
        </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.000444276">
        </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.000531336">
        </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.000432758">
        </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.000426166">
        </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.000442281">
        </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.000319638">
        </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.000345411">
        </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.000300763">
        </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.002243534">
        </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.000502449">
        </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.00045859">
        </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.001507104">
        </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.000365389">
        </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.001272146">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; Singleton Functions &gt; should close singleton client" time="0.000621557">
        </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.00108809">
        </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.0006394">
        </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.000804865">
        </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.000293601">
        </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.000410813">
        </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.000290243">
        </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.00029052">
        </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.001120521">
        </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.000611967">
        </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.000331894">
        </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.000314702">
        </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.000651325">
        </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.000461445">
        </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.000398405">
        </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.000723184">
        </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.000429838">
        </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.000695843">
        </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.000494074">
        </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.000491373">
        </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.000431191">
        </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.001773207">
        </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.000467607">
        </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.000608418">
        </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.00126584">
        </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.000442114">
        </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.000405456">
        </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.000408948">
        </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.000747109">
        </testcase>
        <testcase classname="test/unit/ep-mcp-client.test.js" name="ep-mcp-client &gt; getProcedureEventById &gt; should trim processId and eventId" time="0.000419909">
        </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.000526144">
        </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.000424314">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/file-utils.test.js" timestamp="2026-04-14T20:47:06.494Z" hostname="runnervm35a4x" tests="48" failures="0" errors="0" skipped="0" time="0.064351268">
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; parseArticleFilename &gt; should parse valid article filename" time="0.00476762">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; parseArticleFilename &gt; should parse filename with complex slug" time="0.000742473">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; parseArticleFilename &gt; should return null for invalid filename" time="0.000530858">
        </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.001255617">
            <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.002695995">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; groupArticlesByLanguage &gt; should group articles by language code" time="0.011846241">
        </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.000687956">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; formatSlug &gt; should format slug to title case" time="0.000509018">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; formatSlug &gt; should handle single word" time="0.00044621">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; formatSlug &gt; should handle empty string" time="0.000390501">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; getModifiedDate &gt; should return YYYY-MM-DD format" time="0.001833775">
        </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.000494132">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; formatDateForSlug &gt; should format specific date" time="0.000376057">
        </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.000537544">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; calculateReadTime &gt; should return at least 1 minute" time="0.000382084">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; calculateReadTime &gt; should use custom words per minute" time="0.000357711">
        </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.001030438">
        </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.000458202">
        </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.001073975">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; writeFileContent &gt; should overwrite existing file" time="0.001336999">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; extractArticleMeta &gt; should extract title from h1 element" time="0.00131244">
        </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.000942288">
        </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.000865851">
        </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.00084845">
        </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.000844214">
        </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.000833622">
        </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.000830659">
        </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.000541766">
        </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.000401588">
        </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.00125248">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; atomicWrite &gt; should overwrite existing file atomically" time="0.001042078">
        </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.000845917">
        </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.00092762">
        </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.000833983">
        </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.002280523">
        </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.001686361">
        </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.001034878">
        </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.000644543">
        </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.000482548">
        </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.000343716">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; checkArticleExists &gt; should distinguish between different languages" time="0.000847191">
        </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.000456213">
        </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.001962201">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; discoverAnalysisFileEntries &gt; should discover root-level .md files" time="0.001612945">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; discoverAnalysisFileEntries &gt; should discover files in documents/ subdirectory" time="0.000825966">
        </testcase>
        <testcase classname="test/unit/file-utils.test.js" name="utils/file-utils &gt; discoverAnalysisFileEntries &gt; should ignore non-.md files" time="0.001031694">
        </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.001757019">
        </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.001576509">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/fix-articles.test.js" timestamp="2026-04-14T20:47:06.500Z" hostname="runnervm35a4x" tests="10" failures="0" errors="0" skipped="0" time="0.020922733">
        <testcase classname="test/unit/fix-articles.test.js" name="fix-articles &gt; fixArticle &gt; should skip files that do not match the article filename pattern" time="0.004460267">
        </testcase>
        <testcase classname="test/unit/fix-articles.test.js" name="fix-articles &gt; fixArticle &gt; should skip files already containing site-header__langs and article-top-nav" time="0.00260869">
        </testcase>
        <testcase classname="test/unit/fix-articles.test.js" name="fix-articles &gt; fixArticle &gt; should inject full structure for Type A articles (no site-header)" time="0.002306775">
        </testcase>
        <testcase classname="test/unit/fix-articles.test.js" name="fix-articles &gt; fixArticle &gt; should inject top-nav for Type B articles (has site-header)" time="0.001247526">
        </testcase>
        <testcase classname="test/unit/fix-articles.test.js" name="fix-articles &gt; fixArticle &gt; should inject article-top-nav for Type C articles (has site-header__langs)" time="0.001070934">
        </testcase>
        <testcase classname="test/unit/fix-articles.test.js" name="fix-articles &gt; fixArticle &gt; should use localized back label for non-English articles" time="0.000844527">
        </testcase>
        <testcase classname="test/unit/fix-articles.test.js" name="fix-articles &gt; fixArticle &gt; should use English index link for English articles" time="0.001048322">
        </testcase>
        <testcase classname="test/unit/fix-articles.test.js" name="fix-articles &gt; fixArticle &gt; should include all 14 language links in switcher" time="0.001166776">
        </testcase>
        <testcase classname="test/unit/fix-articles.test.js" name="fix-articles &gt; fixArticle &gt; should not write file when dryRun is true" time="0.002002353">
        </testcase>
        <testcase classname="test/unit/fix-articles.test.js" name="fix-articles &gt; fixAllArticles &gt; should process all HTML files in news directory" time="0.001519659">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/generate-news-indexes.test.js" timestamp="2026-04-14T20:47:06.501Z" hostname="runnervm35a4x" tests="50" failures="0" errors="0" skipped="0" time="0.190032718">
        <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.004179804">
        </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.000877125">
        </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.000650951">
        </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.000415987">
        </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.00070898">
        </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.002807995">
        </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.014405116">
        </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.000595275">
        </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.001314501">
        </testcase>
        <testcase classname="test/unit/generate-news-indexes.test.js" name="generate-news-indexes &gt; Slug Formatting &gt; should handle empty slug" time="0.000441688">
        </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.001344986">
        </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.000730194">
        </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.000413243">
        </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.000380957">
        </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.000715108">
        </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.000405997">
        </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.000367219">
        </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.000619331">
        </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.000378669">
        </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.000337145">
        </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.000379189">
        </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.00037105">
        </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.000422522">
        </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.00036829">
        </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.000437738">
        </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.000563361">
        </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.000939184">
        </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.002147749">
        </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.000437451">
        </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.00154658">
        </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.000463165">
        </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.000479822">
        </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.000445101">
        </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.002215782">
        </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.000695909">
        </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.000814627">
        </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.000681158">
        </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.00102243">
        </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.001963779">
        </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.000490431">
        </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.04516411">
        </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.025626243">
        </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.023966777">
        </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.036503247">
        </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.00061596">
        </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.000496562">
        </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.000531356">
        </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.000702449">
        </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.001379585">
        </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.000794511">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/generate-sitemap.test.js" timestamp="2026-04-14T20:47:06.507Z" hostname="runnervm35a4x" tests="73" failures="0" errors="0" skipped="0" time="0.092375844">
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Sitemap XML Structure &gt; should generate valid XML with declaration" time="0.007994085">
        </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.001503561">
        </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.002593091">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Sitemap XML Structure &gt; should include news articles" time="0.000982408">
        </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.000911587">
        </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.000759303">
        </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.000861115">
        </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.000711978">
        </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.00114036">
        </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.001150797">
        </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.000753915">
        </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.000798668">
        </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.000690249">
        </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.002365725">
        </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.001961439">
        </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.000793424">
        </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.000620039">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; URL Count &gt; should handle many articles" time="0.001233703">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; XML Validation &gt; should have balanced XML tags" time="0.000666107">
        </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.002661935">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; XML Validation &gt; should use HTTPS protocol" time="0.00462794">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; XML Validation &gt; should use correct base URL" time="0.000597657">
        </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.000669702">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Date Handling &gt; should handle valid date format" time="0.000459942">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; File Operations &gt; should handle empty news directory" time="0.000586931">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; File Operations &gt; should filter only HTML files" time="0.001362855">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; File Operations &gt; should get file modification time" time="0.000858575">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Edge Cases &gt; should handle article with future date" time="0.000749871">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Edge Cases &gt; should handle article with past date" time="0.000608782">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Edge Cases &gt; should handle very long filename" time="0.000618101">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; Performance &gt; should handle large number of articles" time="0.011698412">
        </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.00136184">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; collectDocsHtmlFiles &gt; should collect HTML files recursively" time="0.001607827">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; collectDocsHtmlFiles &gt; should skip non-HTML files" time="0.001183352">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; getSitemapFilename &gt; should return sitemap.html for English" time="0.000405125">
        </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.000382245">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemapHTML &gt; should generate valid HTML5 document" time="0.001891409">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemapHTML &gt; should include sitemap title in target language" time="0.000842871">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemapHTML &gt; should include all language index page links" time="0.000842373">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemapHTML &gt; should include article titles and dates" time="0.0009915">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemapHTML &gt; should include article description when present" time="0.000555663">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemapHTML &gt; should handle articles without description" time="0.000745684">
        </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.000748468">
        </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.000603647">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemapHTML &gt; should use localized docs labels" time="0.000534249">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemapHTML &gt; should set correct RTL direction for Arabic" time="0.000528293">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemapHTML &gt; should set correct LTR direction for English" time="0.000503508">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemapHTML &gt; should include language switcher for sitemap pages" time="0.000544743">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemapHTML &gt; should include skip link for accessibility" time="0.000824542">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemapHTML &gt; should include footer with Hack23 info" time="0.000749371">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemapHTML &gt; should escape HTML in article titles" time="0.000652869">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemapHTML &gt; should link news articles correctly" time="0.000693192">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateSitemapHTML &gt; should generate all 14 language variants" time="0.004138322">
        </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.000799621">
        </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.000859046">
        </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.000500711">
        </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.00035302">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateRssFeed &gt; should generate valid RSS 2.0 XML" time="0.00058897">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateRssFeed &gt; should include channel metadata" time="0.000430183">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateRssFeed &gt; should include atom self link" time="0.000347153">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateRssFeed &gt; should include article items with correct structure" time="0.000639939">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateRssFeed &gt; should include multi-language items" time="0.000518285">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateRssFeed &gt; should escape XML special characters in titles" time="0.000405993">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateRssFeed &gt; should handle empty items list" time="0.000366369">
        </testcase>
        <testcase classname="test/unit/generate-sitemap.test.js" name="generate-sitemap &gt; generateRssFeed &gt; should handle large number of items" time="0.00170815">
        </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.000811011">
        </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.001743056">
        </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.000316892">
        </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.000863355">
        </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.000357049">
        </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, 1 rss.xml with no articles" time="0.000253406">
        </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.000316113">
        </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.000442313">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/html-sanitize.test.js" timestamp="2026-04-14T20:47:06.515Z" hostname="runnervm35a4x" tests="25" failures="0" errors="0" skipped="0" time="0.01215558">
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripScriptBlocks &gt; should return empty string for empty input" time="0.003254453">
        </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.000420917">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripScriptBlocks &gt; should strip a simple script block" time="0.000645228">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripScriptBlocks &gt; should strip multiple script blocks" time="0.00044444">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripScriptBlocks &gt; should handle script tag with attributes" time="0.000418718">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripScriptBlocks &gt; should be case-insensitive for script tags" time="0.000219861">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripScriptBlocks &gt; should handle mixed case script tags" time="0.00019853">
        </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.000245761">
        </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.000520449">
        </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.000193629">
        </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.000171915">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripScriptBlocks &gt; should handle empty script tags" time="0.000135166">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripScriptBlocks &gt; should handle script with newlines" time="0.000125454">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripScriptBlocks &gt; should handle adjacent script blocks" time="0.00019992">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripScriptBlocks &gt; should handle script at the very beginning" time="0.000217377">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripScriptBlocks &gt; should handle script at the very end" time="0.000184931">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripScriptBlocks &gt; should handle plain text without HTML" time="0.000165356">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripHtmlTags &gt; should return empty string for empty input" time="0.000257615">
        </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.000179032">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripHtmlTags &gt; should strip simple HTML tags" time="0.000157586">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripHtmlTags &gt; should strip tags with attributes" time="0.000164317">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripHtmlTags &gt; should strip multiple tags" time="0.000192546">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripHtmlTags &gt; should handle self-closing tags" time="0.000087972">
        </testcase>
        <testcase classname="test/unit/html-sanitize.test.js" name="html-sanitize &gt; stripHtmlTags &gt; should handle unclosed tag gracefully" time="0.000111087">
        </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.000171112">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/intelligence-analysis.test.js" timestamp="2026-04-14T20:47:06.518Z" hostname="runnervm35a4x" tests="178" failures="0" errors="0" skipped="0" time="0.057289365">
        <testcase classname="test/unit/intelligence-analysis.test.js" name="scoreVotingAnomaly &gt; should return a VotingAnomalyIntelligence for valid input" time="0.003296918">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="scoreVotingAnomaly &gt; should return null for null input" time="0.000183787">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="scoreVotingAnomaly &gt; should return null for undefined input" time="0.000112708">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="scoreVotingAnomaly &gt; should return null for non-object input" time="0.000139004">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="scoreVotingAnomaly &gt; should return null when anomalyId is missing" time="0.000169294">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="scoreVotingAnomaly &gt; should fall back to id field when anomalyId is absent" time="0.000178673">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="scoreVotingAnomaly &gt; should default significance to low for invalid values" time="0.000113518">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="scoreVotingAnomaly &gt; should accept all valid significance levels" time="0.000340353">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="scoreVotingAnomaly &gt; should filter non-string entries from affectedGroups" time="0.000286551">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="scoreVotingAnomaly &gt; should return empty array when affectedGroups is missing" time="0.000245672">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="scoreVotingAnomaly &gt; should return 0 for deviationPercentage when missing or non-numeric" time="0.000170658">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="analyzeCoalitionCohesion &gt; should return a CoalitionIntelligence for valid input" time="0.000442892">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="analyzeCoalitionCohesion &gt; should return null for null input" time="0.000097115">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="analyzeCoalitionCohesion &gt; should return null for undefined input" time="0.000092117">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="analyzeCoalitionCohesion &gt; should return null when coalition identifier is missing" time="0.000086844">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="analyzeCoalitionCohesion &gt; should fall back to id field when coalitionId is absent" time="0.000100951">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="analyzeCoalitionCohesion &gt; should clamp cohesionScore above 1 to 1" time="0.000087626">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="analyzeCoalitionCohesion &gt; should clamp cohesionScore below 0 to 0" time="0.000081219">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="analyzeCoalitionCohesion &gt; should default alignmentTrend to stable for invalid values" time="0.000080798">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="analyzeCoalitionCohesion &gt; should accept all valid alignment trends" time="0.000131288">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="analyzeCoalitionCohesion &gt; should default riskLevel to medium for invalid values" time="0.000094198">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="analyzeCoalitionCohesion &gt; should accept all valid risk levels" time="0.000162799">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="analyzeCoalitionCohesion &gt; should round keyVotes to the nearest integer" time="0.000098764">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="scoreMEPInfluence &gt; should return a MEPInfluenceScore for valid input" time="0.000295459">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="scoreMEPInfluence &gt; should return null for null input" time="0.000076742">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="scoreMEPInfluence &gt; should return null for undefined input" time="0.000067444">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="scoreMEPInfluence &gt; should return null when mepId is missing" time="0.000074784">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="scoreMEPInfluence &gt; should return null when mepName is missing" time="0.000073958">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="scoreMEPInfluence &gt; should fall back to id when mepId is absent" time="0.000130855">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="scoreMEPInfluence &gt; should clamp overallScore to 0–100 range" time="0.000133918">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="scoreMEPInfluence &gt; should clamp sub-scores to 0–100 range" time="0.000120572">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="scoreMEPInfluence &gt; should return empty string for missing rank" time="0.000094237">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="calculateLegislativeVelocity &gt; should return a LegislativeVelocity for valid input" time="0.000375124">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="calculateLegislativeVelocity &gt; should return null for null input" time="0.000145055">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="calculateLegislativeVelocity &gt; should return null for undefined input" time="0.000190758">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="calculateLegislativeVelocity &gt; should return null when procedureId is missing" time="0.000136818">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="calculateLegislativeVelocity &gt; should return null when title is missing" time="0.000093994">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="calculateLegislativeVelocity &gt; should fall back to id field when procedureId is absent" time="0.000098561">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="calculateLegislativeVelocity &gt; should default stage to Unknown when missing" time="0.000086976">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="calculateLegislativeVelocity &gt; should clamp velocityScore to 0–1 range" time="0.000124395">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="calculateLegislativeVelocity &gt; should default bottleneckRisk to medium for invalid values" time="0.000130652">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="calculateLegislativeVelocity &gt; should floor negative daysInCurrentStage to 0" time="0.000108223">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="rankBySignificance &gt; should return an empty array for empty input" time="0.000184186">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="rankBySignificance &gt; should sort by significance level descending (critical &gt; high &gt; medium &gt; low)" time="0.000187955">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="rankBySignificance &gt; should use overallScore as tie-breaker when significance is equal" time="0.000201251">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="rankBySignificance &gt; should use cohesionScore as tie-breaker when overallScore is absent" time="0.000164944">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="rankBySignificance &gt; should treat unknown significance as lower priority than low" time="0.000110632">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="rankBySignificance &gt; should not mutate the original array" time="0.000176187">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="rankBySignificance &gt; should handle items without significance field" time="0.000127913">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildIntelligenceSection &gt; should return an empty string for an empty items array" time="0.000170078">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildIntelligenceSection &gt; should produce a section element with the provided class name" time="0.000304154">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildIntelligenceSection &gt; should include the heading inside an h2 element" time="0.000094216">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildIntelligenceSection &gt; should render each item as an li element" time="0.000191389">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildIntelligenceSection &gt; should escape XSS in the title" time="0.000221892">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildIntelligenceSection &gt; should escape XSS in item text" time="0.000317438">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildIntelligenceSection &gt; should escape XSS in the className" time="0.000118604">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildWhatToWatchSection &gt; should return empty string when both arrays are empty" time="0.000178866">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildWhatToWatchSection &gt; should produce a section element with class what-to-watch" time="0.000455135">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildWhatToWatchSection &gt; should include the language code as the lang attribute" time="0.000173535">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildWhatToWatchSection &gt; should highlight high bottleneck risk velocities" time="0.000212407">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildWhatToWatchSection &gt; should include bottlenecked procedures" time="0.000168398">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildWhatToWatchSection &gt; should include non-bottleneck velocity items" time="0.000207609">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildWhatToWatchSection &gt; should escape HTML in procedure and velocity titles (XSS prevention)" time="0.000209182">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildWhatToWatchSection &gt; should return empty string when procedures are all non-bottleneck and velocities are empty" time="0.000151983">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildPoliticalAlignmentSection &gt; should return empty string when both arrays are empty" time="0.000264958">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildPoliticalAlignmentSection &gt; should produce a section element with class political-alignment" time="0.000682879">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildPoliticalAlignmentSection &gt; should include the language code as the lang attribute" time="0.000213495">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildPoliticalAlignmentSection &gt; should render voting record titles and results" time="0.00063017">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildPoliticalAlignmentSection &gt; should render coalition groups and cohesion scores" time="0.00030127">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildPoliticalAlignmentSection &gt; should indicate risk level for coalitions" time="0.00019648">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildPoliticalAlignmentSection &gt; should escape HTML in voting record titles (XSS prevention)" time="0.000239885">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildPoliticalAlignmentSection &gt; should escape HTML in coalition group names (XSS prevention)" time="0.000268072">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildPoliticalAlignmentSection &gt; should contain both voting records section and coalition section when both provided" time="0.000278937">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildPoliticalAlignmentSection &gt; should not contain undefined or null in output" time="0.000227193">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildDefaultStakeholderPerspectives &gt; should return exactly 6 perspectives (one per stakeholder group)" time="0.00152944">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildDefaultStakeholderPerspectives &gt; should cover all 6 stakeholder types" time="0.001030339">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildDefaultStakeholderPerspectives &gt; should set severity based on score thresholds" time="0.000502219">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildDefaultStakeholderPerspectives &gt; should set positive impact for score &gt;= 0.6" time="0.000241586">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildDefaultStakeholderPerspectives &gt; should set negative impact for score &lt;= 0.3" time="0.000208434">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildDefaultStakeholderPerspectives &gt; should set neutral impact for score between 0.3 and 0.6 exclusive" time="0.000212424">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildDefaultStakeholderPerspectives &gt; should include the topic in evidence" time="0.00065216">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildDefaultStakeholderPerspectives &gt; should default to score 0.5 (medium / neutral) when no scores provided" time="0.000450223">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="scoreStakeholderInfluence &gt; should return null for null input" time="0.00026525">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="scoreStakeholderInfluence &gt; should return null for undefined input" time="0.000149258">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="scoreStakeholderInfluence &gt; should return null when stakeholder type is invalid" time="0.000158203">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="scoreStakeholderInfluence &gt; should return null for non-object input" time="0.000170809">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="scoreStakeholderInfluence &gt; should parse a valid stakeholder perspective" time="0.000359922">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="scoreStakeholderInfluence &gt; should default impact to neutral for unknown impact values" time="0.000172401">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="scoreStakeholderInfluence &gt; should default severity to medium for unknown severity values" time="0.000162679">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="scoreStakeholderInfluence &gt; should handle all 6 valid stakeholder types" time="0.000807623">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildStakeholderOutcomeMatrix &gt; should return a matrix row with the provided action" time="0.000334222">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildStakeholderOutcomeMatrix &gt; should default to medium confidence" time="0.000279257">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildStakeholderOutcomeMatrix &gt; should accept a confidence override" time="0.000164466">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildStakeholderOutcomeMatrix &gt; should produce outcomes for all 6 stakeholder types" time="0.000762379">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildStakeholderOutcomeMatrix &gt; should mark winner for score &gt; 0.6" time="0.000191289">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildStakeholderOutcomeMatrix &gt; should mark loser for score &lt; 0.4" time="0.000168138">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildStakeholderOutcomeMatrix &gt; should mark neutral for score == 0.5 (default)" time="0.00014136">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildStakeholderOutcomeMatrix &gt; should use neutral outcome for missing scores" time="0.000143253">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="rankStakeholdersByInfluence &gt; should return an empty array for empty input" time="0.000299499">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="rankStakeholdersByInfluence &gt; should rank high-severity before medium and low" time="0.000456809">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="rankStakeholdersByInfluence &gt; should rank negative impact before positive at the same severity" time="0.000229239">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="rankStakeholdersByInfluence &gt; should not mutate the input array" time="0.00019539">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="computeVotingIntensity &gt; should return null for empty records" time="0.000333522">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="computeVotingIntensity &gt; should compute metrics for a single decisive vote" time="0.000572822">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="computeVotingIntensity &gt; should detect close votes (margin &lt; 10%)" time="0.000297782">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="computeVotingIntensity &gt; should handle multiple votes and average correctly" time="0.000272582">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="computeVotingIntensity &gt; should return null when all records have zero total votes" time="0.000159833">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="computeVotingIntensity &gt; should skip zero-vote records and only count valid ones" time="0.000454213">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="computeVotingIntensity &gt; should return averageMargin between 0 and 1" time="0.000348299">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="computeVotingIntensity &gt; should include abstentions when determining unanimity largest faction" time="0.000393361">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="computeVotingIntensity &gt; should not understate polarization when some records are abstain-only" time="0.000261256">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="detectCoalitionShifts &gt; should return empty array when both inputs are empty" time="0.000488756">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="detectCoalitionShifts &gt; should detect a weakening shift when cohesion drops significantly" time="0.00051795">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="detectCoalitionShifts &gt; should detect a strengthening shift when cohesion rises" time="0.000307694">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="detectCoalitionShifts &gt; should mark stable when delta is within ±5%" time="0.00031797">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="detectCoalitionShifts &gt; should use current cohesion as baseline when group not in baseline" time="0.000316047">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="detectCoalitionShifts &gt; should sort by significance then absolute delta" time="0.000360883">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="computePolarizationIndex &gt; should return null for empty patterns" time="0.000234713">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="computePolarizationIndex &gt; should assess &quot;consensus&quot; when all groups have moderate cohesion" time="0.000584176">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="computePolarizationIndex &gt; should assess &quot;highly-polarized&quot; when most groups are extreme" time="0.000457928">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="computePolarizationIndex &gt; should compute effectiveBlocs using Laakso-Taagepera style" time="0.00025588">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="computePolarizationIndex &gt; should return overallIndex between 0 and 1" time="0.000245651">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="computePolarizationIndex &gt; should handle single group patterns" time="0.000268827">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="detectVotingTrends &gt; should return empty array for empty records" time="0.000378384">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="detectVotingTrends &gt; should return empty array for a single record" time="0.000998434">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="detectVotingTrends &gt; should detect adoption rate trend from multiple decided records" time="0.000976983">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="detectVotingTrends &gt; should detect increasing adoption-rate via half comparison" time="0.000298329">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="detectVotingTrends &gt; should detect increasing margins trend" time="0.000415738">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="detectVotingTrends &gt; should detect increasing polarization from close votes" time="0.00029333">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="detectVotingTrends &gt; should skip records with zero total votes" time="0.000296698">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="detectVotingTrends &gt; should sort trends by confidence descending" time="0.000220942">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="detectVotingTrends &gt; should cap confidence at 1" time="0.000208756">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="detectVotingTrends &gt; should sort records by date before splitting into halves" time="0.000437968">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="detectVotingTrends &gt; should skip abstain-only records in margin calculations" time="0.000238466">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="detectVotingTrends &gt; should handle records with missing or invalid dates gracefully" time="0.0002023">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="detectVotingTrends &gt; should skip records with missing or malformed vote data" time="0.000286117">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="computeCrossSessionCoalitionStability &gt; should return volatile report for empty patterns" time="0.000478181">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="computeCrossSessionCoalitionStability &gt; should detect stable groups (avg cohesion &gt;= 0.7)" time="0.000378155">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="computeCrossSessionCoalitionStability &gt; should detect declining groups (avg cohesion &lt; 0.5)" time="0.000266391">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="computeCrossSessionCoalitionStability &gt; should compute overall stability as average of group averages" time="0.000177618">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="computeCrossSessionCoalitionStability &gt; should forecast at-risk when overall stability is between 0.5 and 0.7" time="0.000177615">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="computeCrossSessionCoalitionStability &gt; should forecast volatile when overall stability &lt; 0.5" time="0.000167497">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="computeCrossSessionCoalitionStability &gt; should aggregate multiple entries for the same group" time="0.000526978">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="computeCrossSessionCoalitionStability &gt; should handle non-finite/out-of-range cohesion values via clamping" time="0.000311887">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="computeCrossSessionCoalitionStability &gt; should skip patterns with empty/missing group key" time="0.000425476">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="rankMEPInfluenceByTopic &gt; should return empty array for empty scores" time="0.000274814">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="rankMEPInfluenceByTopic &gt; should filter by topic matching mepName" time="0.000311549">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="rankMEPInfluenceByTopic &gt; should filter by topic matching rank (case-insensitive)" time="0.000320183">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="rankMEPInfluenceByTopic &gt; should return all scores sorted when topic is empty" time="0.000280295">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="rankMEPInfluenceByTopic &gt; should return all scores sorted when no matches found" time="0.00023674">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="rankMEPInfluenceByTopic &gt; should match by mepId" time="0.000233189">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="rankMEPInfluenceByTopic &gt; should sort matching results by overallScore descending" time="0.000217216">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="rankMEPInfluenceByTopic &gt; should handle whitespace-only topic as empty" time="0.000210036">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="rankMEPInfluenceByTopic &gt; should handle null or undefined topic gracefully" time="0.000315265">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="rankMEPInfluenceByTopic &gt; should handle non-string mepName/rank/mepId without throwing" time="0.000184762">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildLegislativeVelocityReport &gt; should return empty report for empty docs" time="0.000604031">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildLegislativeVelocityReport &gt; should count documents by stage using status field" time="0.000512231">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildLegislativeVelocityReport &gt; should use type as fallback when status is missing" time="0.000252152">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildLegislativeVelocityReport &gt; should label unknown stage when both status and type missing" time="0.000183855">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildLegislativeVelocityReport &gt; should detect bottleneck stages" time="0.000228009">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildLegislativeVelocityReport &gt; should compute average days per stage from date spread" time="0.000193536">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildLegislativeVelocityReport &gt; should assess fast throughput for short durations" time="0.000201973">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildLegislativeVelocityReport &gt; should assess slow throughput for long durations" time="0.000178991">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildLegislativeVelocityReport &gt; should handle documents with missing dates" time="0.000272571">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="buildLegislativeVelocityReport &gt; should handle non-string status/type by treating them as unknown stages without throwing" time="0.00023294">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="deriveCoalitionShiftSignals &gt; should return empty array for empty input" time="0.0003187">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="deriveCoalitionShiftSignals &gt; should detect bloc-fragmentation for low cohesion (&lt;0.4)" time="0.0007129">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="deriveCoalitionShiftSignals &gt; should assign high confidence to very low cohesion (&lt;0.25)" time="0.000404448">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="deriveCoalitionShiftSignals &gt; should detect isolation when group cohesion is far below average" time="0.000435911">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="deriveCoalitionShiftSignals &gt; should detect cross-party-alignment when opposing blocs have high cohesion" time="0.000253632">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="deriveCoalitionShiftSignals &gt; should detect new-bloc-formation when 3+ groups from different blocs have high cohesion" time="0.00033244">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="deriveCoalitionShiftSignals &gt; should sort signals by confidence descending" time="0.000224747">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="computeStakeholderInfluenceTrajectory &gt; should return rising when score delta &gt;= 5 and has engagement" time="0.000452696">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="computeStakeholderInfluenceTrajectory &gt; should return declining when score delta &lt;= -5" time="0.000182944">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="computeStakeholderInfluenceTrajectory &gt; should return stable when no significant change" time="0.00018096">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="computeStakeholderInfluenceTrajectory &gt; should return rising without historical when engagement &gt;= 3" time="0.000241271">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="computeStakeholderInfluenceTrajectory &gt; should return low confidence without historical and without engagement" time="0.000429237">
        </testcase>
        <testcase classname="test/unit/intelligence-analysis.test.js" name="computeStakeholderInfluenceTrajectory &gt; should populate driving factors" time="0.000206977">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/intelligence-index.test.js" timestamp="2026-04-14T20:47:06.537Z" hostname="runnervm35a4x" tests="62" failures="0" errors="0" skipped="0" time="0.088242313">
        <testcase classname="test/unit/intelligence-index.test.js" name="createEmptyIndex &gt; should return a valid empty structure" time="0.006570504">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="createEmptyIndex &gt; should include a lastUpdated timestamp" time="0.000602592">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="addArticleToIndex &gt; should add an entry and return an updated index" time="0.001450806">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="addArticleToIndex &gt; should update the actors map" time="0.001045607">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="addArticleToIndex &gt; should update the policyDomains map" time="0.00042522">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="addArticleToIndex &gt; should update the procedures map" time="0.000412734">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="addArticleToIndex &gt; should replace an existing entry with the same id" time="0.00068599">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="addArticleToIndex &gt; should clean up stale map associations when replacing an article" time="0.001490418">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="addArticleToIndex &gt; should not duplicate article IDs in maps" time="0.000478879">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="addArticleToIndex &gt; should not mutate the original index" time="0.000357981">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="buildIndexFromEntries &gt; should deduplicate article IDs when entries have duplicate topics" time="0.000829222">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="buildIndexFromEntries &gt; should reject prototype-pollution keys like __proto__" time="0.000664056">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="addArticleToIndex prototype-safety &gt; should reject dangerous keys in addArticleToIndex" time="0.000364076">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="findRelatedArticles &gt; should find articles sharing topics" time="0.001308442">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="findRelatedArticles &gt; should find articles sharing actors" time="0.000483429">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="findRelatedArticles &gt; should return empty array for empty topics and actors" time="0.000468022">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="findRelatedArticles &gt; should respect maxResults limit" time="0.000400688">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="findRelatedArticles &gt; should sort results by relevance score (highest first)" time="0.000476606">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="findRelatedArticles &gt; should handle empty index" time="0.000436041">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="generateCrossReferences &gt; should generate cross-references for related articles" time="0.001122465">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="generateCrossReferences &gt; should not generate self-references" time="0.000410638">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="generateCrossReferences &gt; should assign strong strength for ≥3 shared items" time="0.000333774">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="generateCrossReferences &gt; should assign follows_up for older target articles" time="0.00039692">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="generateCrossReferences &gt; should assign preceded_by for newer target articles" time="0.000328621">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="generateCrossReferences &gt; should assign related for same-date target articles" time="0.000391521">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="generateCrossReferences &gt; should return empty array for no related articles" time="0.000425815">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="detectTrends &gt; should detect trends when ≥2 articles share topics" time="0.001823732">
        </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.000303844">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="detectTrends &gt; should detect procedure-based trends" time="0.000470977">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="detectTrends &gt; should return empty array for empty index" time="0.000294189">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="detectTrends &gt; should set confidence based on article count" time="0.000780258">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="detectTrends &gt; should set direction to strengthening when ≥4 articles" time="0.000406697">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="detectTrends &gt; should produce non-colliding trend IDs for non-Latin scripts" time="0.001481522">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="findOrCreateSeries &gt; should create a new series when none exists" time="0.000524486">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="findOrCreateSeries &gt; should find an existing series by procedureRef" time="0.000361802">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="findOrCreateSeries &gt; should add the series to the index" time="0.000332384">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="findOrCreateSeries &gt; should generate a stable id from procedureRef" time="0.000375222">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="loadIntelligenceIndex &gt; should return empty index if file not found" time="0.001229794">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="loadIntelligenceIndex &gt; should return empty index if file is malformed JSON" time="0.00084108">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="loadIntelligenceIndex &gt; should normalize partial JSON (missing fields) to a complete index" time="0.002539623">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="loadIntelligenceIndex &gt; should rebuild lookup maps from articles when maps are missing" time="0.001778977">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="loadIntelligenceIndex &gt; should normalize article entries missing required arrays" time="0.001194399">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="loadIntelligenceIndex &gt; should reject non-string seriesId values during normalization" time="0.000922315">
        </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.000829705">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="loadIntelligenceIndex &gt; should recompute trends when lookup maps are rebuilt on load" time="0.001507309">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="loadIntelligenceIndex &gt; should sanitize unsafe keys from structurally valid persisted maps" time="0.001537272">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="saveIntelligenceIndex + loadIntelligenceIndex (round-trip) &gt; should persist and reload an index correctly" time="0.001411544">
        </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.000773565">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="buildRelatedArticlesHTML &gt; should return empty string when no related articles or trends" time="0.00883887">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="buildRelatedArticlesHTML &gt; should return empty string when only empty arrays are provided" time="0.000208693">
        </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.00049129">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="buildRelatedArticlesHTML &gt; should render output when only crossRefs are provided" time="0.000272207">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="buildRelatedArticlesHTML &gt; should generate a section element with aria-label" time="0.02383476">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="buildRelatedArticlesHTML &gt; should include rel=&quot;noopener noreferrer&quot; on links" time="0.000448891">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="buildRelatedArticlesHTML &gt; should include links to article HTML files" time="0.000345955">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="buildRelatedArticlesHTML &gt; should render trend blocks when trends are provided" time="0.000499066">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="buildRelatedArticlesHTML &gt; should include the article count in the trend description" time="0.000354119">
        </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.000348543">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="buildRelatedArticlesHTML &gt; should escape HTML special characters in context" time="0.000537573">
        </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.000983275">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="buildRelatedArticlesHTML &gt; should localise trend labels for German" time="0.000963225">
        </testcase>
        <testcase classname="test/unit/intelligence-index.test.js" name="buildRelatedArticlesHTML &gt; should fall back to English for unknown language codes" time="0.000523763">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/languages.test.js" timestamp="2026-04-14T20:47:06.544Z" hostname="runnervm35a4x" tests="56" failures="0" errors="0" skipped="0" time="0.147910929">
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; ALL_LANGUAGES &gt; should contain exactly 14 language codes" time="0.004897172">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; ALL_LANGUAGES &gt; should contain all expected Hack23 market languages" time="0.001818985">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; LANGUAGE_PRESETS &gt; should have all presets" time="0.000419852">
        </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.001647703">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; LANGUAGE_PRESETS &gt; should have nordic preset with 5 languages" time="0.001014772">
        </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.001789816">
        </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.000765961">
        </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.000820003">
        </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.001096417">
        </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.000897119">
        </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.007327294">
        </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.001920715">
        </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.000503251">
        </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.004888331">
        </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.002527594">
        </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.003189056">
        </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.002706337">
        </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.002583608">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; Language Maps &gt; should have correct native language names" time="0.000264551">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; getLocalizedString &gt; should return correct value for supported language" time="0.000238313">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; getLocalizedString &gt; should fall back to English for unsupported language" time="0.000109346">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; getLocalizedString &gt; should work with function-valued maps" time="0.000150024">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; isSupportedLanguage &gt; should return true for supported languages" time="0.000235067">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; isSupportedLanguage &gt; should return false for unsupported languages" time="0.000148096">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; getTextDirection &gt; should return ltr for LTR languages" time="0.000398767">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; getTextDirection &gt; should return rtl for Arabic" time="0.000114441">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; getTextDirection &gt; should return rtl for Hebrew" time="0.000124332">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="constants/languages &gt; getTextDirection &gt; should return ltr for unknown languages" time="0.000093265">
        </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.000432527">
        </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.014135819">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="EDITORIAL_STRINGS &gt; should have entries for all 14 supported languages" time="0.000284548">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="EDITORIAL_STRINGS &gt; should contain all required editorial string fields for every language" time="0.002992696">
        </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.000191308">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="EDITORIAL_STRINGS &gt; should have non-empty whyThisMatters for all languages" time="0.000239752">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="PROPOSITIONS_STRINGS whyThisMatters &gt; should have whyThisMatters field for all 14 languages" time="0.000783048">
        </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.000579784">
        </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.000105177">
        </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.000528875">
        </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.000080216">
        </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.000532913">
        </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.00051099">
        </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.000075211">
        </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.000564195">
        </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.000118126">
        </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.000798792">
        </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.000132965">
        </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.000111555">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="MONTHLY_REVIEW_TITLES &gt; should have entries for all 14 languages" time="0.000236904">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="MONTHLY_REVIEW_TITLES &gt; should generate title and subtitle for each language" time="0.001838376">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="DEEP_ANALYSIS_STRINGS &gt; should have entries for all 14 languages" time="0.000229868">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="DEEP_ANALYSIS_STRINGS &gt; should have all required fields for each language" time="0.049696233">
        </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.008988202">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="MONTH_IN_REVIEW_STRINGS &gt; should have entries for all 14 languages" time="0.000320327">
        </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.004806412">
        </testcase>
        <testcase classname="test/unit/languages.test.js" name="ANALYSIS_QUALITY_LABELS &gt; should have entries for all 14 languages" time="0.002673534">
        </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.005448949">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/mcp-connection.test.js" timestamp="2026-04-14T20:47:06.550Z" hostname="runnervm35a4x" tests="105" failures="0" errors="0" skipped="0" time="0.095515071">
        <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.005519491">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; parseSSEResponse &gt; should return null for empty string" time="0.00043094">
        </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.000226891">
        </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.000324875">
        </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.000281925">
        </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.000296165">
        </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.000197509">
        </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.000272762">
        </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.000220872">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; parseSSEResponse &gt; should parse error responses from SSE" time="0.000463522">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; formatRetryAfter &gt; should format numeric seconds" time="0.000382969">
        </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.000214779">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; formatRetryAfter &gt; should format zero seconds" time="0.000194609">
        </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.00050866">
        </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.00033409">
        </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.000276286">
        </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.000166308">
        </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.000242183">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPSessionExpiredError &gt; should be an instance of Error" time="0.000406856">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPSessionExpiredError &gt; should be an instance of MCPSessionExpiredError" time="0.000295261">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPSessionExpiredError &gt; should have name MCPSessionExpiredError" time="0.000216958">
        </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.000431243">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; isRetriableError &gt; should return true for a timeout error" time="0.000298293">
        </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.000277718">
        </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.000171778">
        </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.000235595">
        </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.000178709">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; isRetriableError &gt; should return false for MCPSessionExpiredError" time="0.000276174">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; isRetriableError &gt; should return false for a TypeError" time="0.000180686">
        </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.000226414">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; isRetriableError &gt; should return false for a MCPRateLimitError instance" time="0.000230899">
        </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.000184284">
        </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.000270497">
        </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.000192251">
        </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.000241228">
        </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.000173685">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; isRetriableError &gt; should return true for ECONNREFUSED error" time="0.00026493">
        </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.000183054">
        </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.001263115">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; Constructor &gt; should accept maxRetries option" time="0.000413447">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; Constructor &gt; should default maxRetries to 2" time="0.000332432">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; Constructor &gt; should initialize reconnectingPromise to null" time="0.000291561">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; getConnectionHealth &gt; should reflect connected state" time="0.00035649">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; getConnectionHealth &gt; should accumulate timeout count" time="0.006281101">
        </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.000700023">
        </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.001650462">
        </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.002719673">
        </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.004523058">
        </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.00216054">
        </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.001871037">
        </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.001686341">
        </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.00060725">
        </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.000397247">
        </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.000680412">
        </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.000719373">
        </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.002821742">
        </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.00158677">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="mcp-connection &gt; MCPConnection &gt; reconnect &gt; should clear reconnectingPromise after success" time="0.001425344">
        </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.001600985">
        </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.001054376">
        </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.000594283">
        </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.000706748">
        </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.000539957">
        </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.000628884">
        </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.001503401">
        </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.000533313">
        </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.000514291">
        </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.000501479">
        </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.000552829">
        </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.001063068">
        </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.002528953">
        </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.000685647">
        </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.000208387">
        </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.000265301">
        </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.000275842">
        </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.000241026">
        </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.00021115">
        </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.000281575">
        </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.000437926">
        </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.000241551">
        </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.000392039">
        </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.000324398">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="CircuitBreaker (mcp-retry) &gt; starts in CLOSED state and allows requests" time="0.000467274">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="CircuitBreaker (mcp-retry) &gt; stays CLOSED when failures are below threshold" time="0.000331282">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="CircuitBreaker (mcp-retry) &gt; opens after reaching failure threshold" time="0.000608082">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="CircuitBreaker (mcp-retry) &gt; transitions OPEN → HALF_OPEN after reset timeout" time="0.000321828">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="CircuitBreaker (mcp-retry) &gt; closes circuit on success after HALF_OPEN" time="0.000281546">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="CircuitBreaker (mcp-retry) &gt; re-opens on failure in HALF_OPEN" time="0.000266936">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="CircuitBreaker (mcp-retry) &gt; allows only one probe in HALF_OPEN state" time="0.000290471">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="CircuitBreaker (mcp-retry) &gt; resets consecutive failures on success" time="0.000319011">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="CircuitBreaker (mcp-retry) &gt; getStats returns current state and failure count" time="0.000561086">
        </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.000292499">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="withRetry (mcp-retry) &gt; returns result on first success" time="0.000550363">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="withRetry (mcp-retry) &gt; retries and succeeds on later attempt" time="0.003002177">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="withRetry (mcp-retry) &gt; throws last error after all retries exhausted" time="0.002671885">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="withRetry (mcp-retry) &gt; uses exponential backoff between retries" time="0.003887358">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="withRetry (mcp-retry) &gt; caps delay at maxDelayMs" time="0.002754547">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="withRetry (mcp-retry) &gt; defaults to 3 retries when no policy given" time="0.003884609">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="MCPHealthMonitor (mcp-health) &gt; creates breakers on demand for new tools" time="0.000415373">
        </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.000238208">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="MCPHealthMonitor (mcp-health) &gt; applies default options to newly created breakers" time="0.000203021">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="MCPHealthMonitor (mcp-health) &gt; provides aggregated health snapshot" time="0.000570293">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="MCPHealthMonitor (mcp-health) &gt; lists registered tools" time="0.001421854">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="MCPHealthMonitor (mcp-health) &gt; returns empty snapshot when no tools registered" time="0.000324925">
        </testcase>
        <testcase classname="test/unit/mcp-connection.test.js" name="MCPHealthMonitor (mcp-health) &gt; tracks HALF_OPEN state in snapshot" time="0.000248564">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/mindmap-content.test.js" timestamp="2026-04-14T20:47:06.561Z" hostname="runnervm35a4x" tests="52" failures="0" errors="0" skipped="0" time="0.04455792">
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildIntelligenceMindmapSection &gt; should return empty string for null input" time="0.007150301">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildIntelligenceMindmapSection &gt; should return empty string for undefined input" time="0.000487462">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildIntelligenceMindmapSection &gt; should return empty string when all layers have no nodes" time="0.000291863">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildIntelligenceMindmapSection &gt; should render a full intelligence mindmap with nodes" time="0.001948709">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildIntelligenceMindmapSection &gt; should render influence bar with WCAG meter attributes" time="0.003492788">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildIntelligenceMindmapSection &gt; should clamp influence values to 0-1 range" time="0.000413165">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildIntelligenceMindmapSection &gt; should render connections overlay when connections are present" time="0.000563864">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildIntelligenceMindmapSection &gt; should render actor network overlay" time="0.003644267">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildIntelligenceMindmapSection &gt; should render stakeholder perspective overlays via details elements" time="0.000543576">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildIntelligenceMindmapSection &gt; should render optional summary paragraph" time="0.00033971">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildIntelligenceMindmapSection &gt; should use localized heading for supported languages" time="0.00036294">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildIntelligenceMindmapSection &gt; should allow custom heading override" time="0.000417434">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildIntelligenceMindmapSection &gt; should escape HTML in all node labels and evidence strings" time="0.000526046">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildIntelligenceMindmapSection &gt; should include data-total-nodes, data-connections, data-actors attributes" time="0.000422839">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildIntelligenceMindmapSection &gt; should count nested children in data-total-nodes recursively" time="0.000540205">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildIntelligenceMindmapSection &gt; should use localized Policy Domains aria-label" time="0.000394081">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildIntelligenceMindmapSection &gt; should render child nodes as nested actor overlays using details/summary" time="0.000413473">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildIntelligenceMindmapSection &gt; should not render connections section when connections array is empty" time="0.000250146">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildIntelligenceMindmapSection &gt; should not render actor network section when actorNetwork array is empty" time="0.000309047">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildIntelligenceMindmapSection &gt; should use localized influence label in meter aria-label" time="0.000400825">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildIntelligenceMindmapSection &gt; should not include emoji in actor network aria-label" time="0.000283719">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildIntelligenceMindmapSection &gt; should localize influence label in actor network overlay" time="0.000293531">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildIntelligenceMindmapSection &gt; should not include role=&quot;listitem&quot; on inner node divs (li wrapper provides it)" time="0.000640853">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildIntelligenceMindmapSection &gt; should use &quot;Details&quot; instead of &quot;Key Actors&quot; for child toggle label" time="0.000395924">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildIntelligenceMindmapSection &gt; should localize stakeholder panel aria-label &quot;perspective&quot; suffix" time="0.000305894">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildIntelligenceMindmapSection &gt; should fall back to allNodes when depth-1 layer has zero nodes" time="0.001151184">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildIntelligenceMindmapSection &gt; should honor node.color when it maps to a branch palette key" time="0.000348081">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildIntelligenceMindmapSection &gt; should fall back to category palette for unrecognized color keys" time="0.000289099">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildIntelligenceMindmapSection &gt; should resolve actorNetwork names in connection endpoints" time="0.000424561">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildVotingMindmap &gt; should return null when all data is placeholder" time="0.000558571">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildVotingMindmap &gt; should return null when records and patterns are all placeholder" time="0.000309571">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildVotingMindmap &gt; should return null when patterns are empty but records exist" time="0.00026942">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildVotingMindmap &gt; should build a mindmap from voting data" time="0.002865977">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildVotingMindmap &gt; should mark high-cohesion groups with green color" time="0.000408271">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildVotingMindmap &gt; should mark low-cohesion groups with red color" time="0.000344647">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildVotingMindmap &gt; should not produce connection targets exceeding anomaly actor IDs" time="0.001097597">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildProspectiveMindmap &gt; should build a mindmap from week-ahead data" time="0.001281655">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildProspectiveMindmap &gt; should include bottleneck count in summary" time="0.000287919">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildProspectiveMindmap &gt; should always return a non-null result" time="0.000234947">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildProspectiveMindmap &gt; should use stable pipeline IDs when bottleneck follows non-bottleneck" time="0.000690092">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildBreakingMindmap &gt; should return null for undefined feed data (no activity)" time="0.000531058">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildBreakingMindmap &gt; should build a mindmap from breaking news feed data" time="0.000729521">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildBreakingMindmap &gt; should include connections between related categories" time="0.000225351">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildPropositionsMindmap &gt; should handle null pipeline data" time="0.000798439">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildPropositionsMindmap &gt; should build a mindmap with pipeline stage nodes" time="0.000444147">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildPropositionsMindmap &gt; should mark plenary node green for high health score" time="0.000312604">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildPropositionsMindmap &gt; should mark plenary node red for low health score" time="0.000217837">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildPropositionsMindmap &gt; should include all 5 pipeline stage nodes" time="0.000636677">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildCommitteeMindmap &gt; should return null when all data is placeholder" time="0.000681577">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildCommitteeMindmap &gt; should return null when no committees are active" time="0.000212425">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildCommitteeMindmap &gt; should build a mindmap from committee data" time="0.000570983">
        </testcase>
        <testcase classname="test/unit/mindmap-content.test.js" name="mindmap-content &gt; buildCommitteeMindmap &gt; should include inter-committee connections" time="0.000342167">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/motions-generator.test.js" timestamp="2026-04-14T20:47:06.566Z" hostname="runnervm35a4x" tests="43" failures="0" errors="0" skipped="0" time="0.022261333">
        <testcase classname="test/unit/motions-generator.test.js" name="Motions Generator &gt; getMotionsFallbackData &gt; should return placeholder-marked data when MCP is unavailable" time="0.002130889">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="Motions Generator &gt; getMotionsFallbackData &gt; should mark voting record results as data unavailable" time="0.000577399">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="Motions Generator &gt; getMotionsFallbackData &gt; should use generic placeholder names for MEPs" time="0.000315447">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="Motions Generator &gt; getMotionsFallbackData &gt; should use clearly synthetic group names" time="0.000438625">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="Motions Generator &gt; getMotionsFallbackData &gt; should mark anomaly as illustrative only" time="0.000266029">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="Motions Generator &gt; generateMotionsContent &gt; should return HTML containing required section classes" time="0.000846269">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="Motions Generator &gt; generateMotionsContent &gt; should escape HTML in all MCP-sourced data (XSS prevention)" time="0.000283604">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="Motions Generator &gt; generateMotionsContent &gt; should include vote counts for each voting record" time="0.000216788">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="Motions Generator &gt; generateMotionsContent &gt; should include party cohesion data" time="0.000260731">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="Motions Generator &gt; generateMotionsContent &gt; should render anomalies with safe severity class" time="0.000197602">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="Motions Generator &gt; generateMotionsContent &gt; should coerce non-string severity without throwing" time="0.000875415">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="Motions Generator &gt; generateMotionsContent &gt; should include parliamentary questions section" time="0.000188172">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="Motions Generator &gt; generateMotionsContent &gt; should produce valid HTML structure (fragment check)" time="0.000264117">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="Motions Generator &gt; generateMotionsContent &gt; should render fallback placeholder content without throwing" time="0.000337125">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="Motions Generator &gt; generateMotionsContent &gt; should omit voting-results and voting-patterns sections when all data is placeholder" time="0.000213046">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="Motions Generator &gt; generateMotionsContent &gt; should omit voting-results section when records array is empty" time="0.000182416">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="Motions Generator &gt; generateMotionsContent &gt; should still include voting-results section for real (non-placeholder) data" time="0.000273121">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="Motions Generator &gt; generateMotionsContent &gt; should handle empty arrays gracefully" time="0.000241234">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="Motions Generator &gt; generateMotionsContent &gt; should filter placeholder pattern entries in mixed-data voting-patterns section" time="0.000337598">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="Motions Generator &gt; MOTIONS_TITLES multi-language &gt; should generate title containing the date for all 14 languages" time="0.001566408">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="Motions editorial quality &gt; should not include &quot;Why This Matters&quot; section (replaced by AI-driven analysis)" time="0.000176488">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="Motions editorial quality &gt; should include source attribution in lede" time="0.000168403">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="Motions editorial quality &gt; should include parliamentary context label in party cohesion section" time="0.000125086">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="Motions editorial quality &gt; should include analysis note label in anomalies section" time="0.000154404">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="Motions editorial quality &gt; should use localized editorial strings for French" time="0.000243973">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="Motions multi-language section headings &gt; should use localized section headings for all 14 languages" time="0.00221353">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="Motions multi-language section headings &gt; should use localized labels for Japanese" time="0.000362588">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="Motions multi-language section headings &gt; should use localized labels for Korean" time="0.000199584">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="Motions multi-language section headings &gt; should use localized labels for Chinese" time="0.000198809">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="Motions multi-language section headings &gt; should use localized labels for German" time="0.000250303">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="Motions multi-language section headings &gt; should use localized labels for Arabic" time="0.000358646">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="Motions multi-language section headings &gt; should have MOTIONS_STRINGS for all 14 languages" time="0.001849013">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="buildAdoptedTextsSection &gt; should return empty string for empty array" time="0.000239795">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="buildAdoptedTextsSection &gt; should render adopted texts as HTML section" time="0.000224835">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="buildAdoptedTextsSection &gt; should include lang attribute matching the language parameter" time="0.000129316">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="buildAdoptedTextsSection &gt; should use localized heading for each of the 14 languages" time="0.001657809">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="buildAdoptedTextsSection &gt; should handle unknown language by falling back to English heading" time="0.000183381">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="buildAdoptedTextsSection &gt; should escape HTML in titles to prevent XSS" time="0.000177965">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="buildAdoptedTextsSection &gt; should group texts by date and sort most recent first" time="0.00014963">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="buildAdoptedTextsSection &gt; should use identifier when available as feed-label" time="0.000119355">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="buildAdoptedTextsSection &gt; should fall back to id when identifier is missing" time="0.000191202">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="buildAdoptedTextsSection &gt; should display item count in the description" time="0.000181149">
        </testcase>
        <testcase classname="test/unit/motions-generator.test.js" name="buildAdoptedTextsSection &gt; should use localized fallback date label when item has no date" time="0.000262185">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/news-enhanced-dedup.test.js" timestamp="2026-04-14T20:47:06.571Z" hostname="runnervm35a4x" tests="4" failures="0" errors="0" skipped="0" time="0.004393011">
        <testcase classname="test/unit/news-enhanced-dedup.test.js" name="news-enhanced dedup suffix &gt; should preserve numeric run-scoped suffixes" time="0.002248417">
        </testcase>
        <testcase classname="test/unit/news-enhanced-dedup.test.js" name="news-enhanced dedup suffix &gt; should preserve custom alphanumeric run ids with hyphens" time="0.000227393">
        </testcase>
        <testcase classname="test/unit/news-enhanced-dedup.test.js" name="news-enhanced dedup suffix &gt; should preserve custom run ids combined with dedup suffixes" time="0.00013458">
        </testcase>
        <testcase classname="test/unit/news-enhanced-dedup.test.js" name="news-enhanced dedup suffix &gt; should reject invalid suffix patterns" time="0.000201319">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/news-metadata.test.js" timestamp="2026-04-14T20:47:06.571Z" hostname="runnervm35a4x" tests="15" failures="0" errors="0" skipped="0" time="0.048237264">
        <testcase classname="test/unit/news-metadata.test.js" name="utils/news-metadata &gt; buildMetadataDatabase &gt; should build database from article files" time="0.02086175">
        </testcase>
        <testcase classname="test/unit/news-metadata.test.js" name="utils/news-metadata &gt; buildMetadataDatabase &gt; should extract metadata from filenames" time="0.001498749">
        </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.001246762">
        </testcase>
        <testcase classname="test/unit/news-metadata.test.js" name="utils/news-metadata &gt; buildMetadataDatabase &gt; should handle empty news directory" time="0.001061156">
        </testcase>
        <testcase classname="test/unit/news-metadata.test.js" name="utils/news-metadata &gt; buildMetadataDatabase &gt; should skip non-article files" time="0.001451515">
        </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.002030828">
        </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.000652567">
        </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.00091579">
        </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.002098685">
        </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.004360768">
        </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.001716344">
        </testcase>
        <testcase classname="test/unit/news-metadata.test.js" name="utils/news-metadata &gt; updateIntelligenceIndex &gt; should prune deleted articles when rebuilt" time="0.00260273">
        </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.001675304">
        </testcase>
        <testcase classname="test/unit/news-metadata.test.js" name="utils/news-metadata &gt; updateIntelligenceIndex &gt; should handle empty news directory" time="0.001030042">
        </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.001546544">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/pipeline-stages.test.js" timestamp="2026-04-14T20:47:06.573Z" hostname="runnervm35a4x" tests="208" failures="0" errors="0" skipped="0" time="0.433199282">
        <testcase classname="test/unit/pipeline-stages.test.js" name="CircuitBreaker &gt; starts in CLOSED state and allows requests" time="0.002045343">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="CircuitBreaker &gt; opens the circuit after reaching the failure threshold" time="0.001260392">
            <system-err>
⚡ Circuit breaker OPEN after 3 consecutive failures

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="CircuitBreaker &gt; transitions to HALF_OPEN after the reset timeout" time="0.000413277">
            <system-err>
⚡ Circuit breaker OPEN after 1 consecutive failures

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="CircuitBreaker &gt; closes the circuit on success" time="0.000349453">
            <system-err>
⚡ Circuit breaker OPEN after 1 consecutive failures

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="CircuitBreaker &gt; resets consecutive failures on success" time="0.000281272">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="CircuitBreaker &gt; allows a custom failure threshold" time="0.00025914">
            <system-err>
⚡ Circuit breaker OPEN after 2 consecutive failures

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="CircuitBreaker &gt; getStats returns current state snapshot" time="0.000157586">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="CircuitBreaker &gt; HALF_OPEN allows only one probe — second canRequest() returns false" time="0.000370823">
            <system-err>
⚡ Circuit breaker OPEN after 1 consecutive failures

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="CircuitBreaker &gt; HALF_OPEN failure immediately re-opens the circuit" time="0.000498555">
            <system-err>
⚡ Circuit breaker OPEN after 1 consecutive failures
⚡ Circuit breaker OPEN after 2 consecutive failures

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="CircuitBreaker &gt; HALF_OPEN probe-slot is freed after recordSuccess so circuit closes" time="0.00032873">
            <system-err>
⚡ Circuit breaker OPEN after 1 consecutive failures

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="validateMCPResponse &gt; returns valid=true for a well-formed MCP response" time="0.001060887">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="validateMCPResponse &gt; returns valid=false for null" time="0.000354966">
            <system-err>
⚠️ MCP validation failed for test_tool: response is null/undefined

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="validateMCPResponse &gt; returns valid=false for undefined" time="0.000269033">
            <system-err>
⚠️ MCP validation failed for test_tool: response is null/undefined

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="validateMCPResponse &gt; returns valid=false for a plain string" time="0.000322679">
            <system-err>
⚠️ MCP validation failed for test_tool: Expected object, got string

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="validateMCPResponse &gt; returns valid=false when content array is missing" time="0.000385628">
            <system-err>
⚠️ MCP validation failed for test_tool: Missing or invalid &apos;content&apos; array

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="validateMCPResponse &gt; returns valid=false when content array is empty" time="0.000320245">
            <system-err>
⚠️ MCP validation failed for test_tool: Empty content array

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="validateMCPResponse &gt; returns valid=false when first content item lacks text field" time="0.000387134">
            <system-err>
⚠️ MCP validation failed for test_tool: First content item is missing a &apos;text&apos; string field

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="validateMCPResponse &gt; returns valid=false for array input" time="0.000273992">
            <system-err>
⚠️ MCP validation failed for test_tool: Expected object, got array

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="validateMCPResponse &gt; returns valid=false when first content item is null" time="0.000256744">
            <system-err>
⚠️ MCP validation failed for test_tool: First content item is missing a &apos;text&apos; string field

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="validateMCPResponse &gt; returns valid=false when first content item is undefined" time="0.000296708">
            <system-err>
⚠️ MCP validation failed for test_tool: First content item is missing a &apos;text&apos; string field

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="normalizeISO8601Date &gt; returns YYYY-MM-DD for a valid ISO date string" time="0.000329302">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="normalizeISO8601Date &gt; passes through a date already in YYYY-MM-DD format" time="0.000118013">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="normalizeISO8601Date &gt; returns the original string for an unparseable date" time="0.000090531">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="normalizeISO8601Date &gt; returns the original string for an empty string" time="0.00008145">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="sanitizeText &gt; trims leading and trailing whitespace" time="0.000173093">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="sanitizeText &gt; collapses internal multiple spaces to one" time="0.000134248">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="sanitizeText &gt; collapses tabs and newlines to a space" time="0.000139911">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="sanitizeText &gt; returns empty string unchanged" time="0.000121479">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="isValidCountryCode &gt; accepts a valid two-letter uppercase code" time="0.000276583">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="isValidCountryCode &gt; rejects lowercase" time="0.000141171">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="isValidCountryCode &gt; rejects single-letter codes" time="0.000122109">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="isValidCountryCode &gt; rejects three-letter codes" time="0.000142897">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="isValidLanguageCode &gt; accepts a valid two-letter lowercase code" time="0.000251454">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="isValidLanguageCode &gt; rejects uppercase" time="0.000130717">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="writeArticleFile &gt; writes the file when neither dryRun nor skipExisting" time="0.002617697">
            <system-out>
  ✅ Wrote: test.html

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="writeArticleFile &gt; does not write in dryRun mode and returns null" time="0.000863561">
            <system-out>
  [DRY RUN] Would write: dry.html

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="writeArticleFile &gt; skips an existing file when skipExisting is true" time="0.000682646">
            <system-out>
  ⏭️  Skipped (already exists): existing.html

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="writeArticleFile &gt; overwrites existing file when skipExisting is false (dedup is at slug level, not file level)" time="0.000838342">
            <system-out>
  ✅ Wrote: overwrite.html

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="writeSingleArticle &gt; increments stats.generated when article is written" time="0.001590493">
            <system-out>
  ✅ Wrote: 2025-01-15-week-ahead-en.html

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="writeSingleArticle &gt; increments stats.dryRun when dryRun is true" time="0.000530209">
            <system-out>
  [DRY RUN] Would write: 2025-01-15-week-ahead-de.html

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="writeSingleArticle &gt; increments stats.skipped when file already exists and skipExisting is true" time="0.000682112">
            <system-out>
  ⏭️  Skipped (already exists): 2025-01-15-week-ahead-fr.html

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="writeGenerationMetadata &gt; writes a JSON metadata file when dryRun is false" time="0.001673735">
            <system-out>
📝 Metadata written to: /tmp/ep-meta-eXOUjo/generation-2026-04-14.json

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="writeGenerationMetadata &gt; does not write anything when dryRun is true" time="0.000451911">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="writeGenerationMetadata &gt; serialises results array into the metadata file" time="0.000941481">
            <system-out>
📝 Metadata written to: /tmp/ep-meta-nZZIky/generation-2026-04-14.json

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="writeGenerationMetadata &gt; merges stats and results when a metadata file already exists for the same day" time="0.003680362">
            <system-out>
📝 Metadata written to: /tmp/ep-meta-9svggY/generation-2025-01-15.json

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="writeGenerationMetadata &gt; deduplicates results by slug when re-running the same strategy" time="0.001438278">
            <system-out>
📝 Metadata written to: /tmp/ep-meta-3E4DWC/generation-2025-01-15.json

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="createStrategyRegistry &gt; registers all eight built-in article categories" time="0.147346499">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="createStrategyRegistry &gt; returns different instances on each call" time="0.001422787">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="initializeMCPClient &gt; returns null when useMCP is false" time="0.000659776">
            <system-out>
  ℹ️ MCP client disabled via USE_EP_MCP=false

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchWeekAheadData with null client &gt; returns placeholder events when client is null" time="0.001309744">
            <system-out>
  ℹ️ MCP unavailable — using placeholder events

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchWeekAheadData with null client &gt; sets event date to dateRange.start" time="0.000354223">
            <system-out>
  ℹ️ MCP unavailable — using placeholder events

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchVotingAnomalies with null client &gt; returns empty string when client is null" time="0.000282286">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchCoalitionDynamics with null client &gt; returns empty string when client is null" time="0.000295361">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchVotingReport with null client &gt; returns empty string when client is null" time="0.000570183">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchMEPInfluence with null client or empty mepId &gt; returns empty string when client is null" time="0.000279659">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchMEPInfluence with null client or empty mepId &gt; returns empty string when mepId is empty" time="0.00018029">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchCommitteeData with null client &gt; returns default result when client is null" time="0.000662235">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchCommitteeData with null client &gt; includes abbreviation in name" time="0.00022959">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchVotingRecords with null client &gt; returns empty array when client is null" time="0.000257983">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchVotingPatterns with null client &gt; returns empty array when client is null" time="0.000222644">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchMotionsAnomalies with null client &gt; returns empty array when client is null" time="0.000197132">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchParliamentaryQuestionsForMotions with null client &gt; returns empty array when client is null" time="0.000186186">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchMotionsData with null client &gt; returns fallback data with placeholder arrays when client is null" time="0.000591705">
            <system-out>
  ℹ️ Using placeholder voting records
  ℹ️ Using placeholder voting patterns
  ℹ️ Using placeholder voting anomalies
  ℹ️ Using placeholder parliamentary questions

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchProposalsFromMCP with null client &gt; returns empty html and procedureId when client is null" time="0.000288669">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchPipelineFromMCP with null client &gt; returns null when client is null" time="0.000234591">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchProcedureStatusFromMCP with null client or empty procedureId &gt; returns empty string when client is null" time="0.000175555">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchProcedureStatusFromMCP with null client or empty procedureId &gt; returns empty string when procedureId is empty" time="0.000093536">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchAdoptedTextsFeed with null client &gt; returns empty array when client is null" time="0.000180755">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchEventsFeed with null client &gt; returns empty array when client is null" time="0.000309316">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchProceduresFeed with null client &gt; returns empty array when client is null" time="0.000273444">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchMEPsFeed with null client &gt; returns empty array when client is null" time="0.000284223">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchBreakingNewsFeedData with null client &gt; returns undefined when client is null (MCP unavailable)" time="0.000211871">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchBreakingNewsFeedData with circuit breaker OPEN &gt; returns undefined when circuit breaker is OPEN" time="0.000279384">
            <system-err>
⚡ Circuit breaker OPEN after 3 consecutive failures
  ⚠️ Circuit breaker OPEN — treating as MCP unavailable for breaking news feeds

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchDocumentsFeed with null client &gt; returns empty array when client is null" time="0.000255373">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchPlenaryDocumentsFeed with null client &gt; returns empty array when client is null" time="0.000307045">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchCommitteeDocumentsFeed with null client &gt; returns empty array when client is null" time="0.000285041">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchPlenarySessionDocumentsFeed with null client &gt; returns empty array when client is null" time="0.000195762">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchExternalDocumentsFeed with null client &gt; returns empty array when client is null" time="0.000237768">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchQuestionsFeed with null client &gt; returns empty array when client is null" time="0.000291779">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchDeclarationsFeed with null client &gt; returns empty array when client is null" time="0.000211069">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchCorporateBodiesFeed with null client &gt; returns empty array when client is null" time="0.000180812">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchEPFeedData with null client &gt; returns undefined when client is null" time="0.000231969">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchEPFeedData with circuit breaker OPEN &gt; returns undefined when circuit breaker is OPEN" time="0.000248445">
            <system-err>
⚡ Circuit breaker OPEN after 3 consecutive failures
  ⚠️ Circuit breaker OPEN — treating as MCP unavailable for EP feeds

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="feed fetchers accept timeframe parameter &gt; fetchAdoptedTextsFeed accepts timeframe" time="0.000207587">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="feed fetchers accept timeframe parameter &gt; fetchEventsFeed accepts timeframe" time="0.000128268">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="feed fetchers accept timeframe parameter &gt; fetchProceduresFeed accepts timeframe" time="0.000111571">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="feed fetchers accept timeframe parameter &gt; fetchMEPsFeed accepts timeframe" time="0.000127653">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="feed fetchers accept timeframe parameter &gt; fetchDocumentsFeed accepts timeframe" time="0.0001264">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="feed fetchers accept timeframe parameter &gt; fetchBreakingNewsFeedData accepts timeframe" time="0.000105508">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="feed fetchers accept timeframe parameter &gt; fetchEPFeedData accepts timeframe" time="0.000102166">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="upstream timeout detection in feed fetchers &gt; fetchAdoptedTextsFeed returns empty on upstream timeout without widening timeframe" time="0.00127511">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="upstream timeout detection in feed fetchers &gt; fetchEventsFeed returns empty on upstream timeout without widening" time="0.000573799">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="upstream timeout detection in feed fetchers &gt; fetchProceduresFeed returns empty on upstream timeout without widening" time="0.000640978">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="generateArticleForStrategy &gt; returns success=true and writes files with null client" time="0.041154923">
            <system-out>
📅 Generating week-ahead article...
  📆 Date range: 2026-04-15 to 2026-04-22
  ℹ️ MCP unavailable — using placeholder events

  🌐 Generating EN version...
  📊 EN quality: Grade D (68/100)
  ✅ Wrote: 2026-04-14-week-ahead-en.html
  ✅ EN version generated
  ✅ week-ahead article generated: 1/1 language(s) written

            </system-out>
            <system-err>
  ⚠️  EN content warning: Cross-reference density too low: 0 EP document reference(s) found (minimum 2 required)
  ⚠️  EN article did not pass quality gate (score 68 &lt; 40). Recommendations:
       💡 Increase article depth to 1500 words for maximum word-count score (currently 746)
       💡 Provide historical context: compare to previous parliamentary terms, cite precedents or earlier decisions
       💡 Support conclusions with specific data: cite vote counts, attendance figures, or referenced EP documents

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="generateArticleForStrategy &gt; returns success=true with dryRun mode and no files written" time="0.022067706">
            <system-out>
🚨 Generating breaking article...

  ⚠️ MCP unavailable — no feed data or analytical context

  🌐 Generating EN version...
  📊 EN quality: Grade D (62/100)
  [DRY RUN] Would write: 2026-04-14-breaking-en.html
  🌐 Generating DE version...
  📊 DE quality: Grade D (61/100)
  [DRY RUN] Would write: 2026-04-14-breaking-de.html
  ✅ breaking article generation completed: 0 files written (dry-run or all files skipped)

            </system-out>
            <system-err>
  ⚠️  EN content warning: Cross-reference density too low: 0 EP document reference(s) found (minimum 2 required)
  ⚠️  EN article did not pass quality gate (score 62 &lt; 40). Recommendations:
       💡 Increase article depth to 1500 words for maximum word-count score (currently 590)
       💡 Provide historical context: compare to previous parliamentary terms, cite precedents or earlier decisions
       💡 Support conclusions with specific data: cite vote counts, attendance figures, or referenced EP documents
  ⚠️  DE content warning: Keywords for &quot;de&quot; article appear to be entirely in English — consider localizing
  ⚠️  DE content warning: Cross-reference density too low: 0 EP document reference(s) found (minimum 2 required)
  ⚠️  DE content warning: Temporal coverage: article lacks forward-looking content — add forecasts, scenarios, or outlook sections for actionable intelligence
  🌐 DE Translation quality: found 5 likely untranslated English phrase(s): coalition-building strategies, regulatory implications, democratic participation
  ⚠️  DE article did not pass quality gate (score 61 &lt; 40). Recommendations:
       💡 Expand article length to at least 500 words to improve word-count score
       💡 Add a mindmap to illustrate relationships and conceptual structure
       💡 Increase evidence references to 10 for maximum evidence score (currently 6)

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="generateArticleForStrategy &gt; returns success=true with multiple languages and null client" time="0.020641043">
            <system-out>
🗳️ Generating motions article...

  ℹ️ Using placeholder voting records
  ℹ️ Using placeholder voting patterns
  ℹ️ Using placeholder voting anomalies
  ℹ️ Using placeholder parliamentary questions

  🌐 Generating EN version...
  📊 EN quality: Grade D (61/100)
  ✅ Wrote: 2026-04-14-motions-en.html
  ✅ EN version generated
  🌐 Generating SV version...
  📊 SV quality: Grade D (56/100)
  ✅ Wrote: 2026-04-14-motions-sv.html
  ✅ SV version generated
  🌐 Generating DE version...
  📊 DE quality: Grade D (56/100)
  ✅ Wrote: 2026-04-14-motions-de.html
  ✅ DE version generated
  ✅ motions article generated: 3/3 language(s) written

            </system-out>
            <system-err>
  ⚠️  EN content warning: Cross-reference density too low: 0 EP document reference(s) found (minimum 2 required)
  ⚠️  EN article did not pass quality gate (score 61 &lt; 40). Recommendations:
       💡 Increase article depth to 1500 words for maximum word-count score (currently 560)
       💡 Provide historical context: compare to previous parliamentary terms, cite precedents or earlier decisions
       💡 Include forward-looking analysis: describe at least two scenarios (e.g. &quot;if the amendment passes&quot; vs &quot;if rejected&quot;)
  ⚠️  SV content warning: Cross-reference density too low: 0 EP document reference(s) found (minimum 2 required)
  ⚠️  SV content warning: Temporal coverage: article lacks forward-looking content — add forecasts, scenarios, or outlook sections for actionable intelligence
  🌐 SV Translation quality: found 5 likely untranslated English phrase(s): coalition-building strategies, regulatory implications, democratic participation
  ⚠️  SV article did not pass quality gate (score 56 &lt; 40). Recommendations:
       💡 Expand article length to at least 500 words to improve word-count score
       💡 Add a data dashboard with key metrics for quantitative support
       💡 Add a mindmap to illustrate relationships and conceptual structure
  ⚠️  DE content warning: Keywords for &quot;de&quot; article appear to be entirely in English — consider localizing
  ⚠️  DE content warning: Cross-reference density too low: 0 EP document reference(s) found (minimum 2 required)
  ⚠️  DE content warning: Temporal coverage: article lacks forward-looking content — add forecasts, scenarios, or outlook sections for actionable intelligence
  🌐 DE Translation quality: found 5 likely untranslated English phrase(s): coalition-building strategies, regulatory implications, democratic participation
  ⚠️  DE article did not pass quality gate (score 56 &lt; 40). Recommendations:
       💡 Expand article length to at least 500 words to improve word-count score
       💡 Add a data dashboard with key metrics for quantitative support
       💡 Add a mindmap to illustrate relationships and conceptual structure

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="generateArticleForStrategy &gt; returns success=false and increments stats.errors when fetchData throws" time="0.002217428">
            <system-out>
📅 Generating week-ahead article...

            </system-out>
            <system-err>
❌ Error generating week-ahead: MCP timeout

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="generateArticleForStrategy &gt; returns success=true with empty languages array" time="0.001633279">
            <system-out>
📜 Generating propositions article...

  ℹ️ No proposals from MCP — pipeline article will be data-free

  ✅ propositions article generation completed: 0 files written (dry-run or all files skipped)

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="generateArticleForStrategy &gt; increments stats.skipped by languages.length when shouldSkip returns true" time="0.000970781">
            <system-out>
🏛️ Generating committee-reports article...

  ⚠️  committee-reports article skipped: all fetched data is placeholder (MCP unavailable or API gap). No files written.

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchVotingAnomalies with mock client &gt; returns empty string when client returns undefined" time="0.000256505">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchCoalitionDynamics with mock client &gt; returns empty string when client returns undefined" time="0.000201295">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchVotingReport with mock client &gt; returns empty string when client returns undefined" time="0.000288169">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchVotingRecords with mock client &gt; returns empty array when client returns undefined" time="0.000351392">
            <system-out>
  📡 Fetching voting records from MCP server...

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchVotingPatterns with mock client &gt; returns empty array when client returns undefined" time="0.000324713">
            <system-out>
  📡 Fetching voting patterns from MCP server...

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchMotionsAnomalies with mock client &gt; returns empty array when client returns undefined" time="0.000506297">
            <system-out>
  📡 Fetching voting anomalies from MCP server...

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchParliamentaryQuestionsForMotions with mock client &gt; returns empty array when client returns undefined" time="0.000519819">
            <system-out>
  📡 Fetching parliamentary questions from MCP server...

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchProposalsFromMCP with mock client &gt; returns empty html when client returns undefined" time="0.000751073">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchPipelineFromMCP with mock client &gt; returns null when client returns undefined" time="0.00025726">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchProcedureStatusFromMCP with mock client &gt; returns empty string when client returns undefined" time="0.000207882">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchCommitteeData with mock client &gt; returns committee data with defaults when client returns undefined" time="0.001542789">
            <system-out>
  📡 Fetching committee info for LIBE...

  📡 Fetching documents for LIBE...

  ℹ️ Committee LIBE still placeholder after MCP — trying EP v2 API directly...

            </system-out>
            <system-err>
  ⚠️ analyzeLegislativeEffectiveness failed for LIBE: client.analyzeLegislativeEffectiveness is not a function

  ⚠️ EP API direct lookup for LIBE returned 503

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetch-stage error paths with throwing client &gt; fetchVotingAnomalies returns empty string when client throws" time="0.000794649">
            <system-err>
  ⚠️ detect_voting_anomalies failed: MCP call failed

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetch-stage error paths with throwing client &gt; fetchCoalitionDynamics returns empty string when client throws" time="0.001698704">
            <system-err>
  ⚠️ analyze_coalition_dynamics failed: MCP call failed

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetch-stage error paths with throwing client &gt; fetchVotingReport returns empty string when client throws" time="0.000400248">
            <system-err>
  ⚠️ generate_report failed: MCP call failed

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetch-stage error paths with throwing client &gt; fetchMEPInfluence returns empty string when client throws" time="0.000408762">
            <system-err>
  ⚠️ assess_mep_influence failed: MCP call failed

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetch-stage error paths with throwing client &gt; fetchCommitteeData returns default result when client throws" time="0.001190057">
            <system-out>
  📡 Fetching committee info for ENVI...

  📡 Fetching documents for ENVI...

  ℹ️ Committee ENVI still placeholder after MCP — trying EP v2 API directly...

            </system-out>
            <system-err>
  ⚠️ getCommitteeInfo failed for ENVI: MCP call failed

  ⚠️ searchDocuments failed for ENVI: MCP call failed

⚡ Circuit breaker OPEN after 3 consecutive failures

  ⚠️ analyzeLegislativeEffectiveness failed for ENVI: MCP call failed

  ⚠️ EP API direct lookup for ENVI returned 503

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetch-stage error paths with throwing client &gt; fetchProcedureStatusFromMCP returns empty string when client throws" time="0.000452437">
            <system-err>
  ⚠️ track_legislation failed: MCP call failed

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="generateArticleForStrategy DEBUG mode &gt; logs stack trace in DEBUG mode when strategy throws Error with stack" time="0.001250441">
            <system-out>
🚨 Generating breaking article...

            </system-out>
            <system-err>
❌ Error generating breaking: debug test error
   Stack: Error: debug test error
    at /home/runner/work/euparliamentmonitor/euparliamentmonitor/test/unit/pipeline-stages.test.js:1326:24
    at processTicksAndRejections (node:internal/process/task_queues:104:5)
    at file:///home/runner/work/euparliamentmonitor/euparliamentmonitor/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchWeekAheadData with data-returning mock client &gt; returns parsed events when client returns valid session data" time="0.001232659">
            <system-out>
  📡 Fetching week-ahead data from MCP (parallel)...

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchVotingRecords with data-returning mock client &gt; returns parsed voting records when client returns valid data" time="0.000723831">
            <system-out>
  📡 Fetching voting records from MCP server...

  ✅ Fetched 1 voting records from MCP

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchVotingPatterns with data-returning mock client &gt; returns parsed voting patterns when client returns valid data" time="0.000557205">
            <system-out>
  📡 Fetching voting patterns from MCP server...

  ✅ Fetched 1 voting patterns from MCP

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchMotionsAnomalies with data-returning mock client &gt; returns parsed anomalies when client returns valid data" time="0.000518997">
            <system-out>
  📡 Fetching voting anomalies from MCP server...

  ✅ Fetched 1 voting anomalies from MCP

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchMotionsData with data-returning mock client &gt; returns real data without applying fallbacks when client returns data" time="0.001227955">
            <system-out>
  📡 Fetching voting records from MCP server...
  📡 Fetching voting patterns from MCP server...
  📡 Fetching voting anomalies from MCP server...
  📡 Fetching parliamentary questions from MCP server...

  ✅ Fetched 1 voting records from MCP
  ✅ Fetched 1 voting patterns from MCP
  ✅ Fetched 1 voting anomalies from MCP

  ℹ️ Using placeholder parliamentary questions

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchProposalsFromMCP with data-returning mock client &gt; returns HTML with proposal cards and firstProcedureId" time="0.000875796">
            <system-out>
  ✅ Fetched 2 proposals from MCP

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchProposalsFromMCP with data-returning mock client &gt; returns empty firstProcedureId when no document has procedure-style id" time="0.000505324">
            <system-out>
  ✅ Fetched 1 proposals from MCP

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchProposalsFromMCP with data-returning mock client &gt; returns empty when documents array is empty" time="0.0003662">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchPipelineFromMCP with data-returning mock client &gt; returns structured pipeline data with procedures" time="0.00076559">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchPipelineFromMCP with data-returning mock client &gt; returns null when parsed data is null (invalid JSON)" time="0.000387579">
            <system-err>
  ⚠️ Failed to parse JSON for pipeline

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchProcedureStatusFromMCP with data-returning mock client &gt; returns pre-formatted HTML when client returns data" time="0.000374561">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchParliamentaryQuestionsForMotions with data-returning mock client &gt; returns parsed questions with fallback fields" time="0.000795428">
            <system-out>
  📡 Fetching parliamentary questions from MCP server...

  ✅ Fetched 2 parliamentary questions from MCP

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchVotingRecords with partial data mock client &gt; applies default values for missing record fields" time="0.001210331">
            <system-out>
  📡 Fetching voting records from MCP server...

  ✅ Fetched 2 voting records from MCP

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchVotingPatterns with partial data mock client &gt; applies default values for missing pattern fields" time="0.001021243">
            <system-out>
  📡 Fetching voting patterns from MCP server...

  ✅ Fetched 1 voting patterns from MCP

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchMotionsAnomalies with partial data mock client &gt; applies default values for missing anomaly fields" time="0.000937384">
            <system-out>
  📡 Fetching voting anomalies from MCP server...

  ✅ Fetched 1 voting anomalies from MCP

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchWeekAheadData with circuit breaker OPEN &gt; returns placeholder events when circuit breaker is OPEN" time="0.000702215">
            <system-err>
⚡ Circuit breaker OPEN after 3 consecutive failures
  ⚠️ Circuit breaker not accepting requests (OPEN) — using placeholder events

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="generateArticleForStrategy with non-Error throw &gt; handles non-Error throw and converts to string" time="0.001325577">
            <system-out>
🚨 Generating breaking article...

            </system-out>
            <system-err>
❌ Error generating breaking: string error

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchWeekAheadData with HALF_OPEN probe semantics &gt; re-opens circuit when any fetch rejects in HALF_OPEN state" time="0.000607971">
            <system-err>
⚡ Circuit breaker OPEN after 3 consecutive failures
  ⚠️ Circuit breaker not accepting requests (OPEN) — using placeholder events

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchVotingRecords with throwing client &gt; returns empty array when client throws" time="0.000768362">
            <system-out>
  📡 Fetching voting records from MCP server...

            </system-out>
            <system-err>
  ⚠️ MCP voting records fetch failed: MCP call failed

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchVotingPatterns with throwing client &gt; returns empty array when client throws" time="0.000787049">
            <system-out>
  📡 Fetching voting patterns from MCP server...

            </system-out>
            <system-err>
  ⚠️ MCP voting patterns fetch failed: MCP call failed

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchMotionsAnomalies with throwing client &gt; returns empty array when client throws" time="0.000763373">
            <system-out>
  📡 Fetching voting anomalies from MCP server...

            </system-out>
            <system-err>
  ⚠️ MCP voting anomalies fetch failed: MCP call failed

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchParliamentaryQuestionsForMotions with throwing client &gt; returns empty array when client throws" time="0.000808772">
            <system-out>
  📡 Fetching parliamentary questions from MCP server...

            </system-out>
            <system-err>
  ⚠️ MCP parliamentary questions fetch failed: MCP call failed

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="loadFeedDataFromFile &gt; should return undefined for non-existent file" time="0.000949378">
            <system-err>
  ⚠️ Feed data file not found: /tmp/feed-data-test-1GHtic/does-not-exist.json

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="loadFeedDataFromFile &gt; should return undefined for invalid JSON" time="0.000847888">
            <system-err>
  ⚠️ Failed to load feed data from file: Unexpected token &apos;o&apos;, &quot;not valid json&quot; is not valid JSON

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="loadFeedDataFromFile &gt; should return undefined for non-object JSON (array)" time="0.000764468">
            <system-err>
  ⚠️ Feed data file must contain a JSON object

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="loadFeedDataFromFile &gt; should return undefined for JSON null" time="0.000902991">
            <system-err>
  ⚠️ Feed data file must contain a JSON object

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="loadFeedDataFromFile &gt; should return feed data with defaults for missing keys" time="0.001236128">
            <system-out>
  ℹ️ Loaded feed data from file: 0 adopted texts, 0 events, 0 procedures, 0 MEP updates

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="loadFeedDataFromFile &gt; should load valid feed data from file" time="0.001483882">
            <system-out>
  ℹ️ Loaded feed data from file: 1 adopted texts, 1 events, 0 procedures, 1 MEP updates

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="loadFeedDataFromFile &gt; should ignore non-array values for feed keys" time="0.000843353">
            <system-out>
  ℹ️ Loaded feed data from file: 0 adopted texts, 0 events, 0 procedures, 0 MEP updates

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="loadFeedDataFromFile &gt; should filter out non-object items and coerce missing fields to strings" time="0.00165154">
            <system-out>
  ℹ️ Loaded feed data from file: 2 adopted texts, 1 events, 0 procedures, 1 MEP updates

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="loadFeedDataFromFile &gt; should filter loaded breaking feed items to the requested date range" time="0.001443126">
            <system-out>
  ℹ️ Filtered MEP updates to 0/1 items within 2026-03-04..2026-03-04
  ℹ️ Filtered adopted texts to 1/2 items within 2026-03-04..2026-03-04
  ℹ️ Filtered procedures to 0/1 items within 2026-03-04..2026-03-04
  ℹ️ Loaded feed data from file: 1 adopted texts, 1 events, 0 procedures, 0 MEP updates

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="loadEPFeedDataFromFile &gt; should return undefined for non-existent file" time="0.000978029">
            <system-err>
  ⚠️ EP feed data file not found: /tmp/ep-feed-data-test-b4DPrs/does-not-exist.json

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="loadEPFeedDataFromFile &gt; should return undefined for invalid JSON" time="0.000829466">
            <system-err>
  ⚠️ Failed to load EP feed data from file: Unexpected token &apos;o&apos;, &quot;not valid json&quot; is not valid JSON

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="loadEPFeedDataFromFile &gt; should return undefined for non-object JSON (array)" time="0.000789124">
            <system-err>
  ⚠️ EP feed data file must contain a JSON object

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="loadEPFeedDataFromFile &gt; should return EPFeedData with defaults for missing keys" time="0.001339738">
            <system-out>
  ℹ️ Loaded EP feed data from file: 0 total items across 12 keys

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="loadEPFeedDataFromFile &gt; should load valid comprehensive EP feed data" time="0.00161105">
            <system-out>
  ℹ️ Loaded EP feed data from file: 6 total items across 12 keys

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="loadEPFeedDataFromFile &gt; should ignore non-array values for feed keys" time="0.000960035">
            <system-out>
  ℹ️ Loaded EP feed data from file: 0 total items across 12 keys

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="loadEPFeedDataFromFile &gt; should filter out non-object items and coerce missing fields to strings" time="0.001415367">
            <system-out>
  ℹ️ Loaded EP feed data from file: 4 total items across 12 keys

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="loadEPFeedDataFromFile &gt; should filter loaded EP feed items to the requested date range" time="0.002727747">
            <system-out>
  ℹ️ Filtered adopted texts to 1/2 items within 2026-03-01..2026-03-07
  ℹ️ Filtered procedures to 0/1 items within 2026-03-01..2026-03-07
  ℹ️ Filtered plenary documents to 0/1 items within 2026-03-01..2026-03-07
  ℹ️ Filtered declarations to 0/1 items within 2026-03-01..2026-03-07
  ℹ️ Loaded EP feed data from file: 6 total items across 12 keys

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchEPFeedData with pre-fetched file &gt; uses pre-fetched EP feed data when EP_FEED_DATA_FILE is set" time="0.000916287">
            <system-out>
  ℹ️ Loaded EP feed data from file: 1 total items across 12 keys

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchEPFeedData with pre-fetched file &gt; filters pre-fetched EP feed data to the supplied article window" time="0.001407352">
            <system-out>
  ℹ️ Filtered adopted texts to 1/2 items within 2026-03-01..2026-03-07
  ℹ️ Loaded EP feed data from file: 2 total items across 12 keys

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchEPFeedData with pre-fetched file &gt; falls through to MCP when file does not exist" time="0.003457729">
            <system-out>
  ⚠️ Pre-fetched EP feed data failed to load — falling through to MCP fetch

            </system-out>
            <system-err>
  ⚠️ EP feed data file not found: /tmp/nonexistent-ep-feed.json

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchEPFeedData with pre-fetched file &gt; returns undefined when no file and client is null" time="0.000238569">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="loadCommitteeDataFromFile &gt; should return undefined for non-existent file" time="0.000806517">
            <system-err>
  ⚠️ Committee data file not found: /tmp/committee-data-test-NwvUp2/does-not-exist.json

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="loadCommitteeDataFromFile &gt; should return undefined for invalid JSON" time="0.000636111">
            <system-err>
  ⚠️ Failed to load committee data from file: Unexpected token &apos;o&apos;, &quot;not valid json&quot; is not valid JSON

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="loadCommitteeDataFromFile &gt; should return undefined for non-object JSON (array)" time="0.00058974">
            <system-err>
  ⚠️ Committee data file must contain a JSON object

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="loadCommitteeDataFromFile &gt; should return undefined when committee key is missing" time="0.000507806">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="loadCommitteeDataFromFile &gt; should load valid committee data from file" time="0.002054805">
            <system-out>
  ℹ️ Loaded committee data from file: Environment Committee (1 documents)

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="loadCommitteeDataFromFile &gt; should use defaults for missing fields" time="0.000988126">
            <system-out>
  ℹ️ Loaded committee data from file: ECON Committee (0 documents)

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="loadCommitteeDataFromFile &gt; should filter out non-object document entries and coerce missing fields" time="0.001031203">
            <system-out>
  ℹ️ Loaded committee data from file: Civil Liberties (2 documents)

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchCommitteeData with pre-fetched file &gt; uses pre-fetched committee data when EP_COMMITTEE_DATA_FILE is set" time="0.001262559">
            <system-out>
  ℹ️ Loaded committee data from file: Environment Committee (1 documents)

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchCommitteeData with pre-fetched file &gt; falls through to default when committee entry is missing" time="0.000903983">
            <system-err>
  ⚠️ Committee data for ENVI not found in file — falling through to MCP fetch

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchCommitteeData with pre-fetched file &gt; falls through to default when file has malformed JSON" time="0.000857461">
            <system-err>
  ⚠️ Failed to load committee data from file: Unexpected token &apos;o&apos;, &quot;not valid json&quot; is not valid JSON
  ⚠️ Committee data for ENVI not found in file — falling through to MCP fetch

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchCommitteeData with pre-fetched file &gt; returns default result when env var is not set and client is null" time="0.000438233">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchMEPsFeedWithTotal with null client &gt; returns empty items and total 0 when client is null" time="0.001289799">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchMEPsFeedWithTotal with null client &gt; accepts an optional timeframe parameter" time="0.000255887">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchMEPsFeedWithTotal — total parsing via mock client &gt; returns total from API response when total field is present" time="0.001145963">
            <system-out>
  📡 Fetching MEPs feed (one-day)...

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchMEPsFeedWithTotal — total parsing via mock client &gt; returns total 0 when API response has no total field" time="0.000736915">
            <system-out>
  📡 Fetching MEPs feed (one-day)...

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchMEPsFeedWithTotal — total parsing via mock client &gt; returns total 0 when API response total is not a number" time="0.000716653">
            <system-out>
  📡 Fetching MEPs feed (one-day)...

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchMEPsFeedWithTotal — total parsing via mock client &gt; returns total 0 and empty items when API response is empty content" time="0.000666184">
            <system-out>
  📡 Fetching MEPs feed (one-day)...

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="fetchMEPsFeedWithTotal — total parsing via mock client &gt; returns empty items and total 0 when client throws" time="0.000879833">
            <system-out>
  📡 Fetching MEPs feed (one-day)...

            </system-out>
            <system-err>
  ⚠️ get_meps_feed failed: network error

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="filterBreakingNewsFeedDataByDateRange clears totalMEPUpdates on date-range filter &gt; clears totalMEPUpdates when a date-range filter is applied" time="0.001140711">
            <system-out>
  ℹ️ Filtered MEP updates to 1/2 items within 2026-03-10..2026-03-10
  ℹ️ Loaded feed data from file: 0 adopted texts, 0 events, 0 procedures, 1 MEP updates

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="filterBreakingNewsFeedDataByDateRange clears totalMEPUpdates on date-range filter &gt; preserves totalMEPUpdates when no date-range filter is applied" time="0.000965369">
            <system-out>
  ℹ️ Loaded feed data from file: 0 adopted texts, 0 events, 0 procedures, 1 MEP updates

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="writeArticleFile dryRun + skipExisting combined &gt; returns null when file exists and both dryRun and skipExisting are true" time="0.000876036">
            <system-out>
  [DRY RUN] Would skip (already exists): existing-article.html

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="writeSingleArticle stat branches &gt; increments stats.skipped when file exists and skipExisting is true" time="0.001285507">
            <system-out>
  ⏭️  Skipped (already exists): 2025-01-15-week-ahead-en.html

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="writeGenerationMetadata with malformed existing file &gt; writes current data when existing metadata file is malformed JSON" time="0.002028958">
            <system-out>
📝 Metadata written to: /tmp/ep-meta-malformed-PkFvA0/generation-2025-01-15.json

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="writeGenerationMetadata anonymous result dedup &gt; deduplicates identical slug-less error results across runs" time="0.001581284">
            <system-out>
📝 Metadata written to: /tmp/ep-meta-anon-IVXoKU/generation-2025-01-15.json

            </system-out>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="createStrategyRegistry strategy types &gt; each registered strategy has correct type matching its category key" time="0.001302234">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="generateArticleForStrategy validation paths &gt; records zero files when strategy produces content but dryRun prevents writing" time="0.022280595">
            <system-out>
📅 Generating week-ahead article...
  📆 Date range: 2026-04-15 to 2026-04-22
  ℹ️ MCP unavailable — using placeholder events

  🌐 Generating EN version...
  📊 EN quality: Grade D (68/100)
  [DRY RUN] Would write: 2026-04-14-week-ahead-en.html
  ✅ week-ahead article generation completed: 0 files written (dry-run or all files skipped)

            </system-out>
            <system-err>
  ⚠️  EN content warning: Cross-reference density too low: 0 EP document reference(s) found (minimum 2 required)
  ⚠️  EN article did not pass quality gate (score 68 &lt; 40). Recommendations:
       💡 Increase article depth to 1500 words for maximum word-count score (currently 746)
       💡 Provide historical context: compare to previous parliamentary terms, cite precedents or earlier decisions
       💡 Support conclusions with specific data: cite vote counts, attendance figures, or referenced EP documents

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="generateArticleForStrategy validation paths &gt; writes files for all languages when strategy produces valid content" time="0.022803492">
            <system-out>
📅 Generating week-ahead article...
  📆 Date range: 2026-04-15 to 2026-04-22
  ℹ️ MCP unavailable — using placeholder events

  🌐 Generating EN version...
  📊 EN quality: Grade D (68/100)
  ✅ Wrote: 2026-04-14-week-ahead-en.html
  ✅ EN version generated
  🌐 Generating DE version...
  📊 DE quality: Grade D (67/100)
  ✅ Wrote: 2026-04-14-week-ahead-de.html
  ✅ DE version generated
  ✅ week-ahead article generated: 2/2 language(s) written

            </system-out>
            <system-err>
  ⚠️  EN content warning: Cross-reference density too low: 0 EP document reference(s) found (minimum 2 required)
  ⚠️  EN article did not pass quality gate (score 68 &lt; 40). Recommendations:
       💡 Increase article depth to 1500 words for maximum word-count score (currently 746)
       💡 Provide historical context: compare to previous parliamentary terms, cite precedents or earlier decisions
       💡 Support conclusions with specific data: cite vote counts, attendance figures, or referenced EP documents
  ⚠️  DE content warning: Keywords for &quot;de&quot; article appear to be entirely in English — consider localizing
  ⚠️  DE content warning: Cross-reference density too low: 0 EP document reference(s) found (minimum 2 required)
  ⚠️  DE content warning: Temporal coverage: article lacks forward-looking content — add forecasts, scenarios, or outlook sections for actionable intelligence
  🌐 DE Translation quality: found 6 likely untranslated English phrase(s): European Parliament, coalition-building strategies, regulatory implications
  ⚠️  DE article did not pass quality gate (score 67 &lt; 40). Recommendations:
       💡 Increase article depth to 1500 words for maximum word-count score (currently 644)
       💡 Increase evidence references to 10 for maximum evidence score (currently 6)

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="CircuitBreaker edge cases &gt; transitions from OPEN through HALF_OPEN to CLOSED via success after timeout" time="0.001637675">
            <system-err>
⚡ Circuit breaker OPEN after 2 consecutive failures
⚡ Circuit breaker OPEN after 1 consecutive failures

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="CircuitBreaker edge cases &gt; multiple successes in CLOSED state keep circuit CLOSED" time="0.000232273">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="CircuitBreaker edge cases &gt; mixed failures below threshold keep circuit CLOSED" time="0.000232344">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="normalizeISO8601Date edge cases &gt; returns empty string for empty input" time="0.000162575">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="normalizeISO8601Date edge cases &gt; returns original string for unparseable date" time="0.000149607">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="normalizeISO8601Date edge cases &gt; normalizes full ISO datetime to date-only" time="0.000148722">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="transform-stage validation helpers &gt; isValidCountryCode accepts valid codes" time="0.000169278">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="transform-stage validation helpers &gt; isValidCountryCode rejects invalid codes" time="0.000219897">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="transform-stage validation helpers &gt; isValidLanguageCode accepts valid codes" time="0.00023848">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="transform-stage validation helpers &gt; isValidLanguageCode rejects invalid codes" time="0.000217774">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="deriveTypeSlug &gt; returns strategyType unchanged when dedupSuffix is empty" time="0.00026947">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="deriveTypeSlug &gt; appends numeric dedup suffix to strategy type" time="0.000316933">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="deriveTypeSlug &gt; appends UUID-based dedup suffix to strategy type" time="0.000223375">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="deriveTypeSlug &gt; produces distinct per-strategy slugs from the same suffix" time="0.000314885">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="generateArticleForStrategy with dedup suffix &gt; uses suffixed slug when dedupSuffix is provided" time="0.006144461">
            <system-out>
🚨 Generating breaking article...

  🌐 Generating EN version...
  📊 EN quality: Grade F (10/100)
  [DRY RUN] Would write: 2026-04-14-breaking-2-en.html
  ✅ breaking article generation completed: 0 files written (dry-run or all files skipped)

            </system-out>
            <system-err>
  ⚠️  EN content warning: Content too short: 157 words (minimum 300 for &quot;breaking&quot;)
  ⚠️  EN content warning: Cross-reference density too low: 0 EP document reference(s) found (minimum 2 required)
  ⚠️  EN content warning: Temporal coverage: article lacks forward-looking content — add forecasts, scenarios, or outlook sections for actionable intelligence
  ⚠️  EN article did not pass quality gate (score 10 &lt; 40). Recommendations:
       💡 Expand article length to at least 500 words to improve word-count score
       💡 Provide historical context: compare to previous parliamentary terms, cite precedents or earlier decisions
       💡 Support conclusions with specific data: cite vote counts, attendance figures, or referenced EP documents

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="generateArticleForStrategy with dedup suffix &gt; uses unsuffixed slug when dedupSuffix is empty" time="0.004293397">
            <system-out>
📅 Generating week-ahead article...

  🌐 Generating EN version...
  📊 EN quality: Grade F (10/100)
  [DRY RUN] Would write: 2026-04-14-week-ahead-en.html
  ✅ week-ahead article generation completed: 0 files written (dry-run or all files skipped)

            </system-out>
            <system-err>
  ⚠️  EN content warning: Content too short: 157 words (minimum 500 for &quot;week-ahead&quot;)
  ⚠️  EN content warning: Cross-reference density too low: 0 EP document reference(s) found (minimum 2 required)
  ⚠️  EN content warning: Temporal coverage: article lacks forward-looking content — add forecasts, scenarios, or outlook sections for actionable intelligence
  ⚠️  EN article did not pass quality gate (score 10 &lt; 40). Recommendations:
       💡 Expand article length to at least 500 words to improve word-count score
       💡 Provide historical context: compare to previous parliamentary terms, cite precedents or earlier decisions
       💡 Support conclusions with specific data: cite vote counts, attendance figures, or referenced EP documents

            </system-err>
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="resolveUniqueAnalysisDir &gt; returns base dir when it does not exist" time="0.000683275">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="resolveUniqueAnalysisDir &gt; appends -2 suffix when base dir has completed run (manifest.json)" time="0.001293679">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="resolveUniqueAnalysisDir &gt; appends -3 suffix when base and -2 both occupied" time="0.001563887">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="resolveUniqueAnalysisDir &gt; treats existing directory with manifest.json as occupied" time="0.001447556">
        </testcase>
        <testcase classname="test/unit/pipeline-stages.test.js" name="resolveUniqueAnalysisDir &gt; reuses existing directory without manifest.json (supports skipCompleted)" time="0.000609634">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/political-classification.test.js" timestamp="2026-04-14T20:47:06.615Z" hostname="runnervm35a4x" tests="89" failures="0" errors="0" skipped="0" time="0.060783052">
        <testcase classname="test/unit/political-classification.test.js" name="SIGNIFICANCE_ORDER &gt; contains all 5 significance levels in ascending order" time="0.006597584">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="SIGNIFICANCE_ORDER &gt; has routine as the lowest level" time="0.000319693">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="SIGNIFICANCE_ORDER &gt; has historic as the highest level" time="0.000246826">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="IMPACT_ORDER &gt; contains all 5 impact levels in ascending order" time="0.000216817">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="IMPACT_ORDER &gt; has none as the lowest level" time="0.000249225">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="assessPoliticalSignificance &gt; returns routine for empty data" time="0.000344837">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="assessPoliticalSignificance &gt; returns routine for minimal, non-controversial data" time="0.000326979">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="assessPoliticalSignificance &gt; returns a higher level when many controversial votes are present" time="0.000447551">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="assessPoliticalSignificance &gt; considers coalition instability as a signal" time="0.000455594">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="assessPoliticalSignificance &gt; handles undefined sub-fields gracefully" time="0.000992191">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="assessPoliticalSignificance &gt; returns one of the valid 5 significance levels" time="0.000823706">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="assessPoliticalSignificance &gt; accepts anomalies via the `anomalies` alias field" time="0.000185685">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="assessPoliticalSignificance &gt; merges both anomalies and votingAnomalies when both are present" time="0.000243648">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="buildImpactMatrix &gt; returns none impact for all dimensions on empty data" time="0.000556716">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="buildImpactMatrix &gt; returns a valid ImpactLevel for each dimension" time="0.000900321">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="buildImpactMatrix &gt; raises legislativeImpact for bottlenecked procedures" time="0.0002692">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="buildImpactMatrix &gt; raises coalitionImpact for low-cohesion weakening coalitions" time="0.000203319">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="buildImpactMatrix &gt; raises economicImpact for economic-keyword documents and procedures" time="0.000308506">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="buildImpactMatrix &gt; raises publicOpinionImpact for oral questions" time="0.000157346">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="classifyPoliticalActors &gt; returns empty array for empty data" time="0.000721984">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="classifyPoliticalActors &gt; classifies rapporteurs as individual_mep" time="0.000321949">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="classifyPoliticalActors &gt; classifies committee names as eu_institution" time="0.000168596">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="classifyPoliticalActors &gt; classifies voting pattern groups as political_group" time="0.00029342">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="classifyPoliticalActors &gt; classifies low-cohesion groups with low influence" time="0.000137442">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="classifyPoliticalActors &gt; classifies coalition members as political_group" time="0.000382675">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="classifyPoliticalActors &gt; classifies MEP influence scores as individual_mep" time="0.000304116">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="classifyPoliticalActors &gt; deduplicates actors by name (case-insensitive)" time="0.000286589">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="classifyPoliticalActors &gt; classifies committee meetings as eu_institution" time="0.000248844">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="classifyPoliticalActors &gt; all actors have a valid position" time="0.000337512">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="classifyPoliticalActors &gt; classifies civil society actors via keyword heuristics" time="0.000293378">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="classifyPoliticalActors &gt; classifies media actors via keyword heuristics" time="0.000190404">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="classifyPoliticalActors &gt; classifies industry actors via keyword heuristics" time="0.000158392">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="classifyPoliticalActors &gt; classifies national delegation actors via country code + delegation keyword" time="0.000127053">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="classifyPoliticalActors &gt; classifies member state actors via governmental keywords" time="0.000162677">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="analyzePoliticalForces &gt; returns a complete forces analysis for empty data" time="0.00065082">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="analyzePoliticalForces &gt; all force strengths are in [0, 1]" time="0.000630038">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="analyzePoliticalForces &gt; coalitionPower reflects average cohesion" time="0.000197432">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="analyzePoliticalForces &gt; coalitionPower trend is increasing when coalitions are strengthening" time="0.000122428">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="analyzePoliticalForces &gt; coalitionPower trend is decreasing when coalitions are weakening" time="0.000175722">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="analyzePoliticalForces &gt; oppositionPower increases with more controversial votes" time="0.000174583">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="analyzePoliticalForces &gt; institutionalBarriers increase with bottlenecked procedures" time="0.000267614">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="analyzePoliticalForces &gt; institutionalBarriers trend is increasing for &gt;2 bottlenecks" time="0.000196257">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="analyzePoliticalForces &gt; publicPressure increases with oral questions" time="0.00020786">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="analyzePoliticalForces &gt; externalInfluences increases with geopolitical procedures" time="0.000193955">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="analyzePoliticalForces &gt; externalInfluences trend reflects event-only external data" time="0.000181874">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="analyzePoliticalForces &gt; all trends are valid values" time="0.000421435">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="analyzePoliticalForces &gt; all confidence levels are valid" time="0.000354668">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="serializeFrontmatter &gt; produces a string starting and ending with ---" time="0.000293459">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="serializeFrontmatter &gt; includes title, date, analysisType, significance, confidence" time="0.000270465">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="serializeFrontmatter &gt; renders methods as YAML sequences" time="0.000218156">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="serializeFrontmatter &gt; renders articleTypes as YAML sequences" time="0.000125409">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="serializeFrontmatter &gt; emits methods: [] and articleTypes: [] when arrays are empty" time="0.000255802">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="serializeFrontmatter &gt; escapes double quotes in title to prevent YAML injection" time="0.000124615">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="serializeFrontmatter &gt; escapes backslashes in values" time="0.000167622">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="serializeFrontmatter &gt; escapes newlines in values" time="0.000229087">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="writeAnalysisFile &gt; writes a file with YAML frontmatter and body" time="0.001725154">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="writeAnalysisFile &gt; creates parent directories if they do not exist" time="0.000589864">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="initializeAnalysisDirectory &gt; creates the date-stamped run directory" time="0.001504349">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="initializeAnalysisDirectory &gt; creates classification/ subdirectory" time="0.001183686">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="initializeAnalysisDirectory &gt; creates data/ subdirectory" time="0.001301242">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="initializeAnalysisDirectory &gt; creates existing/ subdirectory" time="0.001127071">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="initializeAnalysisDirectory &gt; creates documents/ subdirectory" time="0.001128927">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="initializeAnalysisDirectory &gt; creates threat-assessment/ subdirectory" time="0.00131958">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="initializeAnalysisDirectory &gt; creates risk-scoring/ subdirectory" time="0.00174557">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="initializeAnalysisDirectory &gt; creates data/world-bank/ subdirectory for World Bank data" time="0.001370077">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="initializeAnalysisDirectory &gt; creates data/osint/ subdirectory for OSINT analytical outputs" time="0.003020099">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="initializeAnalysisDirectory &gt; creates data/mcp-responses/ subdirectory for raw MCP responses" time="0.001270855">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="initializeAnalysisDirectory &gt; creates all 14 EP feed data subdirectories" time="0.001923148">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="initializeAnalysisDirectory &gt; is idempotent — does not throw if directory already exists" time="0.001813497">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="initializeAnalysisDirectory &gt; rejects date values containing path separators (path traversal)" time="0.00061295">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="initializeAnalysisDirectory &gt; rejects non-YYYY-MM-DD strings" time="0.000579413">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="writeAnalysisManifest &gt; writes manifest.json to the run directory" time="0.000860681">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="writeAnalysisManifest &gt; manifest contains correct frameworkVersion" time="0.006281925">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="writeAnalysisManifest &gt; manifest contains the provided article types" time="0.000435162">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="writeAnalysisManifest &gt; manifest contains the provided methods" time="0.000393387">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="writeAnalysisManifest &gt; written JSON is parseable and matches the returned manifest" time="0.000429615">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="compareSignificance &gt; returns 0 for equal levels" time="0.000139228">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="compareSignificance &gt; returns positive when first is greater" time="0.000077889">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="compareSignificance &gt; returns negative when first is lower" time="0.00016321">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="compareSignificance &gt; historic &gt; critical &gt; significant &gt; notable &gt; routine" time="0.000214296">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="maxSignificance &gt; returns routine for empty array" time="0.00018239">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="maxSignificance &gt; returns the single element for a one-element array" time="0.00012277">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="maxSignificance &gt; returns the highest level" time="0.000148161">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="maxSignificance &gt; handles all identical values" time="0.000129892">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="maxSignificance &gt; identifies historic as the maximum" time="0.000133612">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="safeArray guards (malformed non-array fields) &gt; assessPoliticalSignificance does not throw when fields are non-arrays" time="0.000304673">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="safeArray guards (malformed non-array fields) &gt; buildImpactMatrix does not throw when fields are non-arrays" time="0.000329312">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="safeArray guards (malformed non-array fields) &gt; classifyPoliticalActors does not throw when fields are non-arrays" time="0.000342195">
        </testcase>
        <testcase classname="test/unit/political-classification.test.js" name="safeArray guards (malformed non-array fields) &gt; analyzePoliticalForces does not throw when fields are non-arrays" time="0.000370936">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/political-risk-assessment.test.js" timestamp="2026-04-14T20:47:06.625Z" hostname="runnervm35a4x" tests="103" failures="0" errors="0" skipped="0" time="0.060245866">
        <testcase classname="test/unit/political-risk-assessment.test.js" name="calculatePoliticalRiskScore &gt; should return correct score for possible × moderate (0.5 × 3 = 1.5)" time="0.004394488">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="calculatePoliticalRiskScore &gt; should return correct score for rare × negligible (0.1 × 1 = 0.1)" time="0.000474835">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="calculatePoliticalRiskScore &gt; should return correct score for almost_certain × severe (0.9 × 5 = 4.5)" time="0.000264736">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="calculatePoliticalRiskScore &gt; should return correct score for likely × major (0.7 × 4 = 2.8)" time="0.000272564">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="calculatePoliticalRiskScore &gt; should return correct score for unlikely × minor (0.3 × 2 = 0.6)" time="0.00023411">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="calculatePoliticalRiskScore &gt; should map all likelihood levels to correct numeric values" time="0.0004655">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="calculatePoliticalRiskScore &gt; should map all impact levels to correct numeric values" time="0.001153733">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="calculatePoliticalRiskScore &gt; should correctly classify all risk level bands" time="0.000846953">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="calculatePoliticalRiskScore &gt; should include provided riskId and description" time="0.00045796">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="calculatePoliticalRiskScore &gt; should include evidence and mitigating factors" time="0.001167717">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="calculatePoliticalRiskScore &gt; should default riskId to RISK-AUTO when not provided" time="0.000247544">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="calculatePoliticalRiskScore &gt; should default confidence to medium when not provided" time="0.000157488">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="calculatePoliticalRiskScore &gt; should accept high confidence level" time="0.000212418">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="calculatePoliticalRiskScore &gt; should accept low confidence level" time="0.000162902">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="calculatePoliticalRiskScore &gt; should return readonly evidence and mitigatingFactors arrays" time="0.000213248">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="calculatePoliticalRiskScore - input validation &gt; should throw for invalid likelihood" time="0.00139249">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="calculatePoliticalRiskScore - input validation &gt; should throw for invalid impact" time="0.000473459">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="calculatePoliticalRiskScore - input validation &gt; should throw for empty string likelihood" time="0.000320795">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="calculatePoliticalRiskScore - input validation &gt; should throw for empty string impact" time="0.000379087">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="createScoredOpportunityOrThreat - input validation &gt; should throw for invalid likelihood" time="0.000516052">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="createScoredOpportunityOrThreat - input validation &gt; should throw for invalid impact" time="0.000353601">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="calculatePoliticalRiskScore - risk level boundaries &gt; should classify score of exactly 1.0 as low" time="0.000290269">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="calculatePoliticalRiskScore - risk level boundaries &gt; should classify score just above 1.0 as medium" time="0.000203036">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="calculatePoliticalRiskScore - risk level boundaries &gt; should classify score of exactly 2.0 as medium" time="0.000219899">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="calculatePoliticalRiskScore - risk level boundaries &gt; should classify score just above 2.0 as high" time="0.000217289">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="calculatePoliticalRiskScore - risk level boundaries &gt; should classify score of exactly 3.5 as high" time="0.00021997">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="calculatePoliticalRiskScore - risk level boundaries &gt; should classify score just above 3.5 as critical" time="0.000264925">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="assessPoliticalCapitalAtRisk &gt; should calculate capital at risk from driver contributions" time="0.000701488">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="assessPoliticalCapitalAtRisk &gt; should clamp currentCapital to 0–100" time="0.000321951">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="assessPoliticalCapitalAtRisk &gt; should return zero capitalAtRisk when there are no drivers" time="0.000197157">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="assessPoliticalCapitalAtRisk &gt; should cap capitalAtRisk at currentCapital" time="0.00041759">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="assessPoliticalCapitalAtRisk &gt; should default to quarter timeHorizon" time="0.00018615">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="assessPoliticalCapitalAtRisk &gt; should accept all timeHorizon options" time="0.000355688">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="assessPoliticalCapitalAtRisk &gt; should default confidenceInterval to 95" time="0.000206683">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="assessPoliticalCapitalAtRisk &gt; should include all provided risk drivers" time="0.001397311">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="buildQuantitativeSWOT &gt; should return a valid QuantitativeSWOT with all fields" time="0.002090545">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="buildQuantitativeSWOT &gt; should generate cross-impact matrix entries for each strength × threat" time="0.000549999">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="buildQuantitativeSWOT &gt; should generate cross-impact matrix entries for each weakness × threat" time="0.000394469">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="buildQuantitativeSWOT &gt; should assign negative netEffect for strengths (mitigation)" time="0.000380447">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="buildQuantitativeSWOT &gt; should assign positive netEffect for weaknesses (amplification)" time="0.000363138">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="buildQuantitativeSWOT &gt; should return strategic position score of 5 for empty inputs" time="0.000210941">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="buildQuantitativeSWOT &gt; should return high strategic position score when strengths dominate" time="0.000320532">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="buildQuantitativeSWOT &gt; should return overall assessment text" time="0.000229561">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="assessLegislativeVelocityRisk &gt; should return an empty array for empty input" time="0.000276574">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="assessLegislativeVelocityRisk &gt; should skip non-object entries" time="0.00027805">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="assessLegislativeVelocityRisk &gt; should skip procedures without procedureId or title" time="0.000222796">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="assessLegislativeVelocityRisk &gt; should return a velocity risk for a valid procedure" time="0.000859821">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="assessLegislativeVelocityRisk &gt; should set higher risk for procedures well past expected duration" time="0.000527717">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="assessLegislativeVelocityRisk &gt; should sort results by risk score descending" time="0.000837525">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="assessLegislativeVelocityRisk &gt; should default unknown stage to committee" time="0.00021426">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="assessLegislativeVelocityRisk &gt; should handle missing daysInCurrentStage as 0" time="0.000289971">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="assessLegislativeVelocityRisk &gt; should parse numeric string daysInCurrentStage" time="0.000218046">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="assessLegislativeVelocityRisk &gt; should handle valid legislative stages" time="0.000646387">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="assessLegislativeVelocityRisk &gt; should preserve predictedCompletion from input" time="0.000289808">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="assessLegislativeVelocityRisk &gt; should return null predictedCompletion when not provided" time="0.000230223">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="runAgentRiskAssessment &gt; should return a workflow with all four steps" time="0.001659726">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="runAgentRiskAssessment &gt; should include assessment metadata" time="0.000491332">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="runAgentRiskAssessment &gt; should include identified risks in the identify step" time="0.000488438">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="runAgentRiskAssessment &gt; should include risk drivers in the analyze step" time="0.00042748">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="runAgentRiskAssessment &gt; should sort evaluate matrix by risk score descending" time="0.000378761">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="runAgentRiskAssessment &gt; should include mitigations in the treat step" time="0.00052257">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="runAgentRiskAssessment &gt; should synthesise an overallRiskProfile from identified risks" time="0.000437463">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="runAgentRiskAssessment &gt; should handle an empty risks list" time="0.000233298">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="generateRiskAssessmentMarkdown &gt; should produce a non-empty markdown string" time="0.001746592">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="generateRiskAssessmentMarkdown &gt; should contain YAML frontmatter" time="0.000668534">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="generateRiskAssessmentMarkdown &gt; should contain a risk heat map section" time="0.000445462">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="generateRiskAssessmentMarkdown &gt; should contain identified risks section" time="0.000418574">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="generateRiskAssessmentMarkdown &gt; should contain evaluation matrix section" time="0.000362553">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="generateRiskAssessmentMarkdown &gt; should contain risk treatment section" time="0.000314115">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="generateRiskAssessmentMarkdown &gt; should contain recommendations section" time="0.00037269">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="generateRiskAssessmentMarkdown &gt; should include heat map emoji cells" time="0.000516311">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="generateRiskAssessmentMarkdown &gt; should handle empty risks / baseline scenario" time="0.000584369">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="generatePoliticalRiskSummary &gt; should return a valid PoliticalRiskSummary" time="0.002280869">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="generatePoliticalRiskSummary &gt; should return low risk and low confidence for empty risk list" time="0.000272314">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="generatePoliticalRiskSummary &gt; should take the highest risk level as overall" time="0.000535627">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="createScoredSWOTItem &gt; should create a ScoredSWOTItem with clamped score (0–5)" time="0.000615421">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="createScoredSWOTItem &gt; should clamp score above 5 to 5" time="0.000279882">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="createScoredSWOTItem &gt; should clamp negative score to 0" time="0.00021085">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="createScoredSWOTItem &gt; should default evidence to empty array" time="0.00019857">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="createScoredSWOTItem &gt; should default confidence to medium" time="0.000134064">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="createScoredSWOTItem &gt; should default trend to stable" time="0.000123678">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="createScoredOpportunityOrThreat &gt; should calculate score as likelihood × impact" time="0.000120539">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="createScoredOpportunityOrThreat &gt; should handle rare × negligible (0.1 × 1 = 0.1)" time="0.000109133">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="createScoredOpportunityOrThreat &gt; should handle almost_certain × severe (0.9 × 5 = 4.5)" time="0.000109509">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="createScoredOpportunityOrThreat &gt; should include description and evidence" time="0.000181159">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="createRiskDriver &gt; should create a valid risk driver" time="0.000195777">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="createRiskDriver &gt; should clamp contribution to 0–100" time="0.000144879">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="createRiskDriver &gt; should default trend to stable" time="0.000105277">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="createRiskDriver &gt; should accept all threat categories" time="0.000257922">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="computeRiskInterconnection &gt; should return isolated for a single risk" time="0.000453317">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="computeRiskInterconnection &gt; should compute cascade pairs for multiple risks" time="0.00024505">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="computeRiskInterconnection &gt; should score same-category pairs higher than cross-category" time="0.00023775">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="computeRiskInterconnection &gt; should return empty for empty input" time="0.000194228">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="computeRiskInterconnection &gt; should clamp negative numeric scores to zero" time="0.000195083">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="computeRiskVelocity &gt; should detect rapidly-escalating for delta &gt; 1.5" time="0.000264785">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="computeRiskVelocity &gt; should detect escalating for delta in (0.5, 1.5]" time="0.000129559">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="computeRiskVelocity &gt; should detect stable for small delta" time="0.000182083">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="computeRiskVelocity &gt; should detect de-escalating for delta in [-1.5, -0.5)" time="0.000187829">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="computeRiskVelocity &gt; should detect rapidly-de-escalating for delta &lt; -1.5" time="0.00016885">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="compareRiskHistorical &gt; should compute 7-day and 30-day averages" time="0.000380879">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="compareRiskHistorical &gt; should use current score as default when history is empty" time="0.00021287">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="compareRiskHistorical &gt; should detect below-average correctly" time="0.000217223">
        </testcase>
        <testcase classname="test/unit/political-risk-assessment.test.js" name="compareRiskHistorical &gt; should detect at-average within threshold" time="0.000162703">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/political-threat-assessment.test.js" timestamp="2026-04-14T20:47:06.636Z" hostname="runnervm35a4x" tests="83" failures="0" errors="0" skipped="0" time="0.05039312">
        <testcase classname="test/unit/political-threat-assessment.test.js" name="ALL_THREAT_LANDSCAPE_DIMENSIONS &gt; contains all six Threat Landscape categories" time="0.004208883">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="ALL_THREAT_LANDSCAPE_DIMENSIONS &gt; is an array of strings" time="0.00045689">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="assessPoliticalThreats &gt; with empty data &gt; returns a complete assessment with defaults" time="0.003026063">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="assessPoliticalThreats &gt; with empty data &gt; returns all six threat landscape dimensions" time="0.001114616">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="assessPoliticalThreats &gt; with empty data &gt; returns at least one key finding" time="0.000327316">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="assessPoliticalThreats &gt; with empty data &gt; returns at least one recommendation" time="0.00024478">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="assessPoliticalThreats &gt; with empty data &gt; includes at least one consequence tree" time="0.000382998">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="assessPoliticalThreats &gt; with empty data &gt; includes at least one legislative disruption" time="0.000247074">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="assessPoliticalThreats &gt; with empty data &gt; has overall threat level of low with no signals" time="0.000259155">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="assessPoliticalThreats &gt; with coalition data &gt; detects weak coalition cohesion as shift threat" time="0.001038294">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="assessPoliticalThreats &gt; with coalition data &gt; generates actor profiles for coalitions" time="0.00033603">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="assessPoliticalThreats &gt; with voting anomalies &gt; elevates shift threat level with anomalies" time="0.000468327">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="assessPoliticalThreats &gt; with voting anomalies &gt; includes anomaly count in evidence" time="0.000336684">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="assessPoliticalThreats &gt; with stalled procedures &gt; elevates reversal and delay threat for stalled procedure" time="0.000570227">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="assessPoliticalThreats &gt; with stalled procedures &gt; builds a consequence tree for stalled procedure" time="0.000292016">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="assessPoliticalThreats &gt; with high-influence MEPs &gt; generates MEP actor threat profiles" time="0.000554281">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="assessPoliticalThreats &gt; edge cases &gt; handles null/undefined data gracefully" time="0.001172922">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="assessPoliticalThreats &gt; edge cases &gt; handles empty arrays" time="0.00028764">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="assessPoliticalThreats &gt; edge cases &gt; handles malformed data without throwing" time="0.000388835">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="assessPoliticalThreats &gt; edge cases &gt; handles non-array field values without throwing" time="0.000527562">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="assessPoliticalThreats &gt; edge cases &gt; handles non-array anomalies gracefully" time="0.000231979">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="assessPoliticalThreats &gt; edge cases &gt; detects shift threats from anomalies array" time="0.000294439">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="assessPoliticalThreats &gt; edge cases &gt; includes anomaly evidence in shift dimension" time="0.000292004">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="buildActorThreatProfiles &gt; returns empty array for no data" time="0.000990966">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="buildActorThreatProfiles &gt; builds profile for weak coalition" time="0.000221462">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="buildActorThreatProfiles &gt; builds profile for high-influence MEP" time="0.000364684">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="buildActorThreatProfiles &gt; does not include low-influence MEPs" time="0.000203321">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="buildActorThreatProfiles &gt; sorts profiles by threat level descending" time="0.000313745">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="buildActorThreatProfiles &gt; includes threatCategories for each profile" time="0.000186036">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="buildActorThreatProfiles &gt; handles malformed coalition data without throwing" time="0.00024558">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="buildConsequenceTree &gt; returns a tree with the given root action" time="0.000182939">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="buildConsequenceTree &gt; includes immediate consequences" time="0.000124452">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="buildConsequenceTree &gt; includes secondary effects" time="0.000112531">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="buildConsequenceTree &gt; includes long-term implications" time="0.000112636">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="buildConsequenceTree &gt; includes mitigating and amplifying factors" time="0.000143022">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="buildConsequenceTree &gt; validates consequence probabilities are in [0, 1]" time="0.000640454">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="buildConsequenceTree &gt; amplifies consequences with weak coalitions" time="0.000273575">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="buildConsequenceTree &gt; handles empty action string by using default" time="0.000129776">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="buildConsequenceTree &gt; handles null action by using default" time="0.000130549">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="buildConsequenceTree &gt; consequence nodes have valid impact levels" time="0.000818243">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="buildConsequenceTree &gt; consequence nodes have valid timeframes" time="0.000446735">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="analyzeLegislativeDisruption &gt; returns a disruption analysis with the given procedure name" time="0.000168501">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="analyzeLegislativeDisruption &gt; includes disruption points for all 7 legislative stages" time="0.000182937">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="analyzeLegislativeDisruption &gt; all disruption points have valid threat categories" time="0.000466982">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="analyzeLegislativeDisruption &gt; all disruption point likelihoods are in [0, 1]" time="0.003399922">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="analyzeLegislativeDisruption &gt; returns valid resilience level" time="0.00020461">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="analyzeLegislativeDisruption &gt; includes alternative pathways" time="0.000148782">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="analyzeLegislativeDisruption &gt; detects current stage from procedure data" time="0.00016608">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="analyzeLegislativeDisruption &gt; uses proposal as default stage when procedure not found" time="0.000138355">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="analyzeLegislativeDisruption &gt; has higher likelihood at plenary stages with anomalies" time="0.000222959">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="analyzeLegislativeDisruption &gt; handles empty procedure name by using default" time="0.000118895">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="analyzeLegislativeDisruption &gt; handles null procedure name gracefully" time="0.000117853">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="analyzeLegislativeDisruption &gt; each disruption point has countermeasures" time="0.000306512">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="analyzeLegislativeDisruption &gt; each disruption point has potential disruptors" time="0.00029411">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="analyzeLegislativeDisruption &gt; adds cross-group rapporteur pathway when coalition risk detected" time="0.000188956">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="generateThreatAssessmentMarkdown &gt; generates a non-empty markdown string" time="0.004579249">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="generateThreatAssessmentMarkdown &gt; includes YAML frontmatter" time="0.001961265">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="generateThreatAssessmentMarkdown &gt; includes threat level in frontmatter" time="0.000893834">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="generateThreatAssessmentMarkdown &gt; includes confidence in frontmatter" time="0.000600341">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="generateThreatAssessmentMarkdown &gt; includes date in frontmatter" time="0.000674756">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="generateThreatAssessmentMarkdown &gt; includes all six threat landscape dimension headings" time="0.000797771">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="generateThreatAssessmentMarkdown &gt; includes Actor Threat Profiles section" time="0.000593972">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="generateThreatAssessmentMarkdown &gt; includes Consequence Trees section" time="0.000567308">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="generateThreatAssessmentMarkdown &gt; includes Mermaid graph syntax in consequence tree" time="0.00073227">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="generateThreatAssessmentMarkdown &gt; includes Legislative Disruption Analysis section" time="0.000545162">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="generateThreatAssessmentMarkdown &gt; includes Key Findings section" time="0.000319927">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="generateThreatAssessmentMarkdown &gt; includes Recommendations section" time="0.00034049">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="generateThreatAssessmentMarkdown &gt; includes GDPR compliance note" time="0.000303289">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="generateThreatAssessmentMarkdown &gt; generates actor table when profiles exist" time="0.000343759">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="generateThreatAssessmentMarkdown &gt; includes threat emojis for elevated threats" time="0.000559038">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="generateThreatAssessmentMarkdown &gt; generates valid markdown for minimal empty assessment" time="0.000335747">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="generateThreatAssessmentMarkdown &gt; handles null input by generating default assessment" time="0.000382102">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="generateThreatAssessmentMarkdown &gt; handles undefined input by generating default assessment" time="0.000328655">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="computeThreatCorrelationMatrix &gt; should return empty array for fewer than 2 dimensions" time="0.000266131">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="computeThreatCorrelationMatrix &gt; should return correlations for valid dimension pairs" time="0.00021954">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="computeThreatCorrelationMatrix &gt; should filter out weak correlations (|score| &lt;= 0.2)" time="0.000246208">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="computeThreatCorrelationMatrix &gt; should sort by absolute correlation score descending" time="0.000894171">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="computeThreatCorrelationMatrix &gt; should include a human-readable description" time="0.000273997">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="detectEmergingThreats &gt; should return empty array when no threats are escalating" time="0.000282548">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="detectEmergingThreats &gt; should detect a new threat not in baseline" time="0.000234861">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="detectEmergingThreats &gt; should detect rapid escalation (2+ level jump)" time="0.000150523">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="detectEmergingThreats &gt; should detect moderate escalation (1 level jump)" time="0.000113798">
        </testcase>
        <testcase classname="test/unit/political-threat-assessment.test.js" name="detectEmergingThreats &gt; should sort by escalation rate (rapid first)" time="0.000253244">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/propositions.test.js" timestamp="2026-04-14T20:47:06.645Z" hostname="runnervm35a4x" tests="15" failures="0" errors="0" skipped="0" time="0.061454474">
        <testcase classname="test/unit/propositions.test.js" name="Propositions Generator &gt; buildPropositionsContent &gt; should return HTML with localized section headings" time="0.00229394">
        </testcase>
        <testcase classname="test/unit/propositions.test.js" name="Propositions Generator &gt; buildPropositionsContent &gt; should include localized pipeline metric labels" time="0.000340361">
        </testcase>
        <testcase classname="test/unit/propositions.test.js" name="Propositions Generator &gt; buildPropositionsContent &gt; should render empty pipeline section when pipelineData is null" time="0.000393893">
        </testcase>
        <testcase classname="test/unit/propositions.test.js" name="Propositions Generator &gt; buildPropositionsContent &gt; should omit procedure section when procedureHtml is empty" time="0.000176661">
        </testcase>
        <testcase classname="test/unit/propositions.test.js" name="Propositions Generator &gt; buildPropositionsContent &gt; should include procedure section when procedureHtml is provided" time="0.000135095">
        </testcase>
        <testcase classname="test/unit/propositions.test.js" name="Propositions Generator &gt; buildPropositionsContent &gt; should escape HTML in localized string fields to prevent XSS" time="0.000504947">
        </testcase>
        <testcase classname="test/unit/propositions.test.js" name="Propositions Generator &gt; buildPropositionsContent &gt; should include proposals HTML verbatim (proposals content is pre-sanitized)" time="0.000228767">
        </testcase>
        <testcase classname="test/unit/propositions.test.js" name="Propositions Generator &gt; buildPropositionsContent &gt; should include pipeline proc rows HTML verbatim" time="0.00041002">
        </testcase>
        <testcase classname="test/unit/propositions.test.js" name="Propositions Generator &gt; buildPropositionsContent &gt; should render adopted-texts-section when adoptedTextsHtml is provided" time="0.00031767">
        </testcase>
        <testcase classname="test/unit/propositions.test.js" name="Propositions Generator &gt; buildPropositionsContent &gt; should omit adopted-texts-section when adoptedTextsHtml is empty" time="0.000181894">
        </testcase>
        <testcase classname="test/unit/propositions.test.js" name="Propositions Generator &gt; Propositions article HTML generation &gt; should produce valid HTML for propositions article" time="0.026377754">
        </testcase>
        <testcase classname="test/unit/propositions.test.js" name="Propositions Generator &gt; Propositions article HTML generation &gt; should generate articles for all 14 EU languages using PROPOSITIONS_TITLES and PROPOSITIONS_STRINGS" time="0.025539007">
        </testcase>
        <testcase classname="test/unit/propositions.test.js" name="Propositions Generator &gt; Propositions article HTML generation &gt; should generate minimal article when MCP is unavailable (null pipeline)" time="0.001171163">
        </testcase>
        <testcase classname="test/unit/propositions.test.js" name="Propositions editorial quality &gt; should not include &quot;Why This Matters&quot; section (replaced by AI-driven analysis)" time="0.000739531">
        </testcase>
        <testcase classname="test/unit/propositions.test.js" name="Propositions editorial quality &gt; should retain whyThisMatters constant for backward compatibility" time="0.000183262">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/section-builders.test.js" timestamp="2026-04-14T20:47:06.647Z" hostname="runnervm35a4x" tests="48" failures="0" errors="0" skipped="0" time="0.028288904">
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; computeArticleQualityScore &gt; should return needs-improvement for empty content" time="0.003992177">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; computeArticleQualityScore &gt; should strip HTML tags when counting words" time="0.000364595">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; computeArticleQualityScore &gt; should count section elements as analysisSections" time="0.000264228">
        </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.000846511">
        </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.000346854">
        </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.000353282">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; computeArticleQualityScore &gt; should rate excellent for rich content" time="0.000684241">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; computeArticleQualityScore &gt; should rate good for medium content" time="0.000508332">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; computeArticleQualityScore &gt; should exclude script content from word count" time="0.000294477">
        </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.000716586">
        </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.00024724">
        </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.000260742">
        </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.00026373">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildTableOfContents &gt; should return empty string for empty entries" time="0.0003996">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildTableOfContents &gt; should render nav with list items" time="0.000809684">
        </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.00030966">
        </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.000287337">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildTableOfContents &gt; should escape HTML in labels" time="0.000549174">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildTableOfContents &gt; should strip leading # from entry ids" time="0.000479443">
        </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.000304141">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildQualityScoreBadge &gt; should render badge for good score" time="0.000319725">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildQualityScoreBadge &gt; should include aria-hidden attribute" time="0.00021918">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildTimelineSection &gt; should return empty string for empty items" time="0.000366527">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildTimelineSection &gt; should render a timeline section with items" time="0.000533973">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildTimelineSection &gt; should use localized heading for German" time="0.000235569">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildTimelineSection &gt; should use English fallback for unknown language" time="0.000211776">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildTimelineSection &gt; should escape HTML in date and label" time="0.000525315">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildTimelineSection &gt; should include aria-label on section" time="0.000589859">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildTimelineSection &gt; should render an ordered list" time="0.000465609">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildTimelineSection &gt; should render optional description when provided" time="0.00026789">
        </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.000142958">
        </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.000250261">
        </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.00011433">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildComparisonTable &gt; should render a comparison table" time="0.000341506">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildComparisonTable &gt; should use localized column headers" time="0.000298224">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildComparisonTable &gt; should escape HTML in cell content" time="0.000916844">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildComparisonTable &gt; should include scope attributes for accessibility" time="0.000563099">
        </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.000188182">
        </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.002429736">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildKeyFiguresBar &gt; should return empty string for empty figures" time="0.000304441">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildKeyFiguresBar &gt; should render a key figures bar" time="0.000578436">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildKeyFiguresBar &gt; should use localized heading" time="0.000264107">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildKeyFiguresBar &gt; should include sr-only heading" time="0.000178984">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildKeyFiguresBar &gt; should include aria-label on figure cards" time="0.000302397">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildKeyFiguresBar &gt; should render optional description as sr-only" time="0.000243289">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildKeyFiguresBar &gt; should escape HTML in labels and values" time="0.000295455">
        </testcase>
        <testcase classname="test/unit/section-builders.test.js" name="section-builders &gt; buildKeyFiguresBar &gt; should include unit with aria-hidden" time="0.000243604">
        </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.000261181">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/significance-scoring.test.js" timestamp="2026-04-14T20:47:06.652Z" hostname="runnervm35a4x" tests="51" failures="0" errors="0" skipped="0" time="0.026164028">
        <testcase classname="test/unit/significance-scoring.test.js" name="clampScore &gt; returns 0 for negative values" time="0.005880221">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="clampScore &gt; returns 10 for values above 10" time="0.000414921">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="clampScore &gt; passes through values within range" time="0.000401901">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="clampScore &gt; returns 0 for NaN" time="0.000223552">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="clampScore &gt; returns 0 for Infinity" time="0.000298411">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="deriveDecision &gt; returns &quot;skip&quot; for scores below hold threshold" time="0.000496566">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="deriveDecision &gt; returns &quot;hold&quot; for scores in hold range" time="0.00034549">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="deriveDecision &gt; returns &quot;publish&quot; for scores at or above publish threshold" time="0.00038274">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="scoreSignificance &gt; computes correct composite for all-zero input" time="0.001130641">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="scoreSignificance &gt; computes correct composite for all-10 input" time="0.000352321">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="scoreSignificance &gt; applies correct weights" time="0.00035845">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="scoreSignificance &gt; clamps out-of-range dimension values" time="0.000365854">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="scoreSignificance &gt; produces consistent results for same input" time="0.000265838">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="scoreSignificance &gt; correctly computes the calibration example from the template" time="0.00031406">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="scoreSignificance &gt; computes routine committee opinion correctly" time="0.000210287">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="scoreSignificance &gt; decision is derived from rounded composite so it matches displayed value" time="0.000256491">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="scoreBatch &gt; handles empty input array" time="0.002464609">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="scoreBatch &gt; scores a single event" time="0.00060168">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="scoreBatch &gt; ranks events by composite descending" time="0.000287836">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="scoreBatch &gt; correctly counts decisions across categories" time="0.000263338">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="scoring constants &gt; weights sum to 1.0" time="0.00021831">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="scoring constants &gt; publish threshold is greater than hold threshold" time="0.00024321">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="scoring constants &gt; thresholds are within 0-10 range" time="0.000238198">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="formatScoreMarkdown &gt; includes the event title in the markdown" time="0.000495846">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="formatScoreMarkdown &gt; includes EP reference when provided" time="0.000194816">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="formatScoreMarkdown &gt; shows correct decision labels" time="0.000185017">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="formatScoreMarkdown &gt; sanitizes pipe and HTML characters in title and reference" time="0.000206084">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="formatScoreMarkdown &gt; omits EP Reference row for empty-string reference" time="0.000153453">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="formatBatchMarkdown &gt; produces a table with header and rows" time="0.000419402">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="formatBatchMarkdown &gt; uses dash for missing references" time="0.000176002">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="formatBatchMarkdown &gt; uses dash for empty-string references" time="0.000137132">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="formatBatchMarkdown &gt; uses dash for whitespace-only references" time="0.000130328">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="formatBatchMarkdown &gt; escapes pipe characters in titles and references" time="0.000191086">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="formatBatchMarkdown &gt; escapes HTML entities in titles" time="0.000187894">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="formatBatchMarkdown &gt; throws when inputs and scores arrays have different lengths" time="0.000829836">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="computeComparativeSignificance &gt; should rank a single item as rank 1 with percentile 100" time="0.000359437">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="computeComparativeSignificance &gt; should return rank 1 for the highest composite score" time="0.000153736">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="computeComparativeSignificance &gt; should return correct peer average" time="0.000141342">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="computeComparativeSignificance &gt; should handle empty peers array" time="0.000126853">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="computeComparativeSignificance &gt; should compute aboveAverage correctly when below average" time="0.000263982">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="computeComparativeSignificance &gt; should give percentile 100 to all tied top scores" time="0.000162465">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="computeComparativeSignificance &gt; should give percentile 0 to all tied bottom scores" time="0.000147932">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="detectSignificanceTrend &gt; should return stable with low confidence for empty array" time="0.000223105">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="detectSignificanceTrend &gt; should return stable with low confidence for single item" time="0.000183703">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="detectSignificanceTrend &gt; should detect increasing trend" time="0.000469558">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="detectSignificanceTrend &gt; should detect decreasing trend" time="0.00024039">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="detectSignificanceTrend &gt; should detect stable trend for flat scores" time="0.000187043">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="detectSignificanceTrend &gt; should assign medium confidence for 3-4 data points" time="0.000100783">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="computeNoveltyBonus &gt; should return 5 for a novel item" time="0.000239467">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="computeNoveltyBonus &gt; should return 0 for a previously seen item" time="0.00010787">
        </testcase>
        <testcase classname="test/unit/significance-scoring.test.js" name="computeNoveltyBonus &gt; should return 5 when the seen set is empty" time="0.000089445">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/swot-content.test.js" timestamp="2026-04-14T20:47:06.658Z" hostname="runnervm35a4x" tests="25" failures="0" errors="0" skipped="0" time="0.01686092">
        <testcase classname="test/unit/swot-content.test.js" name="swot-content &gt; buildSwotSection &gt; should return empty string for null input" time="0.003224785">
        </testcase>
        <testcase classname="test/unit/swot-content.test.js" name="swot-content &gt; buildSwotSection &gt; should return empty string for undefined input" time="0.000259848">
        </testcase>
        <testcase classname="test/unit/swot-content.test.js" name="swot-content &gt; buildSwotSection &gt; should return empty string for SWOT with no items" time="0.000219391">
        </testcase>
        <testcase classname="test/unit/swot-content.test.js" name="swot-content &gt; buildSwotSection &gt; should generate valid HTML with all four quadrants" time="0.001577044">
        </testcase>
        <testcase classname="test/unit/swot-content.test.js" name="swot-content &gt; buildSwotSection &gt; should include SWOT title in heading" time="0.000294555">
        </testcase>
        <testcase classname="test/unit/swot-content.test.js" name="swot-content &gt; buildSwotSection &gt; should use custom heading when provided" time="0.000316274">
        </testcase>
        <testcase classname="test/unit/swot-content.test.js" name="swot-content &gt; buildSwotSection &gt; should default heading to localized &quot;SWOT Analysis&quot; when no title or heading" time="0.000244303">
        </testcase>
        <testcase classname="test/unit/swot-content.test.js" name="swot-content &gt; buildSwotSection &gt; should escape HTML in SWOT item text" time="0.000425362">
        </testcase>
        <testcase classname="test/unit/swot-content.test.js" name="swot-content &gt; buildSwotSection &gt; should include severity badges when severity is set" time="0.001594532">
        </testcase>
        <testcase classname="test/unit/swot-content.test.js" name="swot-content &gt; buildSwotSection &gt; should render severity badges as ARIA-only labels without visible text" time="0.000516789">
        </testcase>
        <testcase classname="test/unit/swot-content.test.js" name="swot-content &gt; buildSwotSection &gt; should not include severity badges when severity is not set" time="0.00024366">
        </testcase>
        <testcase classname="test/unit/swot-content.test.js" name="swot-content &gt; buildSwotSection &gt; should include accessible ARIA attributes" time="0.000276608">
        </testcase>
        <testcase classname="test/unit/swot-content.test.js" name="swot-content &gt; buildSwotSection &gt; should not use invalid ARIA table roles on grid divs" time="0.000317645">
        </testcase>
        <testcase classname="test/unit/swot-content.test.js" name="swot-content &gt; buildSwotSection &gt; should not have hard-coded English aria-label on SWOT grid" time="0.000236832">
        </testcase>
        <testcase classname="test/unit/swot-content.test.js" name="swot-content &gt; buildSwotSection &gt; should include axis labels for internal/external dimensions" time="0.000254">
        </testcase>
        <testcase classname="test/unit/swot-content.test.js" name="swot-content &gt; buildSwotSection &gt; should render all strength items" time="0.00027535">
        </testcase>
        <testcase classname="test/unit/swot-content.test.js" name="swot-content &gt; buildSwotSection &gt; should render all weakness items" time="0.000667994">
        </testcase>
        <testcase classname="test/unit/swot-content.test.js" name="swot-content &gt; buildSwotSection &gt; should render all opportunity items" time="0.000278039">
        </testcase>
        <testcase classname="test/unit/swot-content.test.js" name="swot-content &gt; buildSwotSection &gt; should render all threat items" time="0.000274376">
        </testcase>
        <testcase classname="test/unit/swot-content.test.js" name="swot-content &gt; buildSwotSection &gt; should render with minimal data (only one quadrant populated)" time="0.000247967">
        </testcase>
        <testcase classname="test/unit/swot-content.test.js" name="swot-content &gt; buildSwotSection &gt; should include quadrant headings and descriptions" time="0.000413991">
        </testcase>
        <testcase classname="test/unit/swot-content.test.js" name="swot-content &gt; buildSwotSection &gt; should show placeholder for empty quadrants" time="0.000357653">
        </testcase>
        <testcase classname="test/unit/swot-content.test.js" name="swot-content &gt; buildSwotSection &gt; should localize labels when lang is provided" time="0.000741459">
        </testcase>
        <testcase classname="test/unit/swot-content.test.js" name="swot-content &gt; buildSwotSection &gt; should localize section heading when lang is provided and no custom title" time="0.000241407">
        </testcase>
        <testcase classname="test/unit/swot-content.test.js" name="swot-content &gt; buildSwotSection &gt; should localize axis labels when lang is provided" time="0.000278985">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/synthesis-summary.test.js" timestamp="2026-04-14T20:47:06.661Z" hostname="runnervm35a4x" tests="35" failures="0" errors="0" skipped="0" time="0.025410714">
        <testcase classname="test/unit/synthesis-summary.test.js" name="parseFrontmatter &gt; parses valid frontmatter with all fields" time="0.002698439">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="parseFrontmatter &gt; returns null for content without frontmatter" time="0.000313081">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="parseFrontmatter &gt; defaults to low confidence for unknown values" time="0.000216732">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="parseFrontmatter &gt; handles missing confidence field" time="0.000172801">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="parseFrontmatter &gt; handles missing method field" time="0.000121225">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="aggregateSWOT &gt; counts zero for empty text" time="0.000751269">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="aggregateSWOT &gt; counts SWOT keyword mentions" time="0.000257932">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="aggregateSWOT &gt; handles case insensitivity" time="0.000129217">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="aggregateRisks &gt; counts zero for empty text" time="0.001045456">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="aggregateRisks &gt; counts risk-level mentions" time="0.000256999">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="extractSummaryLine &gt; extracts the first heading from markdown" time="0.000272833">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="extractSummaryLine &gt; falls back to first non-empty line when no heading" time="0.000256107">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="extractSummaryLine &gt; returns default message for empty content" time="0.000118782">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="extractSummaryLine &gt; skips table rows and code block delimiters" time="0.000099786">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="aggregateConfidence &gt; returns low for empty findings array" time="0.000149848">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="aggregateConfidence &gt; returns high when majority is high confidence" time="0.000134284">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="aggregateConfidence &gt; returns medium when majority is medium confidence" time="0.000149357">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="aggregateConfidence &gt; returns low when majority is low confidence" time="0.000127752">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="findMarkdownFiles &gt; returns empty array for non-existent directory" time="0.001634823">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="findMarkdownFiles &gt; returns empty array for empty directory" time="0.000505954">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="findMarkdownFiles &gt; finds markdown files in nested directories" time="0.001530418">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="findMarkdownFiles &gt; excludes synthesis-summary.md to prevent self-contamination" time="0.000661925">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="findMarkdownFiles &gt; excludes documents/ subdirectory to prevent bloat" time="0.000742538">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="generateEditorialRecommendations &gt; recommends pipeline verification for empty findings" time="0.000421133">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="generateEditorialRecommendations &gt; mentions high-confidence findings when present" time="0.000175327">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="generateEditorialRecommendations &gt; flags critical risk mentions" time="0.000163263">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="generateEditorialRecommendations &gt; warns about threat-heavy SWOT balance" time="0.000239945">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="buildSynthesisSummary &gt; handles empty directory gracefully" time="0.00151863">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="buildSynthesisSummary &gt; processes analysis files and produces summary" time="0.001551567">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="buildSynthesisSummary &gt; ranks high-confidence findings first" time="0.001038702">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="buildSynthesisSummary &gt; limits top findings to 5" time="0.001667704">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="formatSynthesisMarkdown &gt; produces valid markdown with all sections" time="0.001070298">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="formatSynthesisMarkdown &gt; includes frontmatter" time="0.000350556">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="formatSynthesisMarkdown &gt; uses &quot;Top Findings by Confidence&quot; heading (not Significance)" time="0.000319206">
        </testcase>
        <testcase classname="test/unit/synthesis-summary.test.js" name="formatSynthesisMarkdown &gt; sanitizes pipe characters and HTML in findings table" time="0.000395863">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/validate-ep-api.test.js" timestamp="2026-04-14T20:47:06.665Z" hostname="runnervm35a4x" tests="19" failures="0" errors="0" skipped="0" time="0.020937925">
        <testcase classname="test/unit/validate-ep-api.test.js" name="validateCommitteeEndpoint &gt; should return success=true when EP API returns valid committee data" time="0.004329201">
        </testcase>
        <testcase classname="test/unit/validate-ep-api.test.js" name="validateCommitteeEndpoint &gt; should return success=false when EP API returns HTTP error" time="0.000543634">
        </testcase>
        <testcase classname="test/unit/validate-ep-api.test.js" name="validateCommitteeEndpoint &gt; should return success=false when response has no data items" time="0.000681369">
        </testcase>
        <testcase classname="test/unit/validate-ep-api.test.js" name="validateCommitteeEndpoint &gt; should return success=false when fetch throws (e.g. timeout)" time="0.000583711">
        </testcase>
        <testcase classname="test/unit/validate-ep-api.test.js" name="validateCommitteeEndpoint &gt; should return success=false when data item has no prefLabel" time="0.000462119">
        </testcase>
        <testcase classname="test/unit/validate-ep-api.test.js" name="validateCommitteeEndpoint &gt; should use altLabel when prefLabel is missing" time="0.000388778">
        </testcase>
        <testcase classname="test/unit/validate-ep-api.test.js" name="validateCommitteeEndpoint &gt; should return success=false when classification is not a committee" time="0.000728918">
        </testcase>
        <testcase classname="test/unit/validate-ep-api.test.js" name="validateEPAPI &gt; should validate all committees and return summary" time="0.002184053">
        </testcase>
        <testcase classname="test/unit/validate-ep-api.test.js" name="validateEPAPI &gt; should report failures in summary" time="0.000680248">
        </testcase>
        <testcase classname="test/unit/validate-ep-api.test.js" name="validateEPAPI &gt; should validate default committees when none specified" time="0.000735198">
        </testcase>
        <testcase classname="test/unit/validate-ep-api.test.js" name="fetchCommitteeInfoFromEPAPI &gt; should populate committee data from EP v2 API response" time="0.002052633">
            <system-out>
  ✅ EP API fallback: Committee on the Environment, Climate and Food Safety (ENVI)

            </system-out>
        </testcase>
        <testcase classname="test/unit/validate-ep-api.test.js" name="fetchCommitteeInfoFromEPAPI &gt; should not overwrite existing non-placeholder members" time="0.001653763">
            <system-out>
  ✅ EP API fallback: Environment (ENVI)

            </system-out>
        </testcase>
        <testcase classname="test/unit/validate-ep-api.test.js" name="fetchCommitteeInfoFromEPAPI &gt; should handle HTTP error gracefully" time="0.000659452">
            <system-err>
  ⚠️ EP API direct lookup for ENVI returned 503

            </system-err>
        </testcase>
        <testcase classname="test/unit/validate-ep-api.test.js" name="fetchCommitteeInfoFromEPAPI &gt; should handle empty data array gracefully" time="0.000319156">
        </testcase>
        <testcase classname="test/unit/validate-ep-api.test.js" name="fetchCommitteeInfoFromEPAPI &gt; should handle fetch error (network timeout) gracefully" time="0.000715202">
            <system-err>
  ⚠️ EP API direct fallback failed for ENVI: AbortError: signal timed out

            </system-err>
        </testcase>
        <testcase classname="test/unit/validate-ep-api.test.js" name="fetchCommitteeInfoFromEPAPI &gt; should not set abbreviation when label starts with org/" time="0.00058847">
            <system-out>
  ✅ EP API fallback: Environment (ENVI)

            </system-out>
        </testcase>
        <testcase classname="test/unit/validate-ep-api.test.js" name="fetchCommitteeInfoFromEPAPI &gt; should use altLabel when prefLabel is missing" time="0.000660095">
            <system-out>
  ✅ EP API fallback: Economic and Monetary Affairs (ECON)

            </system-out>
        </testcase>
        <testcase classname="test/unit/validate-ep-api.test.js" name="fetchCommitteeInfoFromEPAPI &gt; should fall back to label when both prefLabel and altLabel are missing" time="0.000470986">
            <system-out>
  ✅ EP API fallback: LIBE (LIBE)

            </system-out>
        </testcase>
        <testcase classname="test/unit/validate-ep-api.test.js" name="fetchCommitteeInfoFromEPAPI &gt; should handle response with no data property" time="0.000374336">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/wb-mcp-client.test.js" timestamp="2026-04-14T20:47:06.668Z" hostname="runnervm35a4x" tests="18" failures="0" errors="0" skipped="0" time="0.021568641">
        <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.004210224">
        </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.000462733">
        </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.000909489">
        </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.00028522">
        </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.000255154">
        </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.002878559">
        </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.000770778">
        </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.000290111">
        </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.000192162">
        </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.000431555">
        </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.000784343">
        </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.000241524">
        </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.001888639">
        </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.001073033">
        </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.000985323">
        </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.000853418">
        </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.000765155">
        </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.000950261">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/week-ahead.test.js" timestamp="2026-04-14T20:47:06.670Z" hostname="runnervm35a4x" tests="75" failures="0" errors="0" skipped="0" time="0.046933155">
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; parsePlenarySessions &gt; should return events from a fulfilled MCP result" time="0.013450876">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; parsePlenarySessions &gt; should use fallback date when session has no date" time="0.000323085">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; parsePlenarySessions &gt; should use default title when session has none" time="0.000219557">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; parsePlenarySessions &gt; should return empty array for rejected result" time="0.000966803">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; parsePlenarySessions &gt; should return empty array when sessions array is absent" time="0.000221084">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; parsePlenarySessions &gt; should return empty array for invalid JSON" time="0.000227411">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; parsePlenarySessions &gt; should return empty array when no content text" time="0.00021997">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; parseEPEvents &gt; should return events from a fulfilled MCP result" time="0.000534508">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; parseEPEvents &gt; should use fallback date when event has no date" time="0.000250615">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; parseEPEvents &gt; should use default title when event has none" time="0.002520113">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; parseEPEvents &gt; should return empty array for rejected result" time="0.000213439">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; parseEPEvents &gt; should return empty array when events array is absent" time="0.000173437">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; parseEPEvents &gt; should return empty array for invalid JSON" time="0.00020789">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; parseEPEvents &gt; should return empty array when no content text" time="0.000183537">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; parseCommitteeMeetings &gt; should return committee meetings from a fulfilled result" time="0.000447909">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; parseCommitteeMeetings &gt; should use fallback date when meeting has no date" time="0.000174348">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; parseCommitteeMeetings &gt; should use &quot;Unknown&quot; for committee with no name" time="0.000156304">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; parseCommitteeMeetings &gt; should return empty array for rejected result" time="0.000149587">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; parseCommitteeMeetings &gt; should return empty array when committees array is absent" time="0.00015055">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; parseLegislativeDocuments &gt; should return documents from a fulfilled result" time="0.000414614">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; parseLegislativeDocuments &gt; should use &quot;Untitled Document&quot; when title absent" time="0.000206864">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; parseLegislativeDocuments &gt; should return empty array for rejected result" time="0.000812624">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; parseLegislativeDocuments &gt; should return empty array when documents array is absent" time="0.000201178">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; parseLegislativePipeline &gt; should return procedures from a fulfilled result" time="0.000390532">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; parseLegislativePipeline &gt; should use &quot;Unnamed Procedure&quot; when title absent" time="0.000144176">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; parseLegislativePipeline &gt; should return empty array for rejected result" time="0.000103391">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; parseLegislativePipeline &gt; should return empty array when procedures array is absent" time="0.00010284">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; buildWeekAheadContent &gt; should contain the lede with date range" time="0.00072646">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; buildWeekAheadContent &gt; should show &quot;No plenary sessions&quot; when events array is empty" time="0.000135302">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; buildWeekAheadContent &gt; should render plenary event titles in HTML" time="0.000412909">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; buildWeekAheadContent &gt; should include committee-calendar section when committees present" time="0.000336983">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; buildWeekAheadContent &gt; should include legislative-documents section when documents present" time="0.000368549">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; buildWeekAheadContent &gt; should include legislative-pipeline section when pipeline present" time="0.000451293">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; buildWeekAheadContent &gt; should include qa-schedule section when questions present" time="0.000241477">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; buildWeekAheadContent &gt; should escape HTML in event titles to prevent XSS" time="0.000221476">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; buildWeekAheadContent &gt; should include bottleneck indicator for stalled procedures" time="0.000199017">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; buildWeekAheadContent &gt; should omit optional sections when data arrays are empty" time="0.0002629">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; buildKeywords &gt; should always include base keywords" time="0.000566066">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; buildKeywords &gt; should add committee names from committee meetings" time="0.000226248">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; buildKeywords &gt; should not duplicate committee names" time="0.000182547">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; buildKeywords &gt; should add &quot;legislative pipeline&quot; when pipeline has entries" time="0.000132688">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; buildKeywords &gt; should add &quot;parliamentary questions&quot; when questions has entries" time="0.000127345">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead helpers &gt; buildKeywords &gt; should not add &quot;legislative pipeline&quot; or &quot;parliamentary questions&quot; when empty" time="0.000346761">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead editorial quality &gt; should not include &quot;Why This Matters&quot; section (replaced by AI-driven analysis)" time="0.000173982">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead editorial quality &gt; should include committee count in lede when committees are present" time="0.000144726">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead editorial quality &gt; should use singular form for single committee meeting" time="0.000145653">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead editorial quality &gt; should generate valid article structure for Swedish" time="0.000130246">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead multi-language section headings &gt; should use localized section headings for all 14 languages" time="0.002857531">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead multi-language section headings &gt; should use localized no-plenary message when events are empty" time="0.000556776">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead multi-language section headings &gt; should use Japanese section headings" time="0.000260469">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead multi-language section headings &gt; should use Korean section headings" time="0.000215137">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead multi-language section headings &gt; should use Chinese section headings" time="0.000203915">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="week-ahead multi-language section headings &gt; should have WEEK_AHEAD_STRINGS for all 14 languages" time="0.002804163">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="buildStakeholderImpactMatrix &gt; should return empty rows when no events or documents" time="0.00020705">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="buildStakeholderImpactMatrix &gt; should include political groups when events are present" time="0.000197388">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="buildStakeholderImpactMatrix &gt; should include civil society when documents are present" time="0.000134346">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="buildStakeholderImpactMatrix &gt; should assign high impact to political groups with 3+ events" time="0.000133186">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="buildStakeholderImpactMatrix &gt; should assign medium impact to political groups with fewer than 3 events" time="0.000125293">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="buildStakeholderImpactMatrix &gt; should include EU Citizens, EU Institutions and National Governments rows" time="0.000176478">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="buildStakeholderImpactMatrix &gt; should include industry row when events or documents are present" time="0.000109872">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="buildStakeholderImpactMatrix &gt; should use localized stakeholder labels for non-English languages" time="0.000172038">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="computeWeekPoliticalTemperature &gt; should return score 0 when no events or questions" time="0.000196174">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="computeWeekPoliticalTemperature &gt; should increase score with more events" time="0.000150215">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="computeWeekPoliticalTemperature &gt; should increase score with more questions" time="0.000096118">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="computeWeekPoliticalTemperature &gt; should award diversity bonus for distinct event types" time="0.000102851">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="computeWeekPoliticalTemperature &gt; should cap at 100" time="0.000332576">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="computeWeekPoliticalTemperature &gt; should return &quot;Very High&quot; label for high scores" time="0.000295331">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="stakeholder impact HTML integration &gt; should not include stakeholder section when no events or documents" time="0.000134084">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="stakeholder impact HTML integration &gt; should include stakeholder section when events are present" time="0.000239665">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="stakeholder impact HTML integration &gt; should include stakeholder section when documents are present" time="0.000180617">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="stakeholder impact HTML integration &gt; should escape HTML in stakeholder section to prevent XSS" time="0.00016464">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="stakeholder impact HTML integration &gt; should use localized stakeholder headings for all 14 languages" time="0.000929262">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="stakeholder impact HTML integration &gt; should have WEEK_AHEAD_STAKEHOLDER_STRINGS for all 14 languages" time="0.003191697">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="stakeholder impact HTML integration &gt; should use localized temperature descriptors in HTML output" time="0.000195592">
        </testcase>
        <testcase classname="test/unit/week-ahead.test.js" name="stakeholder impact HTML integration &gt; should use localized reason strings with event count" time="0.000181975">
        </testcase>
    </testsuite>
    <testsuite name="test/unit/world-bank-data.test.js" timestamp="2026-04-14T20:47:06.679Z" hostname="runnervm35a4x" tests="43" failures="0" errors="0" skipped="0" time="0.035056205">
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; EU_COUNTRY_CODES &gt; should contain all 27 EU member states" time="0.003767748">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; EU_COUNTRY_CODES &gt; should map DE to DEU" time="0.000403797">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; EU_COUNTRY_CODES &gt; should map FR to FRA" time="0.000213039">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; EU_COUNTRY_CODES &gt; should map SE to SWE" time="0.000202174">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; EU_COUNTRY_CODES &gt; should map all codes to 3-letter strings" time="0.007195281">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; EU_AGGREGATE_CODE &gt; should be EUU" time="0.000304818">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; POLICY_INDICATORS &gt; should contain gdp indicator" time="0.000249008">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; POLICY_INDICATORS &gt; should contain all 25 policy-relevant indicators" time="0.003676785">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; parseWorldBankCSV &gt; should return empty array for empty input" time="0.001648001">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; parseWorldBankCSV &gt; should return empty array for null-like input" time="0.000333862">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; parseWorldBankCSV &gt; should return empty array for header-only CSV" time="0.000340102">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; parseWorldBankCSV &gt; should parse standard World Bank CSV format" time="0.001027648">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; parseWorldBankCSV &gt; should handle alternative header names" time="0.000472687">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; parseWorldBankCSV &gt; should handle null values" time="0.000519884">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; parseWorldBankCSV &gt; should skip rows with invalid year" time="0.000377605">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; parseWorldBankCSV &gt; should handle quoted fields containing commas" time="0.000585692">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; parseWorldBankCSV &gt; should handle quoted headers containing commas" time="0.000447421">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; parseWorldBankCSV &gt; should handle CRLF line endings" time="0.000510247">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; parseWorldBankCSV &gt; should handle RFC 4180 escaped quotes in fields" time="0.000445575">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; formatIndicatorValue &gt; should return N/A for null value" time="0.00037481">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; formatIndicatorValue &gt; should format GDP in trillions" time="0.000260015">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; formatIndicatorValue &gt; should format GDP in billions" time="0.000170707">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; formatIndicatorValue &gt; should format GDP in millions" time="0.000154364">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; formatIndicatorValue &gt; should format population in millions" time="0.000178712">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; formatIndicatorValue &gt; should format population in billions" time="0.000164981">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; formatIndicatorValue &gt; should format percentage indicators" time="0.000359238">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; formatIndicatorValue &gt; should format new percentage-based indicators" time="0.000774704">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; formatIndicatorValue &gt; should format CO2 emissions" time="0.000239668">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; formatIndicatorValue &gt; should format unknown indicator as decimal" time="0.000211919">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; getMostRecentValue &gt; should return null for empty array" time="0.000299165">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; getMostRecentValue &gt; should return null when all values are null" time="0.000206949">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; getMostRecentValue &gt; should return the most recent non-null value" time="0.0003627">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; buildEconomicContext &gt; should build context with indicator summaries" time="0.00105341">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; buildEconomicContext &gt; should handle empty indicator data" time="0.000360784">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; getWorldBankCountryCode &gt; should return World Bank code for EU member states" time="0.000326061">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; getWorldBankCountryCode &gt; should be case-insensitive" time="0.000312546">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; getWorldBankCountryCode &gt; should return null for non-EU countries" time="0.000351812">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; isEUMemberState &gt; should return true for EU member states" time="0.000343609">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; isEUMemberState &gt; should return false for non-EU countries" time="0.000294271">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; isEUMemberState &gt; should be case-insensitive" time="0.000175419">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; buildEconomicContextHTML &gt; should return empty string when no indicators" time="0.000339862">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; buildEconomicContextHTML &gt; should generate valid HTML table" time="0.000748552">
        </testcase>
        <testcase classname="test/unit/world-bank-data.test.js" name="world-bank-data &gt; buildEconomicContextHTML &gt; should escape HTML in country name" time="0.000409965">
        </testcase>
    </testsuite>
</testsuites>
