Skip to content

test(qa): hold the ways a page breaks inside a panel in the DOCX fidelity corpus - #965

Merged
DemchaAV merged 3 commits into
2.5-devfrom
test/docx-page-break-fidelity
Oct 25, 2026
Merged

DemchaAV merged 3 commits into
2.5-devfrom
test/docx-page-break-fidelity

Conversation

@DemchaAV

@DemchaAV DemchaAV commented Oct 25, 2026 •

Copy link
Copy Markdown
Owner

Why

The ways a page breaks inside a panel are each held by unit tests and qa tests that read the written DOCX:

Each was measured in Word and LibreOffice once, when it was fixed. No document of the DOCX fidelity corpus has any of these shapes, so the gate that holds every line of the corpus where the editor set it — LibreOffice in CI, Word on Windows — would not notice an editor setting one of them off the page again.

What changed

  • SyntheticDocxCorpus (new family synthetic): documents built for shapes no preset has on its own fixture.
    • break_in_panel: a card with a page break among its children and a card nested in it with a break of its own, over three pages.
    • break_in_column: page breaks in a row's column and in a stack's layer, on one page.
    • card_over_pages: a bordered card whose table of 60 rows, its header repeated, runs over three pages, the pages after the first set against a larger top margin. It is spaced so that page 1's rows leave room for the paragraph that ends a Word section at the cut: at a gap of 8 or 10pt the export names page 2's margins instead, and both editors set page 2 with page 1's (measured: 52.9pt high).
    • Text in Lato, which the export embeds: in the default Helvetica, which it does not embed, LibreOffice set two lines at other words in a substituted face.
  • InvoiceDocxCorpus: obsidian_long (line items ×12: the card run over four pages with other margins from page 2, and the break after the info cards) and metered_long (×9: the gap above the closing row carried onto page 4). Its withLinesRepeated replaces the private copies in InvoicePanelOverPagesDocxTest and InvoiceNaturalPageBreakDocxTest.
  • DocxFidelityCorpusTest.corpus() takes the synthetic family: 62 documents → 67.
  • Baselines. word-windows and libreoffice-windows take the five documents' rows alone, copied from what their runs measured; the presets' rows stay as recorded. Word here is now 16.0.20527 and the presets' rows were recorded with 16.0.20430: retaking them would carry that build's drift into this change. libreoffice-linux takes the five rows from this PR's first CI run (artifact docx-fidelity-40241271303), where the job failed on those five alone, each not yet in the baseline. A comment under each file's header says where the added rows were measured.
  • Docs: CONTRIBUTING.md (the corpus's synthetic documents, where a preset on a longer fixture and a shape no preset has join), the docx-fidelity job's comment in ci.yml, the synopsis of word-fidelity.ps1, the CHANGELOG.

Measured

Pages, lines found, then the median and p90 of the found lines' drift down (pt); the gate holds each line's drift across as well:

Document Pages Word 16 (Windows) LibreOffice 26.8 (Windows) LibreOffice 24.2 (Linux, CI)
synthetic-break_in_panel 3 3, 8/8, 0.95 / 0.99 3, 8/8, 3.02 / 5.02 3, 8/8, 3.02 / 5.02
synthetic-break_in_column 1 1, 7/7, 0.03 / 0.03 1, 7/7, 0.02 / 0.02 1, 7/7, 0.02 / 0.02
synthetic-card_over_pages 3 3, 114/114, 1.03 / 1.15 3, 114/114, 0.98 / 1.08 3, 114/114, 0.98 / 1.08
invoice-obsidian_long 5 5, 375/375, 0.94 / 1.14 5, 358/375, 0.85 / 0.95 5, 375/375, 4.17 / 8.36
invoice-metered_long 4 4, 350/350, 0.06 / 0.16 4, 350/350, 0.10 / 0.23 4, 334/350, 41.91 / 96.38
  • Word sets every line of every document on the page the PDF sets it on. LibreOffice 26.8 sets each on as many pages, but carries ObsidianInvoice's info cards to page 5 (the 17 lines not found; page 5 128.6pt low), where Word and LibreOffice 24.2 keep them on page 4.
  • LibreOffice 24.2 (CI) sets each on the pages the PDF does. It sets the two long invoices' line items high — ObsidianInvoice's by up to 10pt; MeteredInvoice's more so page after page, by a median of 52 and 87pt on its second and third pages, 16 of its lines on another page — as it sets the presets' long tables (invoice-metered alone: p90 10.6pt). The last pages, which carry the page break after the cards and the gap above the closing row, stand within 0.8pt: ObsidianInvoice's page 5 at +0.02pt, MeteredInvoice's page 4 at −0.52pt.
  • Word's drift down is mostly the top border of a card's part after a cut (1pt, named in the report); ObsidianInvoice's info cards and totals stand up to 1.9pt low. Across, Word sets card_over_pages's amounts 36.4pt left — its table's first column narrower than its grid, 49 of 114 lines — where LibreOffice keeps the grid (0.6pt).
  • In LibreOffice 24.2 and 26.8 the parts of break_in_panel's card after its explicit breaks stand 3 to 5pt high. LibreOffice 24.2 also sets a card's text right — 8.6pt in break_in_panel, 7.1pt in card_over_pages — as it does some of the presets' panel lines in its baseline (cv-panel up to 8.6pt); 26.8 on Windows does not.

Tests

Named, not fixed

  • In LibreOffice 24.2 and 26.8 a card's part after an explicit page break stands 3 to 5pt high, where Word sets it within 1pt. Only synthetic-break_in_panel has it; no preset breaks a page inside a panel.
  • card_over_pages is spaced around a limit of fix(docx): end a page-margin section at a panel's cut #963: at a gap of 8 or 10pt above the card, page 1's rows leave no room for the paragraph that ends a Word section at the cut, the export names page 2's margins, and both editors set page 2 with page 1's, about 53pt high. A change to a table's metrics can tip it there; the class's Javadoc says so, and the answer is to re-space the fixture.
  • LibreOffice 24.2 sets the two long invoices' line items high, MeteredInvoice's more so page after page and with 16 lines on another page, as it does the presets' long tables. The gate compares each line's drift to its baseline's either way, so on those pages a change that moves lines back toward the page passes; their last pages, where the P0-5 shapes are, stand within 0.8pt and are held.
  • Word sets the amounts of card_over_pages's table 36.4pt left, the table nested in the card with its first column narrower than its grid; LibreOffice keeps the grid. Nothing to do with the page breaks; the baseline holds it.
  • LibreOffice 26.8 on Windows carries ObsidianInvoice's info cards to page 5 with its line items repeated 12 times, where LibreOffice 24.2 and Word keep them on page 4. It did so before the page break after the cards was fixed as well (the same document exported before and after it, converted by the same 26.8: identical). The Windows baseline holds it as it stands.
  • Run locally, libreoffice-windows also fails invoice-obsidian and proposal-indigo on 2.5-dev itself: LibreOffice 26.8 sets each on 2 pages against the page's 1. It set them so before the page break after a card was fixed too (the export before that change, converted by the same build); an earlier change since that baseline was taken (2026-10-14) moved them. This change exports both as before, and the five new documents pass it.
  • The fixture covers a page break in a painted card and in a painted card nested in it, and the breaks the page ignores in a row's column and in a stack's layer; a composed table cell, a shape container's layer, a canvas and an unpainted section in a card stay held by the unit tests alone.
  • A baseline rewritten with -Dgraphcompose.docxFidelity.update=true keeps one note: the comment saying where the five documents' rows were measured goes with it.

Lane: tests (qa). No public API change, and no change to the export.

…lity corpus

The DOCX fidelity corpus had no document in which a page breaks inside
a panel, so the gate holding every line of the corpus in LibreOffice and
Word could not see an editor set one off the page again.

A synthetic family joins it, built for shapes no preset has: a page
break among a card's children and inside a card nested in it, breaks the
page ignores in a row's column and a stack's layer, and a bordered card
whose table runs over three pages with other margins from the second.
ObsidianInvoice and MeteredInvoice with their line items repeated join
the invoices. The Word and Windows LibreOffice baselines take the five
documents' rows alone.
…elity baseline

The five documents' rows come from the pull request's first CI run, in
which the DOCX Fidelity job failed on them alone, each not yet in the
baseline. LibreOffice 24.2 sets each on the pages the PDF does; the two
long invoices' line items stand high page after page, as the presets'
long tables do, and their last pages, where the page break after the
cards and the gap above the closing row are, within 0.8pt.

The fixture's Javadoc says what the bordered card's spacing limit looks
like when a change tips it there; CONTRIBUTING says a preset on a longer
fixture stays in its family's corpus class; the Word fidelity script's
synopsis names the synthetic documents.
The gate holds the lines it finds; ObsidianInvoice's line items stand
high in LibreOffice 24.2 without growing page after page, as
MeteredInvoice's do. The bordered card's Javadoc says to check the
export's report before re-spacing it, as a lost section at the cut looks
the same in the gate.
@DemchaAV
DemchaAV marked this pull request as ready for review October 25, 2026 23:03
@DemchaAV
DemchaAV merged commit c2bac3f into 2.5-dev Oct 25, 2026
13 checks passed
@DemchaAV
DemchaAV deleted the test/docx-page-break-fidelity branch October 25, 2026 23:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant