| Title: | Test Shiny Apps |
| Version: | 1.6.1 |
| Description: | Please see the 'shinytest' to 'shinytest2' migration guide at https://rstudio.github.io/shinytest2/articles/z-migration.html. |
| License: | MIT + file LICENSE |
| URL: | https://github.com/rstudio/shinytest |
| BugReports: | https://github.com/rstudio/shinytest/issues |
| Imports: | assertthat, callr (≥ 2.0.3), crayon, debugme, digest, htmlwidgets, httpuv, httr, jsonlite, parsedate, pingr, R6, rematch, rlang, rstudioapi (≥ 0.8.0.9002), shiny (≥ 1.3.2), testthat (≥ 1.0.0), utils, webdriver (≥ 1.0.6), withr |
| Suggests: | flexdashboard, globals, rmarkdown |
| Encoding: | UTF-8 |
| RoxygenNote: | 7.3.1 |
| SystemRequirements: | PhantomJS (http://phantomjs.org/) |
| NeedsCompilation: | no |
| Packaged: | 2024-05-30 18:58:12 UTC; winston |
| Author: | Winston Chang [aut, cre], Gábor Csárdi [aut], Hadley Wickham [aut], Posit Software, PBC [cph, fnd], Ascent Digital Services [cph, ccp] |
| Maintainer: | Winston Chang <winston@posit.co> |
| Repository: | CRAN |
| Date/Publication: | 2024-05-30 19:10:02 UTC |
shinytest: Test Shiny Apps
Description
Please see the shinytest to shinytest2 migration guide at https://rstudio.github.io/shinytest2/articles/z-migration.html
Author(s)
Maintainer: Winston Chang winston@posit.co
Authors:
Gábor Csárdi gabor@posit.co
Hadley Wickham hadley@posit.co
Other contributors:
Posit Software, PBC [copyright holder, funder]
Ascent Digital Services [copyright holder, conceptor]
See Also
Useful links:
Remote control a Shiny app running in a headless browser
Description
This class starts a Shiny app in a new R session, along with a phantom.js
headless browser that can be used to simulate user actions. This provides
a full simulation of a Shiny app so that you can test user interactions
with a live app.
Methods
Public methods
Method new()
Usage
ShinyDriver$new(
path = ".",
loadTimeout = NULL,
checkNames = TRUE,
debug = c("none", "all", shinytest::ShinyDriver$debugLogTypes),
phantomTimeout = 5000,
seed = NULL,
cleanLogs = TRUE,
shinyOptions = list(),
renderArgs = NULL,
options = list()
)Arguments
pathPath to a directory containing a Shiny app, i.e. a single
app.Rfile or aserver.R-ui.Rpair.loadTimeoutHow long to wait for the app to load, in ms. This includes the time to start R. Defaults to 5s when running locally and 10s when running on CI.
checkNamesCheck if widget names are unique?
debugStart the app in debugging mode? In debugging mode debug messages are printed to the console.
phantomTimeoutHow long to wait when connecting to phantomJS process, in ms
seedAn optional random seed to use before starting the application. For apps that use R's random number generator, this can make their behavior repeatable.
cleanLogsWhether to remove the stdout and stderr logs when the Shiny process object is garbage collected.
shinyOptionsA list of options to pass to
shiny::runApp().renderArgsPassed to
rmarkdown::run()for interactive.Rmds.optionsA list of
base::options()to set in the driver's child process.
Method finalize()
Stop app and clean up logs.
Usage
ShinyDriver$finalize()
Method stop()
Stop the app, the terminate external R process that runs the app and the phantomjs instance.
Usage
ShinyDriver$stop()
Method getValue()
Finds a widget and queries its value. See the getValue() method of
Widget for more details.
Usage
ShinyDriver$getValue(name, iotype = c("auto", "input", "output"))Arguments
nameName of a shiny widget.
iotypeType of the Shiny widget. Usually shinytest finds the widgets by their name, so this is only needed if you use the same name for an input and output widget.
Method setValue()
Finds a widget and sets its value. It's a shortcut for findElement()
plus setValue(); see the Widget documentation for more details.
Usage
ShinyDriver$setValue(name, value, iotype = c("auto", "input", "output"))Arguments
nameName of a shiny widget.
valueNew value.
iotypeType of the Shiny widget. Usually shinytest finds the widgets by their name, so this is only needed if you use the same name for an input and output widget.
Returns
Self, invisibly.
Method click()
Find a widget and click it. It's a shortcut for findElement()
plus click(); see the Widget documentation for more details.
Usage
ShinyDriver$click(name, iotype = c("auto", "input", "output"))Arguments
nameName of a shiny widget.
iotypeType of the Shiny widget. Usually shinytest finds the widgets by their name, so this is only needed if you use the same name for an input and output widget.
Method getAllValues()
Returns a named list of all inputs, outputs, and export values.
Usage
ShinyDriver$getAllValues(input = TRUE, output = TRUE, export = TRUE)
Arguments
input, output, exportEither
TRUEto return all input/output/exported values, or a character vector of specific controls.
Method sendKeys()
Sends the specified keys to specific HTML element. Shortcut for
findWidget() plus sendKeys().
Usage
ShinyDriver$sendKeys(name, keys)
Arguments
nameName of a shiny widget.
keysKeys to send to the widget or the app. See webdriver::key for how to specific special keys.
Returns
Self, invisibly.
Method setWindowSize()
Sets size of the browser window.
Usage
ShinyDriver$setWindowSize(width, height)
Arguments
width, heightHeight and width of browser, in pixels.
Returns
Self, invisibly.
Method getWindowSize()
Get current size of the browser window, as list of integer scalars
named width and height.
Usage
ShinyDriver$getWindowSize()
Method getDebugLog()
Query one or more of the debug logs.
Usage
ShinyDriver$getDebugLog(type = c("all", ShinyDriver$debugLogTypes))Arguments
typeLog type:
"all","shiny_console","browser", or"shinytest".
Method enableDebugLogMessages()
Enable/disable debugging messages
Usage
ShinyDriver$enableDebugLogMessages(enable = TRUE)
Arguments
enableNew value.
Method logEvent()
Add event to log.
Usage
ShinyDriver$logEvent(event, ...)
Arguments
eventEvent name
...Addition data to store for event
Method getEventLog()
Retrieve event log.
Usage
ShinyDriver$getEventLog()
Method getUrl()
Get current url
Usage
ShinyDriver$getUrl()
Method getTitle()
Get page title
Usage
ShinyDriver$getTitle()
Method getSource()
Get complete source of current page.
Usage
ShinyDriver$getSource()
Method goBack()
Return to previous page
Usage
ShinyDriver$goBack()
Returns
Self, invisibly.
Method refresh()
Refresh the browser
Usage
ShinyDriver$refresh()
Returns
Self, invisibly.
Method takeScreenshot()
Takes a screenshot of the current page and writes it to a PNG file or shows on current graphics device.
Usage
ShinyDriver$takeScreenshot(file = NULL, id = NULL, parent = FALSE)
Arguments
fileFile name to save the screenshot to. If
NULL, then it will be shown on the R graphics device.idIf not-
NULL, will take a screenshot of element with this id.parentIf
TRUE, will take screenshot of parent ofid; this is useful if you also want to capture the label attached to a Shiny control.
Returns
Self, invisibly.
Method findElement()
Find an HTML element on the page, using a CSS selector, XPath expression,
or link text (for <a> tags). If multiple elements are matched, only
the first is returned.
Usage
ShinyDriver$findElement( css = NULL, linkText = NULL, partialLinkText = NULL, xpath = NULL )
Arguments
cssCSS selector to find an HTML element.
linkTextFind
<a>HTML elements based on exactinnerTextpartialLinkTextFind
<a>HTML elements based on partialinnerTextxpathFind HTML elements using XPath expressions.
Returns
Method findElements()
Find all elements matching CSS selection, xpath, or link text.
Usage
ShinyDriver$findElements( css = NULL, linkText = NULL, partialLinkText = NULL, xpath = NULL )
Arguments
cssCSS selector to find an HTML element.
linkTextFind
<a>HTML elements based on exactinnerTextpartialLinkTextFind
<a>HTML elements based on partialinnerTextxpathFind HTML elements using XPath expressions.
Returns
A list of webdriver::Elements.
Method waitFor()
Waits until a JavaScript expression evaluates to true or the
timeout is exceeded.
Usage
ShinyDriver$waitFor(expr, checkInterval = 100, timeout = 3000)
Arguments
exprA string containing JavaScript code. Will wait until the condition returns
true.checkIntervalHow often to check for the condition, in ms.
timeoutAmount of time to wait before giving up (milliseconds).
Returns
TRUE if expression evaluates to true without error, before
timeout. Otherwise returns NA.
Method waitForShiny()
Waits until Shiny is not busy, i.e. the reactive graph has finished
updating. This is useful, for example, if you've resized the window with
setWindowSize() and want to make sure all plot redrawing is complete
before take a screenshot.
Usage
ShinyDriver$waitForShiny()
Returns
TRUE if done before before timeout; NA otherwise.
Method waitForValue()
Waits until the input or output with name name is not one of
ignored values, or the timeout is reached.
This function can be useful in helping determine if an application has initialized or finished processing a complex reactive situation.
Usage
ShinyDriver$waitForValue(
name,
ignore = list(NULL, ""),
iotype = c("input", "output", "export"),
timeout = 10000,
checkInterval = 400
)Arguments
nameName of a shiny widget.
ignoreList of possible values to ignore when checking for updates.
iotypeType of the Shiny widget. Usually shinytest finds the widgets by their name, so this is only needed if you use the same name for an input and output widget.
timeoutAmount of time to wait before giving up (milliseconds).
checkIntervalHow often to check for the condition, in ms.
Method listWidgets()
Lists the names of all input and output widgets
Usage
ShinyDriver$listWidgets()
Returns
A list of two character vectors, named input and output.
Method checkUniqueWidgetNames()
Check if Shiny widget names are unique.
Usage
ShinyDriver$checkUniqueWidgetNames()
Method executeScript()
Execute JS code
Usage
ShinyDriver$executeScript(script, ...)
Arguments
scriptJS to execute.
...Additional arguments to script.
Returns
Self, invisibly.
Method executeScriptAsync()
Execute JS code asynchronously.
Usage
ShinyDriver$executeScriptAsync(script, ...)
Arguments
scriptJS to execute.
...Additional arguments to script.
Returns
Self, invisibly.
Method findWidget()
Finds the a Shiny input or output control.
Usage
ShinyDriver$findWidget(name, iotype = c("auto", "input", "output"))Arguments
nameName of a shiny widget.
iotypeType of the Shiny widget. Usually shinytest finds the widgets by their name, so this is only needed if you use the same name for an input and output widget.
Returns
A Widget.
Method expectUpdate()
It performs one or more update operations via the browser, thens
waits for the specified output(s) to update. The test succeeds if
all specified output widgets are updated before the timeout.
For updates that involve a lot of computation, increase the timeout.
Usage
ShinyDriver$expectUpdate(
output,
...,
timeout = 3000,
iotype = c("auto", "input", "output")
)Arguments
outputName of output control to check.
...Name-value pairs used to update inputs.
timeoutAmount of time to wait before giving up (milliseconds).
iotypeType of the Shiny widget. Usually shinytest finds the widgets by their name, so this is only needed if you use the same name for an input and output widget.
Method setInputs()
Sets input values.
Usage
ShinyDriver$setInputs(
...,
wait_ = TRUE,
values_ = TRUE,
timeout_ = 3000,
allowInputNoBinding_ = FALSE,
priority_ = c("input", "event")
)Arguments
...Name-value pairs,
name1 = value1, name2 = value2etc. Enput with namename1will be assigned valuevalue1.wait_Wait until all reactive updates have completed?
values_If
TRUE, will return final updated values of inputs.timeout_Amount of time to wait before giving up (milliseconds).
allowInputNoBinding_When setting the value of an input, allow it to set the value of an input even if that input does not have an input binding.
priority_Sets the event priority. For expert use only: see https://shiny.rstudio.com/articles/communicating-with-js.html#values-vs-events for details.
Returns
Returns updated values, invisibly.
Method uploadFile()
Uploads a file to a file input.
Usage
ShinyDriver$uploadFile(..., wait_ = TRUE, values_ = TRUE, timeout_ = 3000)
Arguments
...Name-path pairs, e.g.
name1 = path1. The file located atpath1will be uploaded to file input with namename1.wait_Wait until all reactive updates have completed?
values_If
TRUE, will return final updated values of download control.timeout_Amount of time to wait before giving up (milliseconds).
Method snapshotInit()
Download a snapshot. Generally, you should not call this function
yourself; it will be generated by recordTest() as needed.
Usage
ShinyDriver$snapshotInit(path, screenshot = TRUE)
Arguments
pathDirectory to save snapshots.
screenshotTake screenshots for each snapshot?
Method snapshot()
Take a snapshot. Generally, you should not call this function
yourself; it will be generated by recordTest() as needed.
Usage
ShinyDriver$snapshot(items = NULL, filename = NULL, screenshot = NULL)
Arguments
itemsElements to include in snapshot
filenameFilename to use. It is recommended to use a
.jsonfile extension.screenshotTake a screenshot? Overrides value set by
$snapshotInit()
Method snapshotCompare()
Deprecated
Usage
ShinyDriver$snapshotCompare(...)
Arguments
...Ignored
Method snapshotDownload()
Snapshot a file download action. Generally, you should not call this
function yourself; it will be generated by recordTest() as needed.
Usage
ShinyDriver$snapshotDownload(id, filename = NULL)
Arguments
idOutput id of
shiny::downloadButton()/shiny::downloadLink()filenameFile name to save file to. The default,
NULL, generates an ascending sequence of names:001.download,002.download, etc.
Method getAppDir()
Directory where app is located
Usage
ShinyDriver$getAppDir()
Method getAppFilename()
App file name, i.e. app.R or server.R. NULL for Rmds.
Usage
ShinyDriver$getAppFilename()
Method getTestsDir()
Directory where tests are located
Usage
ShinyDriver$getTestsDir()
Method getRelativePathToApp()
Relative path to app from current directory.
Usage
ShinyDriver$getRelativePathToApp()
Method getSnapshotDir()
Directory where snapshots are located.
Usage
ShinyDriver$getSnapshotDir()
Method isRmd()
Is this app an Shiny Rmd document?
Usage
ShinyDriver$isRmd()
Method clone()
The objects of this class are cloneable with this method.
Usage
ShinyDriver$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
A Shiny Widget
Description
A Widget object represents a Shiny input or output control, and provides
methods for finer grained interaction.
Methods
Public methods
Method new()
Create new Widget
Usage
Widget$new(name, element, type, iotype = c("input", "output"))Arguments
nameName of a Shiny widget.
elementtypeWidget type
iotypeInput/output type.
Method getName()
Control id (i.e. inputId or outputId that control
was created with).
Usage
Widget$getName()
Method getElement()
Underlying webdriver::Element() object.
Usage
Widget$getElement()
Method getHtml()
retrieve the underlying HTML for a widget
Usage
Widget$getHtml()
Method getType()
Widget type, e.g. textInput, selectInput.
Usage
Widget$getType()
Method getIoType()
Is this an input or output control?
Usage
Widget$getIoType()
Method isInput()
Is this an input control?
Usage
Widget$isInput()
Method isOutput()
Is this an output control?
Usage
Widget$isOutput()
Method getValue()
Get current value of control.
Usage
Widget$getValue()
Method setValue()
Set value of control.
Usage
Widget$setValue(value)
Arguments
valueValue to set for the widget.
Method click()
scrolls the element into view, then clicks the in-view centre point of it.
Usage
Widget$click()
Returns
self, invisibly.
Method sendKeys()
Send specified key presses to control.
Usage
Widget$sendKeys(keys)
Arguments
keysKeys to send to the widget or the app. See webdriver::key for how to specific special keys.
Method listTabs()
Lists the tab names of a shiny::tabsetPanel().
It fails for other types of widgets.
Usage
Widget$listTabs()
Method uploadFile()
Upload a file to a shiny::fileInput().
It fails for other types of widgets.
Usage
Widget$uploadFile(filename)
Arguments
filenamePath to file to upload
Method clone()
The objects of this class are cloneable with this method.
Usage
Widget$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
Checks for/installs dependencies
Description
dependenciesInstalled() that all the required system dependency,
PhantomJS, is installed, and installDependencies() installs it if needed.
For more information about where PhantomJS will be installed
see webdriver::install_phantomjs().
Usage
dependenciesInstalled()
installDependencies()
Value
TRUE when all dependencies are fulfilled; otherwise, FALSE.
Creat an htmlwidget that shows differences between files or directories
Description
This function can be used for viewing differences between current test results and the expected results
Usage
diffviewer_widget(old, new, width = NULL, height = NULL, pattern = NULL)
Arguments
old, new |
Names of the old and new directories to compare. Alternatively, they can be a character vectors of specific files to compare. |
width |
Width of the htmlwidget. |
height |
Height of the htmlwidget |
pattern |
A filter to apply to the old and new directories. |
testthat expectation for a Shiny update
Description
testthat expectation for a Shiny update
Usage
expectUpdate(
app,
output,
...,
timeout = 3000,
iotype = c("auto", "input", "output")
)
Arguments
app |
A |
output |
Character vector, the name(s) of the output widgets that are required to update for the test to succeed. |
... |
Named arguments specifying updates for Shiny input widgets. |
timeout |
Timeout for the update to happen, in milliseconds. |
iotype |
Type of the widget(s) to change. These are normally input widgets. |
Examples
## Not run:
## https://github.com/rstudio/shiny-examples/tree/main/050-kmeans-example
app <- ShinyDriver$new("050-kmeans-example")
expectUpdate(app, xcol = "Sepal.Width", output = "plot1")
expectUpdate(app, ycol = "Petal.Width", output = "plot1")
expectUpdate(app, clusters = 4, output = "plot1")
## End(Not run)
Expectation: testApp() passes snapshot tests
Description
This returns an testthat expectation object.
Usage
expect_pass(object, info = NULL)
Arguments
object |
The results returned by |
info |
Extra information to be included in the message (useful when writing tests in loops). |
Examples
## Not run:
expect_pass(testApp("path/to/app/"))
## End(Not run)
Migrate legacy shinytest files to new test directory structure
Description
This function migrates the old-style directory structure used by shinytest (versions 1.3.1 and below) to new test directory structure used in shinytest 1.4.0 and above.
Usage
migrateShinytestDir(appdir, dryrun = FALSE)
Arguments
appdir |
A directory containing a Shiny application. |
dryrun |
If |
Details
Before shinytest 1.4.0, the shinytest scripts and results were put in a
subdirectory of the application named tests/. As of shinytest 1.4.0,
the tests are put in tests/shinytest/, so that it works with the
runTests() function shiny package (added in shiny 1.5.0).
With shinytest 1.3.1 and below, the tests/ subdirectory of the application was used specifically for shinytest, and could not be used for other types of tests. So the directory structure would look like this:
appdir/
`- tests
`- mytest.R
In Shiny 1.5.0, the shiny::runTests() function was added, and it will run
test scripts tests/ subdirectory of the application. This makes it possible
to use other testing systems in addition to shinytest. shinytest 1.4.0
is designed to work with this new directory structure. The directory
structure looks something like this:
appdir/
|- R
|- tests
|- shinytest.R
|- shinytest
| `- mytest.R
|- testthat.R
`- testthat
`- test-script.R
This allows for tests using the shinytest package as well as other
testing tools, such as the shiny::testServer() function, which can be used
for testing module and server logic, and for unit tests of functions in an R/
subdirectory.
In shinytest 1.4.0 and above, it defaults to creating the new directory structure.
Get the name of the OS
Description
Returns the name of the current OS. This can be useful for the suffix when
running testApp().
Usage
osName()
Launch test event recorder for a Shiny app
Description
Launch test event recorder for a Shiny app
Usage
recordTest(
app = ".",
save_dir = NULL,
load_mode = FALSE,
seed = NULL,
loadTimeout = 10000,
debug = "shiny_console",
shinyOptions = list()
)
Arguments
app |
A |
save_dir |
A directory to save stuff. |
load_mode |
A boolean that determines whether or not the resulting test script should be appropriate for load testing. |
seed |
A random seed to set before running the app. This seed will also be used in the test script. |
loadTimeout |
Maximum time to wait for the Shiny application to load, in milliseconds. If a value is provided, it will be saved in the test script. |
debug |
start the underlying |
shinyOptions |
A list of options to pass to |
Register an input processor for the test recorder
Description
registerInputProcessor() registers an input processor which will be used by
the test recorder. The input processor function should take one parameter,
value, and return a string of R code which returns the desired value.
getInputProcessors() returns a named list of all registered input processor
functions.
Usage
registerInputProcessor(inputType, processor)
getInputProcessors()
Arguments
inputType |
The name of an input type, for example,
|
processor |
An input processor function. |
Compare current and expected snapshots
Description
This compares current and expected snapshots for a test set, and prints any differences to the console.
Usage
snapshotCompare(
appDir,
testnames = NULL,
autoremove = TRUE,
images = TRUE,
quiet = FALSE,
interactive = is_interactive(),
suffix = NULL
)
snapshotUpdate(appDir = ".", testnames = NULL, quiet = FALSE, suffix = NULL)
Arguments
appDir |
Directory that holds the tests for an application. This is the parent directory for the expected and current snapshot directories. |
testnames |
Name or names of a test. If NULL, compare all test results. |
autoremove |
If the current results match the expected results, should the current results be removed automatically? Defaults to TRUE. |
images |
Should screenshots and PNG images be compared? It can be useful
to set this to |
quiet |
Should output be suppressed? This is useful for automated testing. |
interactive |
If there are any differences between current results and expected results, provide an interactive graphical viewer that shows the changes and allows the user to accept or reject the changes. |
suffix |
An optional suffix for the expected results directory. For
example, if the suffix is |
See Also
Run tests for a Shiny application
Description
Run tests for a Shiny application
Usage
testApp(
appDir = ".",
testnames = NULL,
quiet = FALSE,
compareImages = TRUE,
interactive = is_interactive(),
suffix = NULL
)
Arguments
appDir |
Path to directory containing a Shiny app (e.g. |
testnames |
Test script(s) to run. The .R extension of the filename is
optional. For example, |
quiet |
Should output be suppressed? This is useful for automated testing. |
compareImages |
Should screenshots be compared? It can be useful to set
this to |
interactive |
If there are any differences between current results and expected results, provide an interactive graphical viewer that shows the changes and allows the user to accept or reject the changes. |
suffix |
An optional suffix for the expected results directory. For
example, if the suffix is |
See Also
snapshotCompare() and snapshotUpdate() if
you want to compare or update snapshots after testing. In most cases, the
user is prompted to do these tasks interactively, but there are also times
where it is useful to call these functions from the console.
Get textual diff of test results
Description
Get textual diff of test results
Usage
textTestDiff(appDir = ".", testnames = NULL, images = TRUE, suffix = NULL)
Arguments
appDir |
Directory of the Shiny application that was tested. |
testnames |
A character vector of names of tests to compare. If NULL, compare all test results for which there are differences. |
images |
Compare screenshot images. |
suffix |
An optional suffix for the expected results directory. For
example, if the suffix is |
See Also
viewTestDiff() for interactive diff viewer.
View differences in test results
Description
View differences in test results
Usage
viewTestDiff(
appDir = ".",
testnames = NULL,
interactive = is_interactive(),
images = TRUE,
suffix = NULL
)
Arguments
appDir |
Directory of the Shiny application that was tested. |
testnames |
A character vector of names of tests to compare. If NULL, compare all test results for which there are differences. |
interactive |
If TRUE, use the interactive diff viewer, which runs in a
Shiny app. If FALSE, print a textual diff, generated by
|
images |
Compare screenshot images (only used when |
suffix |
An optional suffix for the expected results directory. For
example, if the suffix is |
Value
A character vector the same length as testnames, with
"accept" or "reject" for each test.
See Also
textTestDiff() to get a text diff as a string.
Interactive viewer widget for changes in test results
Description
Interactive viewer widget for changes in test results
Usage
viewTestDiffWidget(appDir = ".", testname = NULL, suffix = NULL)
Arguments
appDir |
Directory of the Shiny application that was tested. |
testname |
Name of test to compare. |
suffix |
An optional suffix for the expected results directory. For
example, if the suffix is |