knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.path = "man/figures/README-", out.width = "100%" ) library(details)
When developing Shiny apps there is a lot of reactivity problems that can arise when one reactive
or observe
element triggers other elements. In some cases these can create cascading reactivity (the horror). The goal of reactor
is to diagnose these reactivity problems and then plan unit tests to avert them during development to make development less painful.
And the development version from GitHub with:
# install.packages("remotes") remotes::install_github("yonicd/reactor")
Reactor is a pipeline driven api where the user does not need to learn RSelenium in order to be able to drive their applications
Start by creating a reactor class object
library(reactor) obj <- init_reactor() obj
You can see it is expecting to be populated by two objects
Reactor comes with functions to help you create these specifications
set_runapp_args()
: Assumes that the application is located in a path on the machine and uses shiny::runApp
as the function to launch the applicationset_golem_args()
: Assumes that the application is a golem package and uses the golem
logic to launch the application.set_chrome_driver()
: Launches RSelenium
with a chrome webdriver set_firefox_driver()
: Launches RSelenium
with a firefox (gecko) webdriver obj <- obj%>% set_runapp_args( appDir = system.file('examples/good_app.R',package = 'reactor') )%>% set_chrome_driver()
```{details, echo = FALSE,details.lang = 'yml',details.summary = 'reactor object'} obj
If you want turn off headless mode you can update the object ```r obj <- obj%>% set_chrome_driver( opts = chrome_options(headless = FALSE) )
```{details, echo = FALSE, details.lang = 'yml',details.summary = 'reactor object'} obj
### Starting Reactor Once we have specifications in place we can start reactor using `start_reactor()`. ```r obj%>% start_reactor()
Now that the app is running we can send to the webdriver to interact with the application
set_id_value()
: obj%>% set_id_value('n',500)
The user can use the following utility functions to interact and query with an application
Inject:
set_id_value()
: Sets a value for a shiny input object by idexecute()
: Executes a JavaScript callQuery:
query_input_names()
: Returns names of the shiny input idsquery_input_id()
: Returns current values of a shiny input by idquery_output_names()
: Returns names of the shiny output idsquery_output_id()
: Returns current values of a shiny output by idquery()
: Returns a value from JavaScript callTo safely close reactor and all the child processes use kill_app()
:
obj%>% kill_app()
Because each function is returning the reactor object it is simple to create reactor pipelines.
Reactor will wait for shiny to finish each action before proceeding to the next one.
init_reactor()%>% set_runapp_args( appDir = system.file('examples/good_app.R',package = 'reactor') )%>% set_chrome_driver()%>% start_reactor()%>% set_id_value('n',500)%>% set_id_value('n',300)%>% kill_app()
Finally reactor tests reactivity expectations in a testthat
framework using the builtin expect_reactivity()
function
init_reactor()%>% set_runapp_args( appDir = system.file('examples/good_app.R',package = 'reactor') )%>% set_chrome_driver()%>% start_reactor()%>% set_id_value('n',500)%>% expect_reactivity('hist',1)%>% set_id_value('n',200)%>% expect_reactivity('hist',2)%>% kill_app()
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.