How to Test html-to-pdfmake Conversion: A Complete Guide
You can test html-to-pdfmake conversion by supplying a jsdom window object in Node.js, calling htmlToPdfMake(htmlString, options), and asserting against the returned PDFMake document definition structure using deep equality checks on properties like text, bold, table.body, or image.
The html-to-pdfmake library transforms HTML strings into PDFMake-compatible document definitions, enabling dynamic PDF generation from rich text content. Whether you are building a Node.js service or a browser application, testing this conversion pipeline ensures that your HTML markup reliably produces the expected PDF structure. This guide covers how to test html-to-pdfmake conversion using the repository's built-in testing patterns, from unit assertions to end-to-end PDF generation.
Understanding the html-to-pdfmake Conversion Pipeline
The converter is deterministic—given the same HTML string and options, it always produces the same JSON definition. This purity makes unit testing straightforward. The pipeline consists of seven distinct phases:
Step 1: Initialization
The exported function in index.js (lines 1176-1178) creates a new htmlToPdfMake instance, storing options like window, tableAutoSize, imagesByReference, and default styles.
Step 2: HTML Parsing
The convertHtml function (lines 21-30) builds a DOM using DOMParser in the browser or the supplied window in Node.js, then invokes parseElement on the <body> tag.
Step 3: Recursive Traversal
parseElement (lines 41-99) walks the tree depth-first, handling text nodes (nodeType 3) and element nodes (nodeType 1). For each element, it pushes the current element onto a parents stack, recursively processes children, and decides whether a stack (mixed content) is required via searchForStack.
Step 4: Element-Specific Handling
A switch-case in parseElement implements behavior for tags such as <TABLE>, <IMG>, <HR>, <OL>/<UL>, <A>, and <SVG>. For tables, the code builds ret.table.body, resolves colSpan/rowSpan, and optionally runs the auto-size algorithm when tableAutoSize is enabled (lines 1100-1195).
Step 5: Style Inheritance
applyStyle (lines 55-87) walks the parents stack, merging default styles, inline CSS, and class names into the resulting node. It respects options like removeTagClasses and ignoreStyles.
Step 6: CSS Parsing
parseStyle (lines 68-124) extracts CSS declarations, converts units (px, pt, rem, …) via convertToUnit, normalizes colors via parseColor, and builds PDFMake-compatible keys (margin, border, decoration, …).
Step 7: Finalization
After the DOM walk finishes, convertHtml (lines 61-73) normalizes the result: a pure string becomes {text:…}; if imagesByReference is active, the function returns {content, images}.
Setting Up Your Test Environment
To test html-to-pdfmake conversion in Node.js, you must provide a DOM environment because the library relies on browser APIs like DOMParser and getComputedStyle.
Install the required dependencies:
npm install jsdom
Then initialize the test environment:
// test-setup.js
const htmlToPdfMake = require('./index.js');
const { JSDOM } = require('jsdom');
const { window } = new JSDOM('');
module.exports = { htmlToPdfMake, window };
Writing Unit Tests for html-to-pdfmake Conversion
The library returns plain JavaScript objects, making assertions straightforward using deep equality checks on JSON.stringify outputs or property access.
Testing Basic Text Formatting
Verify that inline tags like <b> and <em> produce the correct PDFMake properties:
const { htmlToPdfMake, window } = require('./test-setup');
function testBasicFormatting() {
const ret = htmlToPdfMake("<b>bold word</b>", { window });
const firstNode = ret[0];
if (firstNode.text !== "bold word" || firstNode.bold !== true) {
throw new Error("Bold formatting test failed");
}
console.log("✅ Basic formatting test passed");
}
testBasicFormatting();
Testing Tables with Colspan and Rowspan
Complex table layouts require verifying the table.body structure and cell properties:
const html = `
<table>
<tr><th colspan="2">Header</th></tr>
<tr><td>A</td><td>B</td></tr>
</table>`;
const result = htmlToPdfMake(html, { window });
const table = result[0].table;
// Verify header has colSpan
console.assert(table.body[0][0].colSpan === 2, "Header colSpan failed");
// Verify TH styles (bold + fillColor from defaults)
console.assert(table.body[0][0].bold === true, "Header bold failed");
console.assert(table.body[0][0].fillColor === "#EEEEEE", "Header fillColor failed");
console.log("✅ Table structure test passed");
Testing Images by Reference
When using the imagesByReference option, the function returns an object with separate content and images properties:
const result = htmlToPdfMake(
'<img src="https://example.com/pic.png">',
{ window, imagesByReference: true }
);
// Verify structure
if (!result.images || !result.content) {
throw new Error("imagesByReference structure invalid");
}
// Verify the image URL is stored correctly
const imageKeys = Object.keys(result.images);
if (result.images[imageKeys[0]] !== "https://example.com/pic.png") {
throw new Error("Image URL mismatch");
}
console.log("✅ Images by reference test passed");
Testing Table Auto-Size
Verify that the tableAutoSize option correctly converts CSS widths to PDFMake column widths:
const html = `<table><tr><td style="width:200px">A</td><td>B</td></tr></table>`;
const def = htmlToPdfMake(html, { window, tableAutoSize: true });
const widths = def[0].table.widths;
if (!Array.isArray(widths) || widths.length !== 2) {
throw new Error("Table widths array invalid");
}
// First column should be a number (converted from 200px), second should be 'auto'
if (typeof widths[0] !== 'number' || widths[1] !== 'auto') {
throw new Error("Table auto-size values incorrect");
}
console.log("✅ Table auto-size test passed");
End-to-End Testing with PDFMake
For complete validation, pipe the generated definition into PDFMake and verify the output file:
// example-test.js
const htmlToPdfMake = require('./index.js');
const pdfMake = require('pdfmake/build/pdfmake');
const pdfFonts = require('pdfmake/build/vfs_fonts');
pdfMake.vfs = pdfFonts;
const { JSDOM } = require('jsdom');
const { window } = new JSDOM('');
const html = `
<h2 style="color:#ff0033">Demo</h2>
<p>This is <strong>bold</strong> and <em>italic</em>.</p>
<table style="width:100%">
<tr><th>Item</th><th>Price</th></tr>
<tr><td>Apple</td><td>$1</td></tr>
</table>
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..." />
`;
const docDef = {
content: htmlToPdfMake(html, { window, tableAutoSize: true })
};
pdfMake.createPdf(docDef).write('output.pdf', () => console.log('PDF generated'));
Running node example-test.js produces output.pdf. You can manually inspect the PDF or compare the docDef.content object against an expected JSON fixture.
Key Source Files for Reference
| File | Role | Link |
|---|---|---|
index.js |
Core conversion engine (parsing, style handling, options) | https://github.com/aymkdn/html-to-pdfmake/blob/master/index.js |
README.md |
Usage guide, options reference, feature list | https://github.com/aymkdn/html-to-pdfmake/blob/master/README.md |
test/unit.js |
Official unit-test suite – great source of expected outputs | https://github.com/aymkdn/html-to-pdfmake/blob/master/test/unit.js |
example.js |
Minimal end-to-end demo that writes a PDF file | https://github.com/aymkdn/html-to-pdfmake/blob/master/example.js |
docs/browser-2.5.32.js |
Browser-ready bundle (for quick in-page testing) | https://github.com/aymkdn/html-to-pdfmake/blob/master/docs/browser-2.5.32.js |
Summary
- Deterministic output: The
htmlToPdfMakefunction inindex.jsalways returns the same JSON structure for identical inputs, making assertions reliable viaJSON.stringifycomparisons. - Node.js testing: You must provide a
windowobject fromjsdombecause the library relies on browser DOM APIs likeDOMParserandgetComputedStyle. - Assertion strategy: Validate specific properties of the returned definition—such as
ret[0].text,ret[0].bold,ret[0].table.body, orret.images—rather than comparing the entire object if minor version differences exist. - Built-in reference: The
test/unit.jsfile demonstrates the official testing pattern using thesimple-test-framework, providing copy-paste templates for custom tests. - End-to-end validation: For complete confidence, pass the generated definition to
pdfMake.createPdf()and verify the output file or stream.
Frequently Asked Questions
How do I test html-to-pdfmake in a Node.js environment?
You must install jsdom to simulate a browser DOM, then pass the window object to the converter. The library requires DOMParser and getComputedStyle, which are not native to Node.js. Initialize jsdom, extract the window object, and include it in the options: htmlToPdfMake(html, { window }).
What is the best way to assert against the generated PDFMake definition?
Because the library returns plain JavaScript objects, use deep equality checks on JSON.stringify outputs or direct property assertions. Focus on critical nodes: verify ret[0].text for content, ret[0].bold for styling, ret[0].table.body for table structures, and ret.images when using imagesByReference. This approach isolates failures better than comparing entire complex objects.
Can I test the actual PDF output or just the document definition?
You can test both. Unit tests should target the document definition returned by htmlToPdfmake for speed and precision. For integration testing, pass the definition to pdfMake.createPdf() and write the output to a file or buffer, then verify the file exists or inspect its binary structure using PDF parsing libraries if necessary.
How do I handle images when testing html-to-pdfmake conversion?
When testing images, use the imagesByReference: true option to separate image URLs from the content array. This returns an object with content (containing placeholder references like img_ref_abc123) and images (a map of placeholders to URLs). Assert that result.images contains the expected URL keys and that the content array references those keys correctly, rather than embedding base64 data directly.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →