% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/compare-screenshot-threshold.R
\name{compare_screenshot_threshold}
\alias{compare_screenshot_threshold}
\alias{screenshot_max_difference}
\title{Compare screenshots given threshold value}
\usage{
compare_screenshot_threshold(
  old,
  new,
  ...,
  threshold = getOption("shinytest2.compare_screenshot.threshold", NULL),
  kernel_size = getOption("shinytest2.compare_screenshot.kernel_size", 5),
  quiet = FALSE
)

screenshot_max_difference(
  old,
  new = missing_arg(),
  ...,
  kernel_size = getOption("shinytest2.compare_screenshot.kernel_size", 5)
)
}
\arguments{
\item{old}{Current screenshot file path}

\item{new}{New screenshot file path}

\item{...}{Must be empty. Allows for parameter expansion.}

\item{threshold}{The threshold for maximum allowed image difference (see
below for details). The default is \code{NULL} or can be set globally via the
\code{shinytest2.compare_screenshot.threshold} option.

If the value of \code{threshold} is \code{NULL}, \code{compare_screenshot_threshold()}
will act like \code{\link[testthat:expect_snapshot_file]{testthat::compare_file_binary}}. However, if \code{threshold} is
a positive number, it will be compared against the largest convolution
value found if the two images fail a \code{\link[testthat:expect_snapshot_file]{testthat::compare_file_binary}}
comparison. The max value that can be found is \code{4 * kernel_size ^ 2}.

Threshold values values below 5 help deter false-positive screenshot
comparisons (such as inconsistent rounded corners). Larger values in the
10s and 100s will help find \emph{real} changes. However, not all values are one
size fits all and you will need to play with a threshold that fits your
needs.

To find the current difference between two images, use
\code{screenshot_max_difference()}.}

\item{kernel_size}{The \code{kernel_size} represents the height and width of the
convolution kernel applied to the matrix of pixel differences. This
integer-like value should be relatively small, such as 5. The default value
can be set via the \code{shinytest2.compare_screenshot.kernel_size} option.}

\item{quiet}{If \code{FALSE} and the value is larger than \code{threshold}, then a
message is printed to the console. This is helpful when getting a failing
image and being informed about how different the \code{new} image is from the
\code{old} image.}
}
\description{
\pkg{chromote} can sometimes produce screenshot images with non-deterministic
(yet close) color values. This can happen in locations such as rounded
corners of \code{div}s or \code{textarea}s.
}
\details{
These differences make comparing screenshots impractical using traditional
expectation methods as false-positives are produced often over time. To
mitigate this, we can use a \emph{fuzzy matching} algorithm that can tolerate
small regional differences throughout the image. If the local changes found
are larger than the \code{threshold}, then the images are determined to be
different. Both the screenshot difference \code{threshold} and the size of the
kernel (\code{kernel_size}) can be set to tune the false positive rate.
}
\section{Functions}{
\itemize{
\item \code{compare_screenshot_threshold()}: Compares two images and allows for a \code{threshold} difference of \emph{so many}
units in each RGBA color channel.

It is suggested to use this method with
\code{\link{AppDriver}}\verb{$expect_screenshot(threshold=, kernel_size=)} to make
expectations on screenshots given particular \code{threshold} and \code{kernel_size}
values.

\item \code{screenshot_max_difference()}: Finds the difference between two screenshots.

This value can be used in \code{compare_screenshot_threshold(threshold=)}. It is
recommended that the value used for \code{compare_screenshot_threshold(threshold=)}
is larger than the immediate max difference found. This allows for random
fluctuations when rounding sub pixels.

If \code{new} is missing, it will use the file value of \code{old} (\code{FILE.png}) and
default to \code{FILE.new.png}

}}
\section{Algorithm for the difference between two screenshots}{

\enumerate{
\item First the two images are compared using
\code{\link[testthat:expect_snapshot_file]{testthat::compare_file_binary()}}. If the files are identical, return
\code{TRUE} that the screenshot images are the same.
\item If \code{threshold} is \code{NULL}, return \code{FALSE} as the convolution will not
occur.
\item Prepare the screenshot difference matrix by reading the RGBA channels of
each image and find their respective absolute differences
\item Sum the screenshot difference matrix channels at each pixel location
\item Perform a convolution using a small square kernel matrix that is
\code{kernel_size} big and filled with \code{1}s.
\item Find the largest value in the resulting convolution matrix.
\item If this max convolution value is larger than \code{threshold}, return \code{FALSE},
images are different.
\item Otherwise, return \code{TRUE}, images are the same.
}
}

\examples{
\dontshow{if (requireNamespace("showimage", quietly = TRUE)) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf}
img_folder <- system.file("example/imgs/", package = "shinytest2")
slider_old <- fs::path(img_folder, "slider-old.png")
slider_new <- fs::path(img_folder, "slider-new.png")

# Can you see the differences between these two images?
showimage::show_image(slider_old)
showimage::show_image(slider_new)

# You might have caught the difference between the two images!
slider_diff <- fs::path(img_folder, "slider-diff.png")
showimage::show_image(slider_diff)

# Let's find the difference between the two images
screenshot_max_difference(slider_old, slider_new)
# ~ 28

# Using different threshold values...
compare_screenshot_threshold(slider_old, slider_new, threshold = NULL)
#> FALSE # Images are not identical
compare_screenshot_threshold(slider_old, slider_new, threshold = 25)
#> FALSE # Images are more different than 25 units
compare_screenshot_threshold(slider_old, slider_new, threshold = 30)
#> TRUE # Images are not as different as 30 units

#########################

# Now let's look at two fairly similar images
bookmark_old <- fs::path(img_folder, "bookmark-old.png")
bookmark_new <- fs::path(img_folder, "bookmark-new.png")

# Can you see the difference between these two images?
# (Hint: Focused corners)
showimage::show_image(bookmark_old)
showimage::show_image(bookmark_new)

# Can you find the red pixels showing the differences?
# Hint: Look in the corners of the focused text
bookmark_diff <- fs::path(img_folder, "bookmark-diff.png")
showimage::show_image(bookmark_diff)

# Let's find the difference between the two images
screenshot_max_difference(bookmark_old, bookmark_new)
# ~ 0.25

# Using different threshold values...
compare_screenshot_threshold(bookmark_old, bookmark_new, threshold = NULL)
#> FALSE # Images are not identical
compare_screenshot_threshold(bookmark_old, bookmark_new, threshold = 5)
#> TRUE # Images are not as different than 5 units
\dontshow{\}) # examplesIf}
}
