Files
pdfcraft/docs/document-properties-sessions.md
T
Perchenko Anton d47adeff89 M4: bind property drafts with edit-session and replay UI scenarios (#4594)
Binds Properties dialog drafts to the vendored edit-session crate (byte-identical to PerchAnton/edit-session@033f7c3a, ledger in vendor/README) and adds replayable UI scenarios. Includes a merge of main and a test covering the clean Properties inspection-tab live refresh.
2026-11-10 20:22:58 +01:00

6.4 KiB

Document Properties sessions and interaction replay

Status: proposed integration, updated 2026-11-10.

Document Properties binds its Description, Initial View and accepted Custom values to the document identity, edit generation and modification permission at opening. A different document, reload, edit or Undo/Redo closes the stale dialog with a notice. Returning to the original values through Undo still invalidates the old draft. The notice is included in the translation-gap scan; catalogs without its translation retain the standard English fallback. Clean inspection tabs (Fonts, Advanced, Security, Space Audit) retain live refresh for the same document; they never rebase accepted edits or pending Custom Name/Value input.

edit-session 0.1.0-alpha.2 is a dependency-free no_std library. The vendor ledger records the snapshot and its source revision. It checks freshness and consumes a draft once. PdfCraft retains its form validation, permission checks, PDF serialization and undo history. The UI bridge is crates/ui-egui/src/properties_session.rs; it stores small property values, not PDF bytes.

Typing does not edit the document. OK rechecks freshness on the serialized UI command path and dispatches one existing Edit::Batch. An engine refusal leaves the draft open for correction without applying part of the batch. Cancel/Escape, a no-op and stale dismissal dispatch no edit. Description whitespace and Custom name validation retain their existing behavior; Custom Name/Value input becomes part of the draft only through Add/Update. No new Reset control or metadata field is introduced.

The same document changes remain available through Session::apply, doc_set_info and doc_initial_view. The existing opt-in ui.set, ui.type, ui.click and ui.key control channel reaches the dialog. This patch adds no server or automation permission. It covers Document Properties only; the broader dialog lifecycle issue #3917 and OS open queueing are separate work.

Replaying the real dialog

The consumer owns crates/ui-egui/examples/properties_scenarios.rs, built in PdfCraft's workspace so it uses the same vendored patches and UI as the app. It is a development example, not a shipped executable. It runs the real egui controls through egui_kittest, then reports actual draft/document/history state as JSONL protocol 1.

interaction-check is a standard-library Python runner for optional local replay. The commands below pin it to 7722d66c0ede7855ff58d1df3d1632fd4e5e66a5. It sends only events; expected values stay in the runner. Each scenario starts a fresh adapter process with two synthetic, two-page PDFs. No corpus, network, proprietary fonts or committed PDF fixture is required.

From this repository, with Python 3.10+ and Rust 1.99.1:

git clone https://github.com/PerchAnton/interaction-check ../interaction-check
git -C ../interaction-check checkout 7722d66c0ede7855ff58d1df3d1632fd4e5e66a5
cargo build --locked -j 2 -p pdfcraft-ui-egui --example properties_scenarios
mkdir -p log/properties-interactions
PDFCRAFT_SYSTEM_FONTS=0 PDFCRAFT_LOCALE=en-US \
  python3 ../interaction-check/interaction_check.py --timeout 30 \
  --report log/properties-interactions/report.json \
  --junit log/properties-interactions/junit.xml \
  tests/interactions/document-properties/*.json -- target/debug/examples/properties_scenarios

On Windows, use properties_scenarios.exe and set environment variables with your shell. The commands write JSON and JUnit reports under log/properties-interactions/. Replay runs headlessly.

Events open, type, click, escape, undo and redo use actual UI commands/controls. external_edit, external_edit_undo, reload, switch and close_document simulate changes arriving outside that modal via the real session or tab selection. save_reopen serializes with the engine and opens the resulting bytes in a fresh session. inspect only advances frames and reports state. Document numbers are 1-based. Unsupported or disabled controls return a state error; the scenarios assert the resulting state after each action. Sixteen simulated frames after each event let the modal's animated layout settle.

Ten scenarios cover cross-tab commit/save/reopen, one-step Undo/Redo, Cancel/Escape, no-op with Redo, intervening edits, edit-then-Undo, same-ID reload, tab switch, target close, Custom validation and live inspection without rebasing pending input. Rust tests additionally cover an engine refusal/retry and the freshness check immediately before commit without an intervening UI frame.

For optional local screenshots and saved.pdf, append --artifacts DIR after the adapter executable while running one scenario. This requires an available GPU or software renderer. Keep PDFCRAFT_SYSTEM_FONTS=0; generated artifacts stay under ignored log/. The headless UI proves widget/engine behavior, not native OS input or PDF fidelity in a separate reader. Existing renderer and interoperability tests remain necessary.

Dependency review

The app builds from the vendored Rust source. The shared Cargo source rules apply to the entire lockfile. The ordinary Rust suite exercises stale edits, Undo and inspection tabs. Running the extended replay is an explicit developer choice. It uses a separate checkout and runs outside the app and its shared CI. Maintainers can review the snapshot or choose to implement the small draft guard in PdfCraft itself. This integration can be evaluated independently of craft-common-actions #84.

Revision history

  • 2026-11-10: reconcile current main's roadmap header; preserve both inactive password cleanup and the Properties draft guard. The vendored library and local replay contract are unchanged. Retain both new upstream print test modules alongside the Properties-session tests.

  • 2026-11-09: reconcile current main, preserving the vendor snapshot, local replay, both projects' license notices and the Properties-session and current upstream test modules.

  • 2026-11-05: vendor the original Rust revision with its lifecycle tests and licenses; keep the ten-scenario Python replay local.

  • 2026-10-25: document the pending dependency decisions and shared release prerequisite; add function documentation for the session bridge, adapter and regression tests, and cover discovery of the stale notice by the translation scanner.

  • 2026-10-25: initial Document Properties integration and real UI replay adapter.