Skip to content

Commit

Permalink
v0.1.0 (#185)
Browse files Browse the repository at this point in the history
* update urls

* Update link to code to avoid checker changing it

* Adjust shiny to be a `Config/Needs/check` so that we can release without a Remote

* Use version `0.1.0`

* Remove header warning

* init cran comments and revdep check

* turn uti-8 i into `i` to avoid LaTeX errors

* Ignore more files to reduce the install size. These files are not checked on CRAN, only CI

* spelling

* Update cran-comments.md

* Use empty app as nothing is needed for printing to occur... just that it prints cleanly

* Fix tests under CRAN testing

* Fix test to not rely on hello app

* Use Installation section like `testthat`. Do not link to packages and let tidytemplate do that

* CRAN has trouble running tests that use chromote. Skip them on CRAN

* Try to make LaTeX happier

* Update docs so LaTeX shows no warnings

* spelling
  • Loading branch information
schloerke authored Apr 27, 2022
1 parent 0a66843 commit 9f92e77
Show file tree
Hide file tree
Showing 25 changed files with 252 additions and 172 deletions.
5 changes: 5 additions & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,8 @@ _\.new\.png$
^actions$
^doc$
^Meta$
^cran-comments\.md$
^revdep$

^tests/testthat/migrate-apps$
^tests/testthat/apps$
8 changes: 3 additions & 5 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: shinytest2
Title: Testing for Shiny Applications
Version: 0.0.0.9002
Version: 0.1.0
Authors@R:
c(
person("Barret", "Schloerke", role = c("cre", "aut"), email = "[email protected]", comment = c(ORCID = "0000-0001-9986-114X")),
Expand All @@ -13,6 +13,7 @@ Authors@R:
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.1.2
URL: https://github.com/rstudio/shinytest2
Expand Down Expand Up @@ -48,11 +49,8 @@ Suggests:
showimage,
knitr,
usethis
Remotes:
Config/Needs/check:
rstudio/shiny
Config/Needs/other:
shiny (>= 1.7.1.9003),
shinyvalidate (>= 1.0.0.9001),
Config/Needs/website:
pkgdown,
tidyverse/tidytemplate
Expand Down
4 changes: 2 additions & 2 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# shinytest2 0.0.0.9000
# shinytest2 0.1.0

* Added a `NEWS.md` file to track changes to the package.
* Initial release of package
86 changes: 44 additions & 42 deletions R/app-driver.R
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ AppDriver <- R6Class( # nolint
#' Shiny app is idle for 200ms.
#' @param screenshot_args Default set of arguments to pass in to
#' [`chromote::ChromoteSession`]'s `$get_screenshot()` method when taking
#' screnshots within `$expect_screenshot()`. To disable screenshots by
#' screenshots within `$expect_screenshot()`. To disable screenshots by
#' default, set to `FALSE`.
#' @param expect_values_screenshot_args The value for `screenshot_args` when
#' producing a debug screenshot for `$expect_values()`. To disable debug
Expand Down Expand Up @@ -343,7 +343,7 @@ AppDriver <- R6Class( # nolint
#' @description Set input values
#'
#' Set Shiny inputs by sending the value to the Chrome browser and
#' programaticly updating the values. Given `wait_ = TRUE`, the method will
#' programmatically updating the values. Given `wait_ = TRUE`, the method will
#' not return until an output value has been updated.
#'
#' @param ... Name-value pairs, `component_name_1 = value_1, component_name_2 = value_2` etc.
Expand Down Expand Up @@ -841,7 +841,7 @@ AppDriver <- R6Class( # nolint
#' Arguments will have to be inserted into the script as there is not access
#' to `arguments`. This can be done with commands like `paste()`. If using
#' `glue::glue()`, be sure to use uncommon `.open` and `.close` values to
#' avoid having to doulbe all `{` and `}`.
#' avoid having to double all `{` and `}`.
#' @param script JavaScript to execute. If a JavaScript Promise is returned,
#' the R session will block until the promise has been resolved and return
#' the value.
Expand Down Expand Up @@ -1243,15 +1243,15 @@ AppDriver <- R6Class( # nolint
#' app <- AppDriver$new(shiny_app, check_names = TRUE)
#' #> Warning:
#' #> ! Shiny inputs should have unique HTML id values.
#' #> The following HTML id values are not unique:
#' #> i The following HTML id values are not unique:
#' #> • text
#'
#' # Manually assert that all names are unique
#' app <- AppDriver$new(shiny_app, check_names = FALSE)
#' app$expect_unique_names()
#' #> Error: `app_check_unique_names(self, private)` threw an unexpected warning.
#' #> Message: ! Shiny inputs should have unique HTML id values.
#' #> The following HTML id values are not unique:
#' #> i The following HTML id values are not unique:
#' #> • text
#' #> Class: rlang_warning/warning/condition
#' }
Expand Down Expand Up @@ -1449,7 +1449,8 @@ AppDriver <- R6Class( # nolint
#' system.file("examples/01_hello", package = "shiny"),
#' options = list(shiny.trace = TRUE)
#' )
#' app$get_logs() # (long output lines have been truncated)
#' app$get_logs()
#' ## (All WebSocket messages have been replaced with `WEBSOCKET_MSG` in example below)
#' # \{shinytest2\} R info 11:09:57.43 Start AppDriver initialization
#' # \{shinytest2\} R info 11:09:57.43 Starting Shiny app
#' # \{shinytest2\} R info 11:09:58.27 Creating new chromote session
Expand All @@ -1460,34 +1461,34 @@ AppDriver <- R6Class( # nolint
#' # \{shinytest2\} R info 11:09:58.54 Waiting until Shiny app starts
#' # \{chromote\} JS info 11:09:58.61 shinytest2; jQuery found
#' # \{chromote\} JS info 11:09:58.61 shinytest2; Waiting for shiny session to connect
#' # \{chromote\} JS websocket 11:09:58.73 send \{"method":"init","data":\{"bins":30,|truncated
#' # \{chromote\} JS websocket 11:09:58.78 recv \{"config":\{"workerId":"","sessionId":|truncated
#' # \{chromote\} JS websocket 11:09:58.73 send WEBSOCKET_MSG
#' # \{chromote\} JS websocket 11:09:58.78 recv WEBSOCKET_MSG
#' # \{chromote\} JS info 11:09:58.78 shinytest2; Connected
#' # \{chromote\} JS info 11:09:58.78 shinytest2; Ready
#' # \{chromote\} JS websocket 11:09:58.85 recv \{"custom":\{"showcase-src":\{"srcref":|truncated
#' # \{chromote\} JS websocket 11:09:58.85 recv \{"busy":"busy"\}
#' # \{chromote\} JS websocket 11:09:58.85 recv WEBSOCKET_MSG
#' # \{chromote\} JS websocket 11:09:58.85 recv WEBSOCKET_MSG
#' # \{chromote\} JS info 11:09:58.85 shinytest2; shiny:busy
#' # \{chromote\} JS websocket 11:09:58.86 recv \{"custom":\{"showcase-src":\{"srcref":|truncated
#' # \{chromote\} JS websocket 11:09:58.86 recv \{"recalculating":\{"name":"distPlot",|truncated
#' # \{chromote\} JS websocket 11:09:58.86 recv WEBSOCKET_MSG
#' # \{chromote\} JS websocket 11:09:58.86 recv WEBSOCKET_MSG
#' # \{shinytest2\} R info 11:09:58.87 Shiny app started
#' # \{shinytest2\} R info 11:09:59.07 Setting inputs: 'bins'
#' # \{chromote\} JS websocket 11:09:59.08 recv \{"recalculating":\{"name":"distPlot",|truncated
#' # \{chromote\} JS websocket 11:09:59.08 recv \{"busy":"idle"\}
#' # \{chromote\} JS websocket 11:09:59.08 recv WEBSOCKET_MSG
#' # \{chromote\} JS websocket 11:09:59.08 recv WEBSOCKET_MSG
#' # \{chromote\} JS info 11:09:59.08 shinytest2; shiny:idle
#' # \{chromote\} JS websocket 11:09:59.08 recv \{"errors":\{\},"values":\{"distPlot":\{|truncated
#' # \{chromote\} JS websocket 11:09:59.08 recv WEBSOCKET_MSG
#' # \{chromote\} JS info 11:09:59.08 shinytest2; shiny:value distPlot
#' # \{chromote\} JS info 11:09:59.08 shinytest2; inputQueue: adding bins
#' # \{chromote\} JS info 11:09:59.09 shinytest2; inputQueue: flushing bins
#' # \{chromote\} JS websocket 11:09:59.10 send \{"method":"update","data":\{"bins":20\}\}
#' # \{chromote\} JS websocket 11:09:59.11 recv \{"progress":\{"type":"binding",|truncated
#' # \{chromote\} JS websocket 11:09:59.11 recv \{"busy":"busy"\}
#' # \{chromote\} JS websocket 11:09:59.10 send WEBSOCKET_MSG
#' # \{chromote\} JS websocket 11:09:59.11 recv WEBSOCKET_MSG
#' # \{chromote\} JS websocket 11:09:59.11 recv WEBSOCKET_MSG
#' # \{chromote\} JS info 11:09:59.11 shinytest2; shiny:busy
#' # \{chromote\} JS websocket 11:09:59.12 recv \{"custom":\{"showcase-src":\{"srcref":|truncated
#' # \{chromote\} JS websocket 11:09:59.14 recv \{"recalculating":\{"name":"distPlot",|truncated
#' # \{chromote\} JS websocket 11:09:59.18 recv \{"recalculating":\{"name":"distPlot",|truncated
#' # \{chromote\} JS websocket 11:09:59.19 recv \{"busy":"idle"\}
#' # \{chromote\} JS websocket 11:09:59.12 recv WEBSOCKET_MSG
#' # \{chromote\} JS websocket 11:09:59.14 recv WEBSOCKET_MSG
#' # \{chromote\} JS websocket 11:09:59.18 recv WEBSOCKET_MSG
#' # \{chromote\} JS websocket 11:09:59.19 recv WEBSOCKET_MSG
#' # \{chromote\} JS info 11:09:59.19 shinytest2; shiny:idle
#' # \{chromote\} JS websocket 11:09:59.21 recv \{"errors":\{\},"values":\{"distPlot":\{|truncated
#' # \{chromote\} JS websocket 11:09:59.21 recv WEBSOCKET_MSG
#' # \{chromote\} JS info 11:09:59.21 shinytest2; shiny:value distPlot
#' # \{shinytest2\} R info 11:09:59.21 Finished setting inputs. Timedout: FALSE
#' # \{shinytest2\} R info 11:09:59.21 Getting all values
Expand All @@ -1503,15 +1504,15 @@ AppDriver <- R6Class( # nolint
#' # \{shiny\} R error ----------- SEND \{"recalculating":\{"name":"distPlot",|truncated
#' # \{shiny\} R error ----------- SEND \{"recalculating":\{"name":"distPlot",|truncated
#' # \{shiny\} R error ----------- SEND \{"busy":"idle"\}
#' # \{shiny\} R error ----------- SEND \{"errors":\{\},"values":\{"distPlot":\{|truncated
#' # \{shiny\} R error ----------- SEND \{"errors":\{\},"values":\{"distPlot"|truncated
#' # \{shiny\} R error ----------- RECV \{"method":"update","data":\{"bins":20\}\}
#' # \{shiny\} R error ----------- SEND \{"progress":\{"type":"binding",|truncated
#' # \{shiny\} R error ----------- SEND \{"busy":"busy"\}
#' # \{shiny\} R error ----------- SEND \{"custom":\{"showcase-src":\{"srcref":|truncated
#' # \{shiny\} R error ----------- SEND \{"recalculating":\{"name":"distPlot",|truncated
#' # \{shiny\} R error ----------- SEND \{"recalculating":\{"name":"distPlot",|truncated
#' # \{shiny\} R error ----------- SEND \{"busy":"idle"\}
#' # \{shiny\} R error ----------- SEND \{"errors":\{\},"values":\{"distPlot":\{|truncated
#' # \{shiny\} R error ----------- SEND \{"errors":\{\},"values":\{"distPlot"|truncated
#'
#' # The log that is returned is a `data.frame()`.
#' log <- app$get_logs()
Expand All @@ -1524,23 +1525,24 @@ AppDriver <- R6Class( # nolint
#'
#' # It may be filtered to find desired logs
#' subset(log, level == "websocket")
#' # \{chromote\} JS websocket 11:09:58.73 send \{"method":"init","data":\{"bins":30,|truncated
#' # \{chromote\} JS websocket 11:09:58.78 recv \{"config":\{"workerId":"","sessionId":|truncated
#' # \{chromote\} JS websocket 11:09:58.85 recv \{"custom":\{"showcase-src":\{"srcref":|truncated
#' # \{chromote\} JS websocket 11:09:58.85 recv \{"busy":"busy"\}
#' # \{chromote\} JS websocket 11:09:58.86 recv \{"custom":\{"showcase-src":\{"srcref":|truncated
#' # \{chromote\} JS websocket 11:09:58.86 recv \{"recalculating":\{"name":"distPlot",|truncated
#' # \{chromote\} JS websocket 11:09:59.08 recv \{"recalculating":\{"name":"distPlot",|truncated
#' # \{chromote\} JS websocket 11:09:59.08 recv \{"busy":"idle"\}
#' # \{chromote\} JS websocket 11:09:59.08 recv \{"errors":\{\},"values":\{"distPlot":\{|truncated
#' # \{chromote\} JS websocket 11:09:59.10 send \{"method":"update","data":\{"bins":20\}\}
#' # \{chromote\} JS websocket 11:09:59.11 recv \{"progress":\{"type":"binding",|truncated
#' # \{chromote\} JS websocket 11:09:59.11 recv \{"busy":"busy"\}
#' # \{chromote\} JS websocket 11:09:59.12 recv \{"custom":\{"showcase-src":\{"srcref":|truncated
#' # \{chromote\} JS websocket 11:09:59.14 recv \{"recalculating":\{"name":"distPlot",|truncated
#' # \{chromote\} JS websocket 11:09:59.18 recv \{"recalculating":\{"name":"distPlot",|truncated
#' # \{chromote\} JS websocket 11:09:59.19 recv \{"busy":"idle"\}
#' # \{chromote\} JS websocket 11:09:59.21 recv \{"errors":\{\},"values":\{"distPlot":\{|truncated
#' ## (All WebSocket messages have been replaced with `WEBSOCKET_MSG` in example below)
#' # \{chromote\} JS websocket 11:09:58.73 send WEBSOCKET_MSG
#' # \{chromote\} JS websocket 11:09:58.78 recv WEBSOCKET_MSG
#' # \{chromote\} JS websocket 11:09:58.85 recv WEBSOCKET_MSG
#' # \{chromote\} JS websocket 11:09:58.85 recv WEBSOCKET_MSG
#' # \{chromote\} JS websocket 11:09:58.86 recv WEBSOCKET_MSG
#' # \{chromote\} JS websocket 11:09:58.86 recv WEBSOCKET_MSG
#' # \{chromote\} JS websocket 11:09:59.08 recv WEBSOCKET_MSG
#' # \{chromote\} JS websocket 11:09:59.08 recv WEBSOCKET_MSG
#' # \{chromote\} JS websocket 11:09:59.08 recv WEBSOCKET_MSG
#' # \{chromote\} JS websocket 11:09:59.10 send WEBSOCKET_MSG
#' # \{chromote\} JS websocket 11:09:59.11 recv WEBSOCKET_MSG
#' # \{chromote\} JS websocket 11:09:59.11 recv WEBSOCKET_MSG
#' # \{chromote\} JS websocket 11:09:59.12 recv WEBSOCKET_MSG
#' # \{chromote\} JS websocket 11:09:59.14 recv WEBSOCKET_MSG
#' # \{chromote\} JS websocket 11:09:59.18 recv WEBSOCKET_MSG
#' # \{chromote\} JS websocket 11:09:59.19 recv WEBSOCKET_MSG
#' # \{chromote\} JS websocket 11:09:59.21 recv WEBSOCKET_MSG
#' }
get_logs = function() {
app_get_logs(self, private)
Expand Down
1 change: 1 addition & 0 deletions R/test-app.R
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ test_app <- function(
#' loads your Shiny app support environment into the testing environment.
#'
#' @param app_dir The base directory for the Shiny application.
#' @param renv The environment in which the files in the `R/`` directory should be evaluated.
#' @inheritParams shiny::loadSupport
#' @export
load_app_env <- function(
Expand Down
24 changes: 10 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,28 @@
[![Lifecycle: experimental](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://lifecycle.r-lib.org/articles/stages.html#experimental)
<!-- badges: end -->

Manually testing Shiny applications is often laborious, inconsistent, and doesn’t scale well. Whether you are developing new features, fixing bug(s), or simply upgrading dependencies on a serious app where mistakes have real consequences, it is critical to know when regressions are introduced. `{shinytest2}` provides a streamlined toolkit for unit testing Shiny applications and seamlessly integrates with the popular `{testthat}` framework for unit testing R code.

> :triangular_flag_on_post::triangular_flag_on_post:<br/>
> {shinytest2} is in beta developement.<br/>
> Please report any bugs or feedback at [https://github.com/rstudio/shinytest2/issues](https://github.com/rstudio/shinytest2/issues) <br/>
> :triangular_flag_on_post::triangular_flag_on_post:

Manually testing Shiny applications is often laborious, inconsistent, and doesn’t scale well. Whether you are developing new features, fixing bug(s), or simply upgrading dependencies on a serious app where mistakes have real consequences, it is critical to know when regressions are introduced. `{shinytest2}` provides a streamlined toolkit for unit testing Shiny applications and seamlessly integrates with the popular [`{testthat}`](https://testthat.r-lib.org/) framework for unit testing R code.

`{shinytest2}` uses [`{chromote}`](https://rstudio.github.io/chromote/) to render applications in a headless Chrome browser. `{chromote}` allows for a live preview, better debugging tools, and/or simply using modern JavaScript/CSS.
`{shinytest2}` uses `{chromote}` to render applications in a headless Chrome browser. `{chromote}` allows for a live preview, better debugging tools, and/or simply using modern JavaScript/CSS.

By simply recording your actions as code and extending them to test the more particular aspects of your application, it will result in fewer bugs and more confidence in future Shiny application development.


## Installation

You can install the [development version of `{shinytest2}`](https://github.com/rstudio/shinytest2) from GitHub with:
```r
# Install the released version from CRAN
install.packages("shinytest2")

``` r
remotes::install_github("rstudio/shinytest2")
# Or the development version from GitHub:
# install.packages("devtools")
devtools::install_github("rstudio/shinytest2")
```

Please check out our [Getting Started](https://rstudio.github.io/shinytest2/articles/shinytest2.html) article for example usage.

## Usage

The easiest way to get started is by calling `shinytest2::record_test()` in your app directory. This will open a Shiny application to record your actions as code. To programmatically create a test, call `shinytest2::use_shinytest2_test()`.

Call `shinytest2::use_shinytest2()` to create a initial value test file and set up any other infrastructure you may need.

Please check out our [Getting Started](https://rstudio.github.io/shinytest2/articles/shinytest2.html) article for example usage.
35 changes: 35 additions & 0 deletions cran-comments.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
## Comments

#### 2022-04-23

Releasing a new package `{shinytest2}`.

Please let me know if there is any more information I can provide.

Thank you,
Barret


## Test environments

* local macOS, R 4.1.3
* GitHub Actions
* macOS
* 4.1
* windows
* 4.1
* ubuntu18
* devel, 4.1, 4.0, 3.6, 3.5, 3.4
* devtools::
* check_win_devel()
* check_win_release()
* check_win_oldrelease()

## R CMD check results

0 errors ✔ | 0 warnings ✔ | 1 note

N checking CRAN incoming feasibility
Maintainer: ‘Barret Schloerke <[email protected]>

New submission
Loading

0 comments on commit 9f92e77

Please sign in to comment.