A cross-implementation conformance test suite for WordprocessingML (.docx),
in the spirit of web-platform-tests
and wpt.fyi.
Every scenario in this suite asserts behavior that is derivable from ECMA-376 (Office Open XML), cited by edition, part, and section — never from any one library's internal algorithm. Implementations participate through small adapter binaries; the runner compares each adapter's output against the scenario's assertions and publishes a results matrix.
WordprocessingML conformance only, currently:
- tracked changes (
w:ins/w:delaccept and reject semantics), - find-replace over run text,
- schema validity (optional
xmllint+ WML XSD tooling — seedocs/scenario-dsl.md).
SpreadsheetML and PresentationML are out of scope.
An honest unsupported outcome is part of the design: an implementation
with no tracked-changes API reports unsupported (exit code 2) for those
scenarios rather than failing, and the matrix shows the gap. That asymmetry
is information, not noise.
The superdoc-sdk adapter exercises SuperDoc's headless Document API for
tracked-change accept/reject and find-replace coverage. It is optional like
the other adapters, but note that its upstream @superdoc-dev/sdk package is
published as AGPL-3.0.
The same honesty cuts the other way: an implementation that satisfies the
cited clause but serializes differently — materializing formatting defaults
on save, say — is graded pass-divergent, not fail. canonicalXmlEquals
pins serialization granularity beyond what the clause requires, and the suite
does not claim a conformance failure where there is only serialization
freedom. See "Outcome grading" in docs/scenario-dsl.md.
Published results live at results/latest.json and include a top-level
schemaVersion. The JSON contract is published alongside the data as
results/results.schema.json (draft 2020-12), and CI validates every emitted
results document against it before publishing.
docs/ scenario DSL and adapter protocol specifications (versioned)
scenarios/ one directory per scenario: scenario.json + input/ + expected/
adapters/ one directory per registered implementation adapter
runner/ the neutral runner (Node, @xmldom/xmldom; no implementation deps)
registry/ adapters.json — registered adapters and their invocation commands
results/ latest published results snapshot (also published to gh-pages)
cd runner
npm ci
npm run check-fixtures # verify input.docx packages match input/document.xml
npm run suite # run all registered adapters, write ../results/latest.json
npm run validate-results # validate ../results/latest.json against the schemaScenarios that use schemaValidAgainstWml require xmllint and
DPT_WML_SCHEMA_PATH pointing to a WordprocessingML XSD entry point whose
imports are resolvable from that file. Set DPT_XMLLINT_BIN to override the
xmllint binary name/path.
Write an adapter that satisfies docs/adapter-protocol.md (a CLI taking
--protocol-version 1 --operation operation.json --input input.docx --output output.docx), add it under adapters/<name>/, and register it in
registry/adapters.json. Adapters must decline operations they cannot
perform with exit code 2 — never approximate.
A scenario must cite the ECMA-376 section its assertion derives from. Where
Microsoft Word's observed behavior deviates from a strict reading of the
spec, record it in the scenario's wordBehaviorNote. See
docs/scenario-dsl.md for the format and the assertion-strength rules.
Apache-2.0. ECMA-376 is cited by section number only; no spec text is reproduced in this repository.