Word documents
Snapshot.VerifyDocxAsync snapshots DOCX files the same way, with the same
received and verified files, accept mode and report. It reads the file directly: no Word, Office or Open XML SDK needed.
[Fact]
public async Task Notes_ShouldMatchApprovedSnapshot_WhenGenerated()
{
using Stream docx = await NotesGenerator.CreateAsync();
await Snapshot.VerifyDocxAsync(docx);
}
Snapshots are saved as {name}.verified.docx.txt. The Name, Variant and Directory options work as for
PDF snapshots, and the document can be a stream, a byte[] or a DocxDocument
already loaded, read the same way as a PDF. Snapshot.VerifyDocx is the synchronous version, for
a test that isn't async.
What a snapshot looks like
A DOCX snapshot reads like the document: one line per paragraph with its runs merged, and only what differs from its style listed.
# docx-snapshot v1
document
metadata title="Trail notes" created=yes modified=yes
settings lang=en-US compat=15 track-changes=no protection=none even-odd-headers=no
defaults font="Calibri" size=11
sections
s1 letter margins=72,72,72,72 header=36 footer=36 columns=1 break=nextPage headers=[default]
styles
ListParagraph paragraph "List Paragraph" font="Arial" size=12 indent-left=36
TableGrid table "Table Grid" font="Calibri" size=11
numbering
list 1 definition=1
level 0 format=decimal text="%1." start=1 indent=36 hanging=18
body
P style=ListParagraph list=1:0 label="1." "Bring a trail map"
span "trail" bold
Table style=TableGrid widths=[144,216]
Row header
Cell
P "Trail"
Cell
P "Length"
P "Visit example.com"
link "example.com" target="https://example.com" at=6
P
image inline size=120x40 alt=(missing) type=png hash=3f9c0a1b2d4e5f60 at=0
headers
s1 default
P "Page 3"
field "PAGE" result="3" at=5
footers
(none)
notes
(none)
The Word snapshot format reference lists every section and line.
What's recorded
- Document settings, each section's page setup, and headers and footers.
- The styles in use, with their properties resolved through the styles they're based on. Styles nothing uses are left out, since they can't change the document.
- List labels as Word numbers them.
- Paragraph layout and text formatting.
- Tables: grid, header rows, merged cells, shading, widths, margins and borders, alt text, row heights, cell alignment and text direction, and content controls around rows and cells.
- Images and charts with their alt text and a hash of the image; text boxes with their paragraphs; equations; embedded objects and ActiveX controls.
- Links, bookmarks, symbols, fields with their results, and form controls.
- Tracked changes to text, paragraphs and their marks, tables, rows, cells and section settings.
- Footnotes, endnotes, comments, and inserted documents.
Relationship IDs, editing-session IDs and the zip's layout are left out, so regenerating the same document gives the same snapshot.
Anything PDiffy doesn't read yet, such as a phonetic guide (w:ruby), prints as unsupported <element> hash=..., so a
change to it still fails the test.
Leave out what changes
await Snapshot.VerifyDocxAsync(docx, configure: options => options
// A PAGE field's cached result depends on where Word last laid out the page.
.Ignore(DocxDetail.FieldResults)
// The template's styles are tested elsewhere.
.Ignore(DocxSection.Styles)
.ScrubDates());
See Ignore and scrub for every option.
Assert on the model
DocxDocument.Load gives the same content as properties:
DocxDocument notes = DocxDocument.Load("notes.docx");
// Every image has alt text.
Assert.All(notes.Images(), image => Assert.NotNull(image.AltText));
// No tracked changes shipped.
Assert.Empty(notes.Revisions());
// Nothing is deleted in a tracked change.
Assert.DoesNotContain(notes.Revisions(), revision => revision.Kind == DocxRevisionKind.Delete);
// The first paragraph uses the Title style.
Assert.Equal("Title", notes.Paragraphs().First().Style);
| Member | Gives |
|---|---|
Paragraphs() |
Every paragraph in the body, including those in tables, content controls, text boxes and inserted documents |
Images() |
Every image, chart and shape in the body, headers, footers and notes |
Revisions() |
Every tracked change, in reading order |
Body, Headers, Footers, Notes |
The content, as blocks |
Styles, Lists, PageSetups |
Styles in use, lists and section setups |
CompareTo(after) |
A comparison with another document |
Check() |
What the Word checks find, such as an image with no alt text, each with the path a diff shows |
ToTranscript() |
The body as the lines a screen reader announces, in reading order, like a PDF's transcript: headings by outline level, images by alt text (leaving out decorative ones), tables with their header rows, lists and links. pdiffy read notes.docx prints it |
Kinds whose values PDiffy defines are enums: DocxRevisionKind,
DocxFormKind and DocxNoteKind. Values PDiffy copies from the
file stay strings, so a nonstandard value still comes through. Classes such as
DocxAlignments (where "both" means justified) and
DocxStyleTypes list the standard values, and the
API reference lists every such class.
See also
- Word snapshot format
DocxDocumentin the API reference