Skip to content

Commit

Permalink
Merge branch 'main' into pkg_support
Browse files Browse the repository at this point in the history
  • Loading branch information
schloerke authored Feb 10, 2025
2 parents 15bf131 + 6ce71fd commit 8c6aaa5
Show file tree
Hide file tree
Showing 56 changed files with 496 additions and 326 deletions.
1 change: 1 addition & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ _\.new\.png$
^tests/testthat/migrate-apps$
^tests/testthat/apps$
^CRAN-SUBMISSION$
^_dev$
4 changes: 2 additions & 2 deletions .github/workflows/test-actions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ jobs:

# ## Suggested usage
# - name: Test app
# uses: rstudio/shinytest2/actions/test-app@v1
# uses: rstudio/shinytest2/actions/test-app@actions/v1
# with:
# app-dir: |
# tests/testthat/apps/hello

- name: Test app (main)
uses: rstudio/shinytest2/actions/test-app@v1
uses: rstudio/shinytest2/actions/test-app@actions/v1
with:
app-dir: "tests/testthat/apps/window"

Expand Down
22 changes: 11 additions & 11 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
Package: shinytest2
Title: Testing for Shiny Applications
Version: 0.2.1.9001
Version: 0.3.2.9001
Authors@R:
c(
person("Barret", "Schloerke", role = c("cre", "aut"), email = "barret@rstudio.com", comment = c(ORCID = "0000-0001-9986-114X")),
person(family = "RStudio", role = c("cph", "fnd")),
person("Winston", "Chang", role ="ctb", email = "winston@rstudio.com", comment = "Original author to rstudio/shinytest"),
person("Gábor", "Csárdi", role = "ctb", email = "gabor@rstudio.com", comment = "Original author to rstudio/shinytest"),
person("Hadley", "Wickham", role = "ctb", email = "hadley@rstudio.com", comment = "Original author to rstudio/shinytest"),
person("Barret", "Schloerke", role = c("cre", "aut"), email = "barret@posit.co", comment = c(ORCID = "0000-0001-9986-114X")),
person(family = "Posit Software, PBC", role = c("cph", "fnd")),
person("Winston", "Chang", role ="ctb", email = "winston@posit.co", comment = "Original author to rstudio/shinytest"),
person("Gábor", "Csárdi", role = "ctb", email = "gabor@posit.co", comment = "Original author to rstudio/shinytest"),
person("Hadley", "Wickham", role = "ctb", email = "hadley@posit.co", comment = "Original author to rstudio/shinytest"),
person(family = "Mango Solutions", role = c("cph", "ccp"), comment = "Original author to rstudio/shinytest")
)
Description: Automated unit testing of Shiny applications through a headless 'Chromium' browser.
License: MIT + file LICENSE
Encoding: UTF-8
Language: en-US
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.2.3
RoxygenNote: 7.3.2
URL: https://rstudio.github.io/shinytest2/, https://github.com/rstudio/shinytest2
BugReports: https://github.com/rstudio/shinytest2/issues
VignetteBuilder: knitr
Expand All @@ -25,16 +25,15 @@ Imports:
R6 (>= 2.4.0),
callr,
checkmate (>= 2.0.0),
chromote (>= 0.1.0),
chromote (>= 0.1.2),
crayon,
ellipsis,
fs,
globals (>= 0.14.0),
httr,
jsonlite,
lifecycle (>= 1.0.3),
pingr,
rlang (>= 0.3.0),
rlang (>= 1.0.0),
rmarkdown,
shiny,
withr
Expand All @@ -54,7 +53,8 @@ Suggests:
vdiffr (>= 1.0.0),
spelling
Config/Needs/check:
rstudio/shiny
rstudio/shiny,
bslib
Config/Needs/website:
pkgdown,
tidyverse/tidytemplate
Expand Down
26 changes: 26 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,31 @@
# shinytest2 (development version)

## Bug / Improvements

* Add support for `$click()`ing `{bslib}`'s `input_task_button()` (#829).

* Improved the error message when an app takes too long to start up (@LouisLeNezet, #394).

# shinytest2 0.3.2

## Bug / Improvements

* `{shinytest2}` now uses `{rlang}` and longer depends on `{ellipsis}` (@olivroy, #382).

* `{shinytest2}` now warns rather than erroring when a potentially non-existent global variable is found in the server function, such as when column names are passed to `dplyr::select()` (thanks @matt-sd-watson @MichalLauer, #385).

# shinytest2 0.3.1

## Breaking changes

* `AppDriver$get_screenshot()`/`AppDriver$expect_screenshot()` now default an underlying `deviceScaleFactor` option to 0 instead of 1. This ensures that image sizes are more consistent across devices. To revert to prior behavior, provide `screenshot_args = list(scale = 1)` to `get_screenshot()`/`expect_screenshot()` (#350).

## Bug / Improvements

* shinytest2 no longer checks if the computer running the tests is connected to the internet when determining if shinytest2 can connect to the server hosting the Shiny app being tested. (@Riraro #364)

# shinytest2 0.3.0

## Breaking changes

* `AppDriver$get_screenshot(selector=)`, `AppDriver$expect_screenshot(selector=)`'s default `selector` value changed from the HTML DOM selector `"html"` to `"scrollable_area"`. `"scrollable_area"` is a custom `{shinytest2}` selector that will take a screenshot of the entire scrollable area. While a breaking change, this new default value is more intuitive and robust to non-standard CSS height and width values that fail with `"html"`. (#325)
Expand Down
4 changes: 2 additions & 2 deletions R/app-driver-expect-download.R
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ app_expect_download <- function(
cran = FALSE
) {
ckm8_assert_app_driver(self, private)
ellipsis::check_dots_empty()
rlang::check_dots_empty()

snapshot_info <- app_download(
self, private,
Expand Down Expand Up @@ -127,7 +127,7 @@ app_get_download <- function(
filename = NULL
) {
ckm8_assert_app_driver(self, private)
# ellipsis::check_dots_empty()
# rlang::check_dots_empty()

if (is.null(filename)) {
# Save to a temporary file with possibly suggested name
Expand Down
14 changes: 7 additions & 7 deletions R/app-driver-expect-js.R
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ app_get_js <- function(
timeout = missing_arg()
) {
ckm8_assert_app_driver(self, private)
ellipsis::check_dots_empty()
rlang::check_dots_empty()
timeout <- app_get_timeout(self, private, timeout = timeout)

"!DEBUG app_get_js()"
Expand All @@ -38,7 +38,7 @@ app_run_js <- function(
timeout = missing_arg()
) {
ckm8_assert_app_driver(self, private)
ellipsis::check_dots_empty()
rlang::check_dots_empty()
timeout <- app_get_timeout(self, private, timeout = timeout)

"!DEBUG app_run_js()"
Expand All @@ -65,7 +65,7 @@ app_expect_js <- function(
cran = FALSE
) {
ckm8_assert_app_driver(self, private)
ellipsis::check_dots_empty()
rlang::check_dots_empty()
timeout <- app_get_timeout(self, private, timeout = timeout)

result <- self$get_js(
Expand Down Expand Up @@ -99,7 +99,7 @@ app_get_text <- function(
selector
) {
ckm8_assert_app_driver(self, private)
# ellipsis::check_dots_empty()
# rlang::check_dots_empty()

ret <- self$get_js(
script = get_text_js(selector)
Expand All @@ -113,7 +113,7 @@ app_expect_text <- function(
cran = FALSE
) {
ckm8_assert_app_driver(self, private)
ellipsis::check_dots_empty()
rlang::check_dots_empty()

self$expect_js(
script = get_text_js(selector),
Expand All @@ -138,7 +138,7 @@ app_get_html <- function(
outer_html = TRUE
) {
ckm8_assert_app_driver(self, private)
ellipsis::check_dots_empty()
rlang::check_dots_empty()

ret <- self$get_js(
script = get_html_js(selector, isTRUE(outer_html))
Expand All @@ -153,7 +153,7 @@ app_expect_html <- function(
cran = FALSE
) {
ckm8_assert_app_driver(self, private)
ellipsis::check_dots_empty()
rlang::check_dots_empty()

self$expect_js(
script = get_html_js(selector, isTRUE(outer_html)),
Expand Down
4 changes: 2 additions & 2 deletions R/app-driver-expect-screenshot.R
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ app_get_screenshot <- function(
) {
"!DEBUG app_get_screenshot()"
ckm8_assert_app_driver(self, private)
ellipsis::check_dots_empty()
rlang::check_dots_empty()

screenshot_args <- default_screenshot_args(
maybe_missing_value(screenshot_args, private$default_screenshot_args)
Expand Down Expand Up @@ -76,7 +76,7 @@ app_expect_screenshot <- function(
) {
"!DEBUG app_expect_screenshot()"
ckm8_assert_app_driver(self, private)
ellipsis::check_dots_empty()
rlang::check_dots_empty()

compare <- rlang::maybe_missing(
compare,
Expand Down
6 changes: 3 additions & 3 deletions R/app-driver-expect-values.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ app_get_single_ioe <- function(
export = missing_arg()
) {
ckm8_assert_app_driver(self, private)
ellipsis::check_dots_empty()
rlang::check_dots_empty()

# input <- rlang::maybe_missing(input, FALSE)
# output <- rlang::maybe_missing(output, FALSE)
Expand Down Expand Up @@ -79,7 +79,7 @@ app_get_values <- function(
hash_images = FALSE
) {
ckm8_assert_app_driver(self, private)
ellipsis::check_dots_empty()
rlang::check_dots_empty()
hash_images <- isTRUE(hash_images)

self$log_message("Getting all values")
Expand Down Expand Up @@ -154,7 +154,7 @@ app_expect_values <- function(
cran = FALSE
) {
ckm8_assert_app_driver(self, private)
ellipsis::check_dots_empty()
rlang::check_dots_empty()

self$log_message("Expecting values")
"!DEBUG app_expect_values()"
Expand Down
2 changes: 1 addition & 1 deletion R/app-driver-initialize.R
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ app_initialize_ <- function(
options = list()
) {
ckm8_assert_app_driver(self, private)
ellipsis::check_dots_empty()
rlang::check_dots_empty()

# This will kill any existing Shiny processes launched by shinytest,
# in case they're using some of the same resources.
Expand Down
4 changes: 2 additions & 2 deletions R/app-driver-node.R
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ app_find_node_id <- function(
selector = missing_arg()
) {
ckm8_assert_app_driver(self, private)
ellipsis::check_dots_empty()
rlang::check_dots_empty()

"!DEBUG finding a nodeID"

Expand Down Expand Up @@ -89,7 +89,7 @@ app_click <- function(
self$set_inputs(!!input := "click", ...)

} else {
ellipsis::check_dots_empty()
rlang::check_dots_empty()
self$log_message(paste0(
"Clicking HTML element with selector: ",
node_id_css_selector(
Expand Down
11 changes: 9 additions & 2 deletions R/app-driver-start.R
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,15 @@ app_start_shiny <- function(
Sys.sleep(0.2)

if (i == max_i) {
app_abort(self, private, paste0(
"Cannot find shiny port number. Error lines found:\n",
app_abort(self, private, sprintf(
paste(
"The Shiny app failed to start up within %s second%s.",
"To increase the loading timeout, consult the documentation in `?AppDriver`",
"for the `load_timeout` argument of `AppDriver$new()`.",
"The app printed the following lines to stderr during start up:\n%s"
),
load_timeout / 1000,
if (load_timeout == 1000) "" else "s",
paste(err_lines, collapse = "\n")
))
}
Expand Down
4 changes: 2 additions & 2 deletions R/app-driver-timeout.R
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
app_get_timeout <- function(self, private, ..., timeout = missing_arg(), timeout_name = checkmate::vname(timeout)) {
ckm8_assert_app_driver(self, private)
ellipsis::check_dots_empty()
rlang::check_dots_empty()

timeout <- rlang::maybe_missing(timeout, private$timeout)
ckm8_assert_single_number(timeout, lower = 0, finite = TRUE, .var.name = timeout_name)
Expand Down Expand Up @@ -115,7 +115,7 @@ app_init_timeouts <- function(
timeout = missing_arg()
) {
ckm8_assert_app_driver(self, private)
ellipsis::check_dots_empty()
rlang::check_dots_empty()

private$load_timeout <- resolve_load_timeout(load_timeout)

Expand Down
6 changes: 3 additions & 3 deletions R/app-driver-upload-file.R
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ app_upload_file <- function(
"shinytest2.outputValuesWaiter.start(", toJSON_atomic(timeout_), ", 2);"
))


filename <- inputs[[1]]
self$log_message(paste0("Uploading file for id: ", filename))
self$log_message(paste0("Uploading file(s) for id: ",
paste(filename, collapse = ", ")))

node_id <- app_find_node_id(self, private, input = names(inputs)[1])

Expand All @@ -42,7 +42,7 @@ app_upload_file <- function(
)

self$get_chromote_session()$DOM$setFileInputFiles(
files = list(fs::path_real(filename)),
files = as.list(fs::path_real(filename)),
nodeId = node_id
)

Expand Down
2 changes: 1 addition & 1 deletion R/app-driver-wait.R
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ app_wait_for_value <- function(
) {
"!DEBUG app_wait_for_value()"
ckm8_assert_app_driver(self, private)
ellipsis::check_dots_empty()
rlang::check_dots_empty()
timeout <- app_get_timeout(self, private, timeout = timeout)

checkmate::assert_number(interval, lower = 0, finite = FALSE, na.ok = FALSE)
Expand Down
2 changes: 1 addition & 1 deletion R/app-driver.R
Original file line number Diff line number Diff line change
Expand Up @@ -1064,7 +1064,7 @@ AppDriver <- R6Class( # nolint
#' images byte-by-byte.
#' @param threshold Parameter supplied to [`compare_screenshot_threshold()`]
#' when using the default `compare` method. If the value of `threshold` is
#' NULL`, [`compare_screenshot_threshold()`] will act like
#' `NULL`, [`compare_screenshot_threshold()`] will act like
#' [`testthat::compare_file_binary`]. However, if `threshold` is a positive number,
#' it will be compared against the largest convolution value found if the
#' two images fail a [`testthat::compare_file_binary`] comparison.
Expand Down
10 changes: 5 additions & 5 deletions R/chromote-methods.R
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ chromote_wait_for_condition <- function(
timeout = 15 * 1000,
interval = 100
) {
ellipsis::check_dots_empty()
rlang::check_dots_empty()
condition_js <- as.character(condition_js) # {glue} support
checkmate::assert_character(condition_js, any.missing = FALSE, len = 1)
checkmate::assert_number(timeout, lower = 0)
Expand Down Expand Up @@ -200,15 +200,15 @@ chromote_wait_for_condition <- function(



chromote_set_device_metrics <- function(chromote_session, ..., width = NULL, height = NULL, device_scale_factor = 1, mobile = FALSE) {
chromote_set_device_metrics <- function(chromote_session, ..., width = NULL, height = NULL) {
assert_chromote_session(chromote_session)
ellipsis::check_dots_empty()
rlang::check_dots_empty()

chromote_session$Emulation$setDeviceMetricsOverride(
width = width,
height = height,
deviceScaleFactor = device_scale_factor,
mobile = mobile
deviceScaleFactor = 0,
mobile = FALSE
)
}

Expand Down
2 changes: 1 addition & 1 deletion R/compare-screenshot-threshold.R
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ compare_screenshot_threshold <- function(
kernel_size = 5,
quiet = FALSE
) {
ellipsis::check_dots_empty()
rlang::check_dots_empty()

is_same_file <- testthat::compare_file_binary(old, new)
# Quit early if they are the same file
Expand Down
2 changes: 1 addition & 1 deletion R/httr.R
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ app_httr_get <- function(self, private, url, fn_404 = NULL) {
pieces$port <- switch(pieces$scheme, "http" = 80, "https" = 443)
}

if (!pingr::is_up(pieces$hostname, pieces$port)) {
if (!pingr::is_up(pieces$hostname, pieces$port, check_online = FALSE)) {
app_abort(self, private, "Could not find Shiny server. Shiny app is no longer running")
}

Expand Down
2 changes: 1 addition & 1 deletion R/migrate.R
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ migrate_from_shinytest <- function(
include_expect_screenshot = missing_arg(),
quiet = FALSE
) {
ellipsis::check_dots_empty()
rlang::check_dots_empty()
rlang::check_installed("shinytest", version = "1.5.1")

# Use an environment to avoid having to return many function levels to merge info and then send back many function levels
Expand Down
Loading

0 comments on commit 8c6aaa5

Please sign in to comment.