Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ Imports:
rlang (>= 1.0.0),
rmarkdown,
shiny,
withr
withr,
lifecycle
Suggests:
deSolve,
diffobj,
Expand Down
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ importFrom(cli,col_magenta)
importFrom(cli,col_red)
importFrom(cli,col_silver)
importFrom(cli,make_ansi_style)
importFrom(lifecycle,deprecated)
importFrom(rlang,"%||%")
importFrom(rlang,":=")
importFrom(rlang,list2)
Expand Down
6 changes: 5 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# shinytest2 (development version)

## Breaking changes

* `{shinytest2}` will skip and test on CRAN where an `AppDriver` is initialized. From a request from CRAN, using [`{chromote}` during CRAN package testing](https://rstudio.github.io/chromote/articles/example-cran-tests.html) should be avoided as it can create failing tests over time due to application changes within the testing machine, not changes in package code. Since `AppDriver` directly depends on `{chromote}` to test Shiny applications, creating an `AppDriver` should always skip the current test during CRAN package testing. This decision was made to achieve consistent testing behavior over time (rather than silently skipping tests that are expected to run due to a Chrome update). To escape this behavior, you can set the system environment variable `SHINYTEST2_APP_DRIVER_TEST_ON_CRAN=1`. Following `{chromote}`'s recommendation, you should test your R package [in a CI environment, ideally on a weekly or monthly schedule](https://rstudio.github.io/chromote/articles/example-cran-tests.html) to test your Shiny app with the latest R package versions. (#407)

## Bug / Improvements

* Add support for `$click()`ing `{bslib}`'s `input_task_button()` (#389).
Expand All @@ -8,7 +12,7 @@

* The `threshold` and `kernel_size` default values of the `AppDriver$expect_screenshot()` method are now configurable via two new global options: `shinytest2.compare_screenshot.threshold` and `shinytest2.compare_screenshot.kernel_size` (#401)

* `{shinytest2}` now imports `{cli}` and no longer imports `{crayon}` (@olivroy, #399).
* `{shinytest2}` now imports `{cli}` and no longer imports `{crayon}` (@olivroy, #399).

# shinytest2 0.3.2

Expand Down
37 changes: 23 additions & 14 deletions R/app-driver-expect-download.R
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

app_download <- function(
self, private,
self,
private,
output,
name = NULL,
save_dir = tempdir(),
Expand All @@ -25,11 +25,18 @@ app_download <- function(
# Find suggested name
content_dispo <- httr::headers(req)[["content-disposition"]]
filename_header <- NULL
if (length(content_dispo) == 1 && is.character(content_dispo) && nzchar(content_dispo)) {
if (
length(content_dispo) == 1 &&
is.character(content_dispo) &&
nzchar(content_dispo)
) {
vals <- strsplit(content_dispo, "filename=")[[1]]
if (length(vals) > 1) {
filename_header <- gsub("\"", "", vals[2], fixed = TRUE)
self$log_message(paste0("Content disposition file name: ", filename_header))
self$log_message(paste0(
"Content disposition file name: ",
filename_header
))
}
}

Expand Down Expand Up @@ -83,14 +90,14 @@ app_expect_download <- function(
output,
...,
compare = NULL,
name = NULL,
cran = FALSE
name = NULL
) {
ckm8_assert_app_driver(self, private)
rlang::check_dots_empty()

snapshot_info <- app_download(
self, private,
self,
private,
output = output,
name = name,
# Save within temp app dir
Expand All @@ -101,19 +108,19 @@ app_expect_download <- function(

# Compare download_file content
app__expect_snapshot_file(
self, private,
self,
private,
snapshot_info$download_path,
cran = cran,
compare = compare
)

# Compare requested filename
requested_download_name <- snapshot_info$filename_header
if (!is.null(requested_download_name)) {
app__expect_snapshot_value(
self, private,
requested_download_name,
cran = cran
self,
private,
requested_download_name
)
}

Expand All @@ -122,7 +129,8 @@ app_expect_download <- function(


app_get_download <- function(
self, private,
self,
private,
output,
filename = NULL
) {
Expand All @@ -140,7 +148,8 @@ app_get_download <- function(
}

snapshot_info <- app_download(
self, private,
self,
private,
output = output,
name = name,
save_dir = save_dir,
Expand Down
65 changes: 40 additions & 25 deletions R/app-driver-expect-js.R
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
app_js_script_helper <- function(self, private, script = missing_arg(), file = missing_arg()) {
app_js_script_helper <- function(
self,
private,
script = missing_arg(),
file = missing_arg()
) {
ckm8_assert_app_driver(self, private)
if (rlang::is_missing(file)) return(script)

if (!rlang::is_missing(script)) {
app_warn(self, private,
app_warn(
self,
private,
"Both `file` and `script` are specified. `script` will be ignored."
)
}
read_utf8(file)
}

app_get_js <- function(
self, private,
self,
private,
script,
...,
file = missing_arg(),
Expand All @@ -31,7 +39,8 @@ app_get_js <- function(
)$result$value
}
app_run_js <- function(
self, private,
self,
private,
script,
...,
file = missing_arg(),
Expand All @@ -56,13 +65,13 @@ app_run_js <- function(


app_expect_js <- function(
self, private,
self,
private,
script,
...,
file = missing_arg(),
timeout = missing_arg(),
pre_snapshot = NULL,
cran = FALSE
pre_snapshot = NULL
) {
ckm8_assert_app_driver(self, private)
rlang::check_dots_empty()
Expand All @@ -82,20 +91,23 @@ app_expect_js <- function(
# Must use _value_ output as _print_ output is unstable
# over different R versions and locales
app__expect_snapshot_value(
self, private,
result,
cran = cran
self,
private,
result
)
}


get_text_js <- function(selector) {
paste0(
"Array.from(document.querySelectorAll(", toJSON_atomic(selector), ")).map((item, i) => item.textContent);"
"Array.from(document.querySelectorAll(",
toJSON_atomic(selector),
")).map((item, i) => item.textContent);"
)
}
app_get_text <- function(
self, private,
self,
private,
selector
) {
ckm8_assert_app_driver(self, private)
Expand All @@ -107,18 +119,17 @@ app_get_text <- function(
unlist(ret)
}
app_expect_text <- function(
self, private,
self,
private,
selector,
...,
cran = FALSE
...
) {
ckm8_assert_app_driver(self, private)
rlang::check_dots_empty()

self$expect_js(
script = get_text_js(selector),
pre_snapshot = unlist,
cran = cran
pre_snapshot = unlist
)

invisible(self)
Expand All @@ -127,12 +138,17 @@ app_expect_text <- function(

get_html_js <- function(selector, outer_html) {
paste0(
"let map_fn = ", toJSON_atomic(outer_html), " ? (item, i) => item.outerHTML : (item, i) => item.innerHTML;\n",
"Array.from(document.querySelectorAll(", toJSON_atomic(selector), ")).map(map_fn);"
"let map_fn = ",
toJSON_atomic(outer_html),
" ? (item, i) => item.outerHTML : (item, i) => item.innerHTML;\n",
"Array.from(document.querySelectorAll(",
toJSON_atomic(selector),
")).map(map_fn);"
)
}
app_get_html <- function(
self, private,
self,
private,
selector,
...,
outer_html = TRUE
Expand All @@ -146,19 +162,18 @@ app_get_html <- function(
unlist(ret)
}
app_expect_html <- function(
self, private,
self,
private,
selector,
...,
outer_html = TRUE,
cran = FALSE
outer_html = TRUE
) {
ckm8_assert_app_driver(self, private)
rlang::check_dots_empty()

self$expect_js(
script = get_html_js(selector, isTRUE(outer_html)),
pre_snapshot = unlist,
cran = cran
pre_snapshot = unlist
)

invisible(self)
Expand Down
Loading
Loading