knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  fig.path = "man/figures/README-",
  out.width = "100%", 
  eval = TRUE, 
  cache = FALSE
)

crrry

The goal of crrry is to provide some recipes around {crrri} for manipulating shiny applications from the command line.

Installation

You can install the development version of {crrry} from GitHub with:

# install.packages("remotes")
remotes::install_github("ColinFay/crrry")

Starting example

Generate a chrome object connection to a specific app (here, online).

(Note: the randomPort() function requires httpuv >= 1.5.2)

# install.packages("pagedown")
# install.packages("httpuv")
test <- crrry::CrrryOnPage$new(
  chrome_bin = pagedown::find_chrome(),
  chrome_port = httpuv::randomPort(),
  url = "https://connect.thinkr.fr/prenoms/",
  headless = TRUE
)

Block the process until shiny is ready to continue:

test$wait_for_shiny_ready()

You can send random JavaScript:

test$call_js(
      '$("#mod_popuui-dep").click()'
    )

call_js() returns its value invisibly, but it can be assigned:

res <- test$call_js(
      '$("#mod_popuui-choix").attr("value")'
    )
res

Set the value of a shiny input

test$shiny_set_input(
    "mod_popuui-depchoice", 
    "59"
  )

Note that this doesn't change the front, only the backend. You won't see the input change with this one, but the reactivity linked to this input changes.

Wait for a condition to be true:

test$wait_for('$("#mod_popuui-depchoice").text() == "01"')

Send some gremlins:

test$gremlins_horde()

Stop the process:

test$stop()

Use on a local app

test <- crrry::CrrryProc$new(
  # find the chrome binary
  chrome_bin = pagedown::find_chrome(),
  # Set chrome on a random port
  chrome_port = httpuv::randomPort(),
  # Set shiny on a random port
  shiny_port = httpuv::randomPort(),
  # The code to launch the shiny app
  fun = "hexmake::run_app()",
  # optional code to launch before `fun`
  pre_launch_cmd = "whereami::set_whereami_log('~/Desktop')",
  # Should Chrome be launched headless?
  headless = FALSE
)

To get the output of the process, run $stdout() and $stderr()

test$wait_for_shiny_ready()
test$stderr()
test$stdout()
jsonlite::fromJSON("~/Desktop/whereami.json")
test$stop()

Perform a load test

In combination with {dockerstats}

system("docker run -p 2708:80 --rm --name hexmake colinfay/hexmake", wait = FALSE)
Sys.sleep(5)
library(dockerstats)

unlink("inst/dockerstatsss.csv")

tests <- list()

n_users <- 4

append_csv <- function(
  message,
  i
){
  readr::write_csv(
    append = TRUE,
    dockerstats::dockerstats("hexmake", extra = sprintf(
      "%s - %s", message, i
    )),
    "inst/dockerstatsss.csv"
  )
}


for (i in 1:n_users){
  cli::cat_rule(as.character(i))
  tests[[i]] <- crrry::CrrryOnPage$new(
    chrome_bin = pagedown::find_chrome(),
    chrome_port = httpuv::randomPort(),
    url = "http://localhost:2708",
    headless = FALSE
  )
  append_csv( "Connection", i)
}

for (i in 1:n_users){
  Sys.sleep(0.5)
  cli::cat_rule(as.character(i))
  tests[[i]]$call_js('$("summary:contains(\'Name\')").click()')
  append_csv( "Clicking on Name", i)
}

for (i in 1:n_users){
  Sys.sleep(0.5)
  cli::cat_rule(as.character(i))
  tests[[i]]$shiny_set_input(
    "main_ui_1-left_ui_1-pkg_name_ui_1-package", 
    "pouet"
  )
  append_csv( "Changin pkg name", i)
}

for (i in 1:n_users){
  Sys.sleep(0.5)
  cli::cat_rule(as.character(i))
  tests[[i]]$gremlins_horde()
  Sys.sleep(5)
  append_csv( "gremlins", i)
}

for (i in 1:n_users){
  Sys.sleep(0.5)
  cli::cat_rule(as.character(i))
  tests[[i]]$stop()
}
system("docker kill hexmake")

Analyse results

df <- readr::read_csv(
  "inst/dockerstatsss.csv", 
  col_names = names(dockerstats::dockerstats())
  )
df$MemUsage <- fs::as_fs_bytes(
  df$MemUsage
)
library(ggplot2)
ggplot() + 
  geom_line(data = df, aes(x = record_time, y = MemUsage)) + 
  scale_y_continuous(labels = scales::label_bytes())


ColinFay/crrry documentation built on Oct. 14, 2020, 12:13 p.m.