import { describe, it, expect, vi } from 'vitest'; import { compileHtmlToMarkdown, extractIndependentStaticReference } from '../src/core/transformer'; import { isSafePublicUrl, verifyResolvedHostSafety } from '../src/core/security'; import { isSafeTwinCandidate, isSafeRedirectDestination, resolveAuthoritativeTwin } from '../src/services/twin-resolver'; import { fetchOrigin } from '../src/core/fetcher'; import { LIMITS } from '../src/config/constants'; import { app } from '../src/index'; describe('Golden Corpus Regression Suite (Adversarial Parity Gates)', () => { it('Next.js Documentation: passes visible-text recall, preserves doc context, and avoids sidebar cutoff', async () => { // Synthetic mirror of Next.js Docs DOM structure with complex sidebar, nested broken tags, and article const nextDocsHtml = ` Next.js Docs | Next.js
  • i18n
  • Next.js Docs

    Welcome to the Next.js documentation!

    What is Next.js?

    Next.js is a React framework for building full-stack web applications. You use React Components to build user interfaces.

    How to use the docs

    On each page, you will find documentation and guides for implementing Next.js features.

    App Router and Pages Router

    Next.js has two different routers: the App Router and the Pages Router.

    React version handling

    Next.js uses the latest stable or canary versions of React.

    `; const result = await compileHtmlToMarkdown(nextDocsHtml, 'https://nextjs.org/docs'); // 1. Visible-Text Recall Gate: All key article sections MUST be present expect(result.markdown).toContain('## What is Next.js?'); expect(result.markdown).toContain('Next.js is a React framework for building full-stack web applications'); expect(result.markdown).toContain('## How to use the docs'); expect(result.markdown).toContain('## App Router and Pages Router'); expect(result.markdown).toContain('## React version handling'); // 2. Document Context Gate: Version & router context preserved cleanly expect(result.markdown).toContain('Latest Version: 16.4.0'); expect(result.markdown).toContain('Using App Router'); // 3. No Spurious "Yes" Gate: Dropdown chevrons MUST NOT emit "Yes" expect(result.markdown).not.toContain('16.4.0 / Yes'); expect(result.markdown).not.toContain('/ Yes'); // 4. Anti-Scaffolding Gate: No synthetic HTML cite- anchors or wrapper headings expect(result.markdown).not.toContain('id="cite-'); expect(result.markdown).not.toContain('## Core Page Content'); expect(result.markdown).not.toContain('## Structured Entity Metadata'); // 5. Strictly ONE Primary H1 Gate: Must not duplicate page title and article H1 const h1Headings = result.markdown.match(/^#\s+[^\n]+/gm) || []; expect(h1Headings).toHaveLength(1); expect(result.markdown).toContain('# Next.js Docs'); expect(result.markdown).not.toContain('# Next.js Docs | Next.js'); // 6. Feedback Widget Stripping Gate: "Was this helpful? supported. Send" MUST NOT leak expect(result.markdown).not.toContain('Was this helpful?'); expect(result.markdown).not.toContain('supported. Send'); // 7. Zero Synthetic Metadata Table Gate: Bot-only tables from JSON-LD stripped expect(result.markdown).not.toContain('### Technical Documentation'); // 8. Pagination Context Gate: Previous/Next navigation preserved expect(result.markdown).toContain('**Navigation:**'); expect(result.markdown).toContain('[← Previous: Rspack](/docs/community/rspack)'); expect(result.markdown).toContain('[Next: App Router →](/docs/app)'); }); it('SaaS Pricing Matrix (Resend Benchmark): verifies clean tables, deduplicates carousels, prunes orphan tablists, and marks exclusions', async () => { const resendPricingHtml = ` Pricing · Resend

    Pricing

    FreeRecommended

    $0 / mo
    • 3,000 emails/mo
    • Single Sign-On

    ProRecommended

    $20 / mo
    • 50,000 emails/mo
    • Single Sign-On

    Deliverability & reliability

    FeatureFreePro
    Custom domains 3 10
    DKIM, SPF, DMARC
    Dedicated IPs – With add-on

    Frequently asked questions

    `; const result = await compileHtmlToMarkdown(resendPricingHtml, 'https://resend.com/pricing'); // 1. FAQ Heading & Answer Gate: Must NOT prepend "### Yes" or leave empty "### " expect(result.markdown).not.toContain('#### Yes'); expect(result.markdown).not.toMatch(/^###\s*$/m); expect(result.markdown).toContain('### Do you offer any discounts for annual subscriptions?'); expect(result.markdown).toContain('No, we only provide monthly plans.'); // 2. Tablist Pruning Gate: Orphan tablist button labels MUST be pruned from AST expect(result.markdown).not.toContain('Transactional emails\nMarketing emails'); expect(result.markdown).toContain('omitted_dynamic_states: ["non_default_tab_panels", "volume_slider_tiers"]'); // 3. Hidden Text Gate: Opacity-0 badges must NOT concatenate onto plan titles expect(result.markdown).not.toContain('FreeRecommended'); expect(result.markdown).not.toContain('ProRecommended'); expect(result.markdown).toContain('### Free'); expect(result.markdown).toContain('### Pro'); expect(result.markdown).toMatch(/^###\s+Free\s*$/m); expect(result.markdown).toMatch(/^###\s+Pro\s*$/m); // 4. Plan Pricing & Quota Recall Gate expect(result.markdown).toContain('$0 / mo'); expect(result.markdown).toContain('$20 / mo'); expect(result.markdown).toContain('3,000 emails/mo'); expect(result.markdown).toContain('50,000 emails/mo'); // 5. Exclusions Marker Gate: Single Sign-On must be marked as excluded in Free plan card expect(result.markdown).toContain('✖ Single Sign-On'); // 6. Comparison Table Gate: Checks converted to Yes, dashes preserved expect(result.markdown).toContain('| DKIM, SPF, DMARC | Yes | Yes |'); expect(result.markdown).toContain('| Dedicated IPs | – | With add-on |'); // 7. No Raw JSON-LD in Body Gate:

    Enterprise Pricing

    Deprecated tier: $888 / mo

    Starter

    $20 / mo

    Base tier

    Team

    $49 / mo

    Collaborative tier

    Scale

    $200 / mo

    Growth tier

    Enterprise

    $1,150 / mo

    Includes dedicated IP and SLA

    Volume Pricing

    High-volume automations billed at $0.0015 / per run.

    `; // 1. Direct verification of the converter-independent reference extractor const independentRef = extractIndependentStaticReference(pricingHtml); expect(independentRef.currencyTokens).toContain('$20 / mo'); expect(independentRef.currencyTokens).toContain('$49 / mo'); expect(independentRef.currencyTokens).toContain('$200 / mo'); expect(independentRef.currencyTokens).toContain('$1,150 / mo'); expect(independentRef.currencyTokens).toContain('$0.0015 / per run'); // Non-visible prices in