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").
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").
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.
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$matchFor many pages at once, use compare_image_dirs() and
batch_report():
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().