/** * E2E tests for the direct HTML input path. * * These tests use small inline HTML strings rather than the shared fixture to * verify edge cases in the html→markdown pipeline independently of readability. */ import { describe, it } from 'node:test'; import assert from 'node:assert'; import { getAgent } from '../helpers/client'; async function crawlHtml(html: string, opts: Record = {}) { return getAgent() .post('/') .set('Accept', 'application/json') .set('Content-Type', 'application/json') .send({ html, url: 'https://example.com/test', ...opts }); } describe('minimal HTML input', () => { it('processes a bare paragraph', async () => { const res = await crawlHtml('

Hello world

'); assert.strictEqual(res.status, 200); assert.ok(res.body.data.content.includes('Hello world')); }); it('processes HTML with only a heading', async () => { const res = await crawlHtml('

Only Heading

'); assert.strictEqual(res.status, 200); assert.match(res.body.data.content, /Only Heading/); }); }); describe('HTML entity handling', () => { it('decodes & to & in output', async () => { const res = await crawlHtml('

Tom & Jerry

'); assert.strictEqual(res.status, 200); assert.ok(res.body.data.content.includes('Tom & Jerry')); }); it('decodes < to < in output', async () => { const res = await crawlHtml('

1 < 2

'); assert.strictEqual(res.status, 200); assert.ok(res.body.data.content.includes('1 < 2')); }); it('decodes > to > in output', async () => { const res = await crawlHtml('

2 > 1

'); assert.strictEqual(res.status, 200); assert.ok(res.body.data.content.includes('2 > 1')); }); }); describe('unicode content', () => { it('preserves Japanese characters', async () => { const res = await crawlHtml('

日本語テスト

'); assert.strictEqual(res.status, 200); assert.ok(res.body.data.content.includes('日本語テスト')); }); it('preserves emoji characters', async () => { const res = await crawlHtml('

Hello 🌍 World

'); assert.strictEqual(res.status, 200); assert.ok(res.body.data.content.includes('🌍')); }); }); describe('nested document structure', () => { it('extracts headings from nested article/section elements', async () => { const html = `

Top Level

Sub Section

Body text

`; const res = await crawlHtml(html); assert.strictEqual(res.status, 200); assert.match(res.body.data.content, /Top Level/); assert.match(res.body.data.content, /Sub Section/); assert.match(res.body.data.content, /Body text/); }); }); describe('output determinism', () => { it('identical HTML sent twice produces identical content', async () => { const html = '

Deterministic

Same every time.

'; const [r1, r2] = await Promise.all([crawlHtml(html), crawlHtml(html)]); assert.strictEqual(r1.status, 200); assert.strictEqual(r2.status, 200); assert.strictEqual(r1.body.data.content, r2.body.data.content); }); });