DEV Community

Test HTML-to-DOCX Export as a Contract, Not a Screenshot

DOM-docx, an MIT-licensed HTML-to-native-Word project, is trending today.

โ€œLooks right in one screenshotโ€ is not enough for an export feature. The contract spans structure, editing, pagination, and interoperability.

Create a golden fixture containing headings, nested lists, a table, links, inline styles, an image, code, page breaks, and non-Latin text. Export it, then inspect the DOCX package as ZIP/XML.

import { readFile } from "node:fs/promises";
import JSZip from "jszip";

const zip = await JSZip.loadAsync(await readFile("out.docx"));
const xml = await zip.file("word/document.xml").async("string");

for (const text of ["Heading One", "ๆฑไบฌ", "example.com"]) {
  if (!xml.includes(text)) throw new Error(`missing: ${text}`);
}

Test Layers

Add four test layers:

  • Schema/package validation
  • Semantic assertions on headings, lists, and links
  • Visual snapshots rendered by at least two office suites
  • An edit round-trip where a user changes text, saves, and reopens the file

CSS and Limits

Define unsupported CSS explicitly. A deterministic warning for position: fixed is better than silently producing a misleading document.

Set limits for image size, document length, memory, and export time. Sanitize remote URLs and never let HTML reference arbitrary local files.

Treat the exporter as a compiler: HTML is input, OOXML is output, warnings are part of the API, and fixtures are compatibility tests.

Comments

No comments yet. Start the discussion.