odiffr 0.6.0
CRAN release: 2026-10-05
Breaking changes
- odiffr now requires odiff >= 4.1.1 (previously documented as >= 3.0.0). odiff 4.0.0 produced incomplete machine-readable output.
-
compare_image_dirs()now reports files missing fromcurrent_diras failing rows withreason = "missing"instead of silently dropping them (the warning is still emitted), so a disappearing screenshot now fails CI. -
compare_images_batch()(and thereforecompare_image_dirs()) no longer stops when a single pair fails, including a nonexistent path or a parallel worker crash; that pair is reported as areason = "error"row with the message in the newerrorcolumn. Empty input returns an emptyodiffr_batch, and malformed list input gives a clear error. -
diff_countanddiff_percentageare now0(rather thanNA) for matching images.NAnow means “unknown” (layout difference or error). - The
stdoutelement ofodiff_run()results now holds odiff’s machine-readable output (e.g."126;1.26") rather than the human-readable message, andstderris now populated. -
expect_images_differ()now fails, rather than passes, when the images cannot be compared. - The default
compare_image_dirs()pattern now matches.bmp(supported by odiff) and no longer matches.tif(rejected by odiff; use.tiff). -
threshold,diff_coloranddiff_overlayare validated up front, so invalid values (e.g.diff_color = "red", which odiff rejects) now error in R. Small thresholds are no longer passed in scientific notation.
New Features
-
install_odiff()downloads the odiff binary for your platform to the user cache, so odiff can be installed from R without Node.js or npm. When odiff is not found, functions that need it (e.g.compare_images()) now offer to runinstall_odiff()in interactive sessions, once per session; nothing is ever downloaded without asking, and the offer is never made in non-interactive sessions, testthat runs, while knitting or duringR CMD check. Setoptions(odiffr.ask_install = FALSE)to turn it off.odiff_available()remains a silent check. The startup message and the “odiff binary not found” error now recommendinstall_odiff(). -
use_odiffr_ci()writes a ready-to-use GitHub Actions workflow for visual tests: it installs odiff withinstall_odiff(), runs the testthat tests, adds asnapshot_report()summary of changed image snapshots to the job summary and uploads new snapshots and diff images when tests fail. -
find_odiff()now bypasses the Node.js launcher script installed bynpm install -g odiff-bin(odiff >= 4.4) and calls the native odiff binary directly, making each comparison around 5x faster. A path set withoptions(odiffr.path)is used as-is, andoptions(odiffr.resolve_npm = FALSE)disables the lookup.odiff_info()gains ashimfield. -
compare_file_odiff()andexpect_snapshot_image()now write a diff image when a snapshot comparison fails (outside_snaps/, intests/testthat/_odiffr/by default) and report its location. Both gain apresetargument, and the newodiff_preset()provides calibrated settings:"strict","default","screenshot"(ignores anti-aliasing noise) and"cross_platform".compare_file_odiff()works as thecomparefunction ofshinytest2::AppDriver$expect_screenshot(); seevignette("shinytest2", package = "odiffr"). -
snapshot_report()builds an HTML, Markdown or JUnit report of changed image snapshots (*.new.pngfiles under_snaps/), for reviewing snapshot failures in CI. -
compare_pdfs()compares two PDF files page by page, andcompare_pdf_dirs()compares directories of PDFs, returning batch results that work withsummary(),batch_report(),batch_markdown()andbatch_junit(). Requires the pdftools package. Seevignette("pdf-outputs", package = "odiffr"). -
audit_record()writes a JSON or CSV record of comparisons, including input and output file hashes, the odiff version and binary hash, parameters, timestamp and platform.odiff_run()results gain aparamselement with the effective comparison parameters. - New vignette on comparing web pages and htmlwidgets screenshots taken with webshot2.
-
expect_snapshot_image()is a testthat snapshot expectation that compares images with odiff, so baselines are managed withtestthat::snapshot_review()andtestthat::snapshot_accept().compare_file_odiff()returns the underlying compare function for use withtestthat::expect_snapshot_file(). -
compare_images(), the testthat expectations andexpect_snapshot_image()accept plots as inputs: ggplot objects, functions that draw a plot, and recorded plots. Plots are rendered to PNG (with ragg when installed); rendering is controlled with the newplot_options(). -
approve_changes()accepts current images as the new baselines for the directory/batch workflow, withdry_run,backup_dirand optional removal of baselines whose current image no longer exists. -
plot()method forodiff_resultobjects shows the baseline, current and diff images side by side;diff_image()returns the diff image as a magick image or raster. -
batch_report()andcompare_dirs_report()gainimages = "all"to show baseline, current and diff thumbnails side by side. -
batch_markdown()writes a Markdown summary of batch results (appending to the GitHub Actions job summary by default when run in GitHub Actions), andbatch_junit()writes JUnit XML for CI test reporting. -
odiff_run()gains anenable_asmparameter to enable AVX-512 optimised assembly for ~12% faster comparisons on supported x86_64 CPUs. Requires odiff >= 4.1.1. -
odiff_run()gains adiff_colsparameter (--output-diff-cols) that returns the column numbers containing differences. Requires odiff >= 4.5.0. -
odiff_run()results gain anerrorelement, andcompare_images(),compare_images_batch()andcompare_image_dirs()results gain anerrorcolumn (last), holding odiff’s error message whenreason == "error". Error messages are also shown byprint(), in testthat failure messages and inbatch_report().
Bug Fixes
- Image paths containing spaces (or other shell-special characters) now work. Previously every comparison involving such a path failed with
reason = "error". -
odiff_run(diff_lines = TRUE)now returns correctdiff_count,diff_percentageanddiff_lines. Previously the count and percentage wereNAand the line numbers included unrelated digits. - odiff is now always run with
--parsable-stdoutand its machine-readable output is parsed strictly. stdout and stderr are captured separately, so thestderrelement is now populated. -
_R_CHECK_LIMIT_CORES_=falseno longer limits parallel workers to 2. -
expect_images_match()uses deterministic diff file names, so re-runs overwrite the previous diff instead of accumulating files in_odiffr/, and a stale diff is removed once the expectation passes. - A
diff_outputpath without an extension now gets.pngappended (previously odiff failed to write the diff). -
timeoutvalues below one second are rounded up to one second instead of silently disabling the timeout;0orInfmeans no timeout. Timeouts are reported viaerror. -
odiff_version()is cached per binary, soenable_asm/diff_colsno longer spawnodiff --versionon every comparison. -
batch_report(): image links are properfile:///URIs (or percent-encoded relative URLs), fixing broken images on Windows and for paths containing spaces,#,?or%. Rows without pixel statistics show “-” instead ofNA%, empty batches produce a valid report, reports are written as UTF-8, the output directory is created if needed, and embedding images is much faster. -
summary()of an empty batch returnspass_rate = NAinstead ofNaN. -
odiffr_update()accepts versions with or without thevprefix, usesGITHUB_PAT/GITHUB_TOKENfor the GitHub API, never leaves a partial binary behind after a failed download, gives a clearer error for releases without binaries (e.g. v4.3.8, v4.4.0), and allows at least 300 seconds for the download.
odiffr 0.5.1
CRAN release: 2025-12-09
Bug Fixes
-
odiff_version()now correctly parses the version fromodiff --versionoutput instead of--help, which did not contain version information. -
batch_report()withrelative_paths = TRUEnow produces correct relative paths on Windows by normalizing path separators before computing relative paths.
Odiffr 0.5.0
New Features
-
batch_report()gains arelative_pathsparameter. WhenTRUE, image paths in HTML reports are relative to the report location, making reports portable without embedding images. -
compare_image_dirs()now emits a message when files incurrent_dirhave no corresponding baseline, helping catch missing or extra images early. - New accessor functions
failed_pairs()andpassed_pairs()make it easy to filter batch comparison results.
Odiffr 0.4.1
New Features
-
compare_dirs_report()convenience function combinescompare_image_dirs()andbatch_report()into a single call for the common QA workflow of comparing two directories and generating an HTML report.
Odiffr 0.4.0
HTML Diff Reports
-
batch_report(): Generate standalone HTML reports from batch comparison results. Reports include pass/fail statistics, failure reason breakdown, diff statistics, and thumbnails of worst offenders. - Configurable image embedding: Use
embed = TRUEfor self-contained reports with base64-encoded images, orembed = FALSE(default) to link to files. - Customizable: Set report title, number of worst offenders to display, and optionally include all comparisons (not just failures) with
show_all = TRUE.
Odiffr 0.3.0
Directory Comparison
-
compare_image_dirs(): Compare all images in two directories by matching relative paths. Baseline directory is source of truth; missing files in current directory trigger warnings and are excluded from results.
Batch Results Summary
-
summary()method for batch results: Get aggregate statistics including pass/fail counts, failure reason breakdown, diff statistics (min, median, mean, max), and worst offenders ranked by diff percentage. -
compare_images_batch()andcompare_image_dirs()now return objects with classodiffr_batchfor S3 method dispatch.
Parallel Batch Processing
- New
parallelparameter forcompare_images_batch()andcompare_image_dirs(): Setparallel = TRUEto compare images using multiple CPU cores. - Uses
parallel::mclapplyon Unix systems (macOS, Linux) for faster batch comparisons. - Automatically falls back to sequential processing on Windows.
Odiffr 0.2.0
testthat Integration
-
expect_images_match(): Assert two images are visually identical -
expect_images_differ(): Assert two images are visually different - Automatic diff image saving to
tests/testthat/_odiffr/on failure - Configurable via
options(odiffr.save_diff)andoptions(odiffr.diff_dir)
Odiffr 0.1.0
CRAN release: 2025-12-01
Initial release.
Features
-
compare_images(): High-level image comparison returning tibble/data.frame -
compare_images_batch(): Batch comparison of multiple image pairs -
odiff_run(): Low-level CLI wrapper with full option control -
ignore_region(): Helper for creating ignore region specifications
Binary Management
-
find_odiff(): Locate Odiff binary with priority-based search -
odiff_available(): Check if Odiff is available -
odiff_version(): Get Odiff version string -
odiff_info(): Display full configuration information -
odiffr_update(): Download Odiff binary to user cache (fallback option) -
odiffr_cache_path(): Get cache directory path -
odiffr_clear_cache(): Remove cached binaries
System Requirements
Requires Odiff (>= 3.0.0) to be installed. Install via:
- npm (cross-platform):
npm install -g odiff-bin - Manual: Download from https://github.com/dmtrKovalenko/odiff/releases
Alternatively, use odiffr_update() to download to user cache.
