The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Comparing web pages and htmlwidgets

odiffr compares images; it does not open web pages or drive a browser. To test how a web page, an R Markdown/Quarto report or an htmlwidget looks, take a screenshot with a headless browser first, for example with webshot2 or chromote (both use Chrome or Chromium), and then compare the PNG files with odiff. For Shiny apps, see vignette("shinytest2").

Screenshot a page

webshot2::webshot(
  "https://example.com",
  file = "current/home.png",
  vwidth = 1280, vheight = 800,
  delay = 0.5           # let the page settle
)

Local HTML files work too, e.g. a rendered report: webshot2::webshot("report.html", "current/report.png").

Screenshot an htmlwidget

Save the widget as an HTML file, then take a screenshot of it:

widget <- DT::datatable(head(iris))  # any htmlwidget

html <- tempfile(fileext = ".html")
htmlwidgets::saveWidget(widget, html, selfcontained = TRUE)
webshot2::webshot(html, file = "current/table.png",
                  vwidth = 800, vheight = 600, delay = 1)

Keep everything deterministic that you can: a fixed viewport size, a fixed zoom level, a fixed seed for random data, and no animations (many widgets have an option to disable them). Map tiles and other content loaded from the internet can change at any time; avoid them in tests or hide them with ignore_regions.

Compare with a baseline

Browser screenshots contain anti-aliasing noise around rounded corners, borders and text. The "screenshot" preset ignores anti-aliased pixels while keeping the colour threshold low (see ?odiff_preset):

library(odiffr)

result <- do.call(compare_images, c(
  list("baseline/home.png", "current/home.png", diff_output = "home-diff.png"),
  odiff_preset("screenshot")
))
result$match

For many pages at once, use compare_image_dirs() and batch_report():

results <- do.call(compare_image_dirs, c(
  list("baseline/", "current/", diff_dir = "diffs/"),
  odiff_preset("screenshot")
))
batch_report(results, output_file = "report.html", images = "all",
             embed = TRUE)

As a testthat snapshot

expect_snapshot_image() stores the screenshot as a testthat snapshot and compares it with odiff on later runs. On failure a diff image is written to tests/testthat/_odiffr/.

test_that("report looks the same", {
  skip_if_not_installed("webshot2")
  path <- tempfile(fileext = ".png")
  webshot2::webshot("report.html", file = path,
                    vwidth = 1024, vheight = 768)

  expect_snapshot_image(
    path,
    name = "report",
    preset = "screenshot",
    variant = Sys.info()[["sysname"]]  # fonts differ between systems
  )
})

Review changes with testthat::snapshot_review(), and on CI write a report of all changed snapshots with snapshot_report().

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.