import { describe, expect, it } from "vitest"; import { exportDocxBlob, htmlToWordBlocks, importDocxFile } from "./wordOffice"; const tinyPngBase64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+/p9sAAAAASUVORK5CYII="; const tinyPngDataUri = `data:image/png;base64,${tinyPngBase64}`; describe("wordOffice DOCX import", () => { it("imports DOCX Heading 3-6 as h3-h6", async () => { const blob = await exportDocxBlob("Headings.docx", "
Quoted fragment"); const file = new File([blob], "Quote.docx", { type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }); const imported = await importDocxFile(file); expect(imported.html).toContain("
Quoted fragment"); expect(htmlToWordBlocks(imported.html)).toEqual([ { type: "paragraph", text: "Quoted fragment", runs: [{ text: "Quoted fragment" }], quote: true } ]); }); it("imports DOCX text color and highlight from OOXML", async () => { const blob = await exportDocxBlob( "Color.docx", '
Color fragment
' ); const file = new File([blob], "Color.docx", { type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }); const imported = await importDocxFile(file); expect(imported.html).toContain("color: #0F5FAE;"); expect(imported.html).toContain("background-color: #FFF2CC;"); expect(htmlToWordBlocks(imported.html)).toEqual([ { type: "paragraph", text: "Color fragment", runs: [{ text: "Color fragment", color: "0F5FAE", highlightColor: "FFF2CC" }] } ]); }); it("imports DOCX paragraph alignment from OOXML", async () => { const blob = await exportDocxBlob( "Alignment.docx", 'Centered
Right
Justified
' ); const file = new File([blob], "Alignment.docx", { type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }); const imported = await importDocxFile(file); expect(imported.html).toContain('style="text-align: center;"'); expect(imported.html).toContain('style="text-align: right;"'); expect(imported.html).toContain('style="text-align: justify;"'); expect(htmlToWordBlocks(imported.html)).toEqual([ { type: "paragraph", text: "Centered", runs: [{ text: "Centered" }], alignment: "center" }, { type: "paragraph", text: "Right", runs: [{ text: "Right" }], alignment: "right" }, { type: "paragraph", text: "Justified", runs: [{ text: "Justified" }], alignment: "both" } ]); }); it("imports DOCX font size from OOXML", async () => { const blob = await exportDocxBlob("FontSize.docx", 'Large text
'); const file = new File([blob], "FontSize.docx", { type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }); const imported = await importDocxFile(file); expect(imported.html).toContain("font-size: 18pt;"); expect(htmlToWordBlocks(imported.html)).toEqual([ { type: "paragraph", text: "Large text", runs: [{ text: "Large text", fontSize: 18 }] } ]); }); it("imports DOCX font family from OOXML", async () => { const blob = await exportDocxBlob("FontFamily.docx", 'Arial text
'); const file = new File([blob], "FontFamily.docx", { type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }); const imported = await importDocxFile(file); expect(imported.html).toContain("font-family: 'Arial';"); expect(htmlToWordBlocks(imported.html)).toEqual([ { type: "paragraph", text: "Arial text", runs: [{ text: "Arial text", fontFamily: "Arial" }] } ]); }); it("imports DOCX strikethrough from OOXML", async () => { const blob = await exportDocxBlob("Strike.docx", "Deleted text
H2O m2
"); const file = new File([blob], "Indexes.docx", { type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }); const imported = await importDocxFile(file); expect(imported.html).toContain("2"); expect(imported.html).toContain("2"); expect(htmlToWordBlocks(imported.html)).toEqual([ { type: "paragraph", text: "H2O m2", runs: [ { text: "H" }, { text: "2", subscript: true }, { text: "O m" }, { text: "2", superscript: true } ] } ]); }); it("imports DOCX line breaks from OOXML", async () => { const blob = await exportDocxBlob("LineBreak.docx", "Line 1
Line 2
BeforeAfter
'); const file = new File([blob], "PageBreak.docx", { type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }); const imported = await importDocxFile(file); expect(imported.html).toContain('data-qoffice-page-break="true"'); expect(htmlToWordBlocks(imported.html)).toEqual([ { type: "paragraph", text: "Before After", runs: [{ text: "Before\fAfter" }] } ]); }); it("imports DOCX tabs from OOXML", async () => { const blob = await exportDocxBlob("Tab.docx", 'Before\tAfter
'); const file = new File([blob], "Tab.docx", { type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }); const imported = await importDocxFile(file); expect(imported.html).toContain('data-qoffice-tab="true"'); expect(htmlToWordBlocks(imported.html)).toEqual([ { type: "paragraph", text: "Before After", runs: [{ text: "Before\tAfter" }] } ]); }); it("imports DOCX external hyperlinks from OOXML relationships", async () => { const blob = await exportDocxBlob("Hyperlink.docx", 'Open report.
'); const file = new File([blob], "Hyperlink.docx", { type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }); const imported = await importDocxFile(file); expect(imported.html).toContain(''); expect(htmlToWordBlocks(imported.html)).toEqual([ { type: "paragraph", text: "Open report.", runs: [ { text: "Open " }, { text: "report", bold: true, href: "https://example.com/report" }, { text: "." } ] } ]); }); it("imports DOCX internal hyperlink anchors from OOXML", async () => { const blob = await exportDocxBlob("InternalHyperlink.docx", 'Open section.
'); const file = new File([blob], "InternalHyperlink.docx", { type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }); const imported = await importDocxFile(file); expect(imported.html).toContain(''); expect(htmlToWordBlocks(imported.html)).toEqual([ { type: "paragraph", text: "Open section.", runs: [{ text: "Open " }, { text: "section", bold: true, href: "#Section1" }, { text: "." }] } ]); }); it("imports DOCX bookmarks as HTML ids", async () => { const blob = await exportDocxBlob("Bookmark.docx", 'Before table
| Stage | Owner |
|---|---|
| Plan | Anna |
After table
" ); const file = new File([blob], "Table.docx", { type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }); const imported = await importDocxFile(file); expect(imported.html).toContain("Stage | ");
expect(imported.html).toContain("Anna | ");
expect(htmlToWordBlocks(imported.html)).toEqual([
{ type: "paragraph", text: "Before table", runs: [{ text: "Before table" }] },
{
type: "table",
rows: [
["Stage", "Owner"],
["Plan", "Anna"]
]
},
{ type: "paragraph", text: "After table", runs: [{ text: "After table" }] }
]);
});
it("imports DOCX bullet and numbered lists from OOXML numbering", async () => {
const blob = await exportDocxBlob(
"Lists.docx",
'
| Stage | Done |