├── .Rbuildignore ├── .github ├── .gitignore ├── shiny-workflows │ └── routine.sh └── workflows │ ├── R-CMD-check.yaml │ └── test-actions.yaml ├── .gitignore ├── .lintr ├── .vscode ├── c_cpp_properties.json └── settings.json ├── DESCRIPTION ├── LICENSE ├── LICENSE.md ├── NAMESPACE ├── NEWS.md ├── R ├── R6-helper.R ├── app-driver-chromote.R ├── app-driver-dir.R ├── app-driver-expect-download.R ├── app-driver-expect-js.R ├── app-driver-expect-screenshot.R ├── app-driver-expect-unique-names.R ├── app-driver-expect-values.R ├── app-driver-get-log.R ├── app-driver-initialize.R ├── app-driver-log-message.R ├── app-driver-message.R ├── app-driver-node.R ├── app-driver-set-inputs.R ├── app-driver-start.R ├── app-driver-stop.R ├── app-driver-timeout.R ├── app-driver-upload-file.R ├── app-driver-variant.R ├── app-driver-wait.R ├── app-driver-window.R ├── app-driver.R ├── chromote-methods.R ├── compare-screenshot-threshold.R ├── cpp11.R ├── expect-snapshot.R ├── expr-recurse.R ├── httr.R ├── migrate.R ├── missing-value.R ├── platform.R ├── record-test-unique-name.R ├── record-test.R ├── rstudio.R ├── save-app.R ├── shiny-browser.R ├── shinytest2-logs.R ├── shinytest2-package.R ├── test-app.R ├── use.R └── utils.R ├── README.md ├── actions └── test-app │ ├── License │ ├── README.Rmd │ ├── README.md │ ├── action.yml │ ├── example-test-app-description.yaml │ ├── example-test-app-package.yaml │ └── example-test-app-renv.yaml ├── cran-comments.md ├── inst ├── WORDLIST ├── example │ └── imgs │ │ ├── bookmark-diff.png │ │ ├── bookmark-new.png │ │ ├── bookmark-old.png │ │ ├── slider-diff.png │ │ ├── slider-new.png │ │ └── slider-old.png ├── gha │ ├── audit-app.R │ └── audit-app.yaml ├── internal │ ├── app-template.R │ ├── js │ │ └── shiny-tracer.js │ ├── recorder │ │ ├── app.R │ │ ├── recorder.js │ │ └── www │ │ │ ├── exit-nosave.png │ │ │ ├── exit-save.png │ │ │ ├── inject-recorder.js │ │ │ ├── recorder.css │ │ │ ├── shiny.png │ │ │ └── snapshot.png │ └── template │ │ ├── test-shinytest2.R │ │ ├── testthat.R │ │ └── unused │ │ └── DESCRIPTION └── vig-apps │ └── non-optimized-app │ └── app.R ├── logo ├── shinytest2.png └── shinytest2.svg ├── man ├── AppDriver.Rd ├── compare_screenshot_threshold.Rd ├── figures │ └── logo.svg ├── load_app_env.Rd ├── migrate_from_shinytest.Rd ├── platform_variant.Rd ├── record_test.Rd ├── register_input_processor.Rd ├── test_app.Rd └── use_shinytest2.Rd ├── pkgdown ├── _pkgdown.yml └── favicon │ ├── apple-touch-icon-120x120.png │ ├── apple-touch-icon-152x152.png │ ├── apple-touch-icon-180x180.png │ ├── apple-touch-icon-60x60.png │ ├── apple-touch-icon-76x76.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ └── favicon.ico ├── revdep ├── .gitignore ├── README.md ├── cran.md ├── failures.md └── problems.md ├── shinytest2.Rproj ├── src ├── .gitignore ├── code.cpp └── cpp11.cpp ├── tests ├── spelling.R ├── testthat.R └── testthat │ ├── _snaps │ ├── app-expect-file-transform.md │ └── app-expect-file-transform │ │ ├── 001-download-button.txt │ │ ├── 002.json │ │ └── 002_.png │ ├── app-files │ └── bear.png │ ├── apps │ ├── README.md │ ├── bookmark │ │ ├── app.R │ │ └── tests │ │ │ ├── testthat.R │ │ │ └── testthat │ │ │ ├── _snaps │ │ │ └── bookmark │ │ │ │ ├── 001.json │ │ │ │ └── 001_.png │ │ │ ├── setup-shinytest2.R │ │ │ └── test-bookmark.R │ ├── dir-profile │ │ ├── .Rprofile │ │ ├── app.R │ │ └── tests │ │ │ ├── testthat.R │ │ │ └── testthat │ │ │ ├── setup-shinytest2.R │ │ │ └── test-shinytest2.R │ ├── download │ │ ├── app.R │ │ ├── bear.png │ │ └── tests │ │ │ ├── testthat.R │ │ │ └── testthat │ │ │ ├── _snaps │ │ │ ├── app-download.md │ │ │ └── app-download │ │ │ │ ├── 001-download-link.txt │ │ │ │ ├── 002-download-button.txt │ │ │ │ ├── 003-download-link.csv │ │ │ │ ├── 004-download-button.csv │ │ │ │ ├── 005-bear.png │ │ │ │ ├── 006-bear.png │ │ │ │ └── 007-my_custom_name.txt │ │ │ ├── setup.R │ │ │ └── test-app-download.R │ ├── export │ │ ├── app.R │ │ └── tests │ │ │ ├── testthat.R │ │ │ └── testthat │ │ │ ├── setup.R │ │ │ └── test-app-export.R │ ├── files-app-rmd │ │ ├── app.R │ │ ├── index.Rmd │ │ └── tests │ │ │ ├── testthat.R │ │ │ └── testthat │ │ │ ├── setup.R │ │ │ └── test-shinytest2.R │ ├── files-app-server │ │ ├── app.R │ │ ├── server.R │ │ ├── tests │ │ │ ├── testthat.R │ │ │ └── testthat │ │ │ │ ├── setup.R │ │ │ │ └── test-shinytest2.R │ │ └── ui.R │ ├── files-server-ui │ │ ├── server.R │ │ ├── tests │ │ │ ├── testthat.R │ │ │ └── testthat │ │ │ │ ├── _snaps │ │ │ │ └── shinytest2 │ │ │ │ │ ├── kgs-001.json │ │ │ │ │ └── kgs-001_.png │ │ │ │ ├── setup-shinytest2.R │ │ │ │ └── test-shinytest2.R │ │ └── ui.R │ ├── hello │ │ ├── app.R │ │ └── tests │ │ │ ├── testthat.R │ │ │ └── testthat │ │ │ ├── _snaps │ │ │ ├── app-click │ │ │ │ ├── 001.json │ │ │ │ ├── 001_.png │ │ │ │ ├── 002.json │ │ │ │ └── 002_.png │ │ │ ├── app-init-args │ │ │ │ ├── test-001.json │ │ │ │ └── test-custom.json │ │ │ ├── app-variant │ │ │ │ ├── 001.json │ │ │ │ └── 001_.png │ │ │ ├── execute-js.md │ │ │ └── mac-4.1 │ │ │ │ ├── app.md │ │ │ │ └── app │ │ │ │ ├── 001.png │ │ │ │ ├── 002.json │ │ │ │ ├── 002_.png │ │ │ │ ├── 003.json │ │ │ │ ├── 003_.png │ │ │ │ └── manual-screenshot.png │ │ │ ├── js │ │ │ ├── execute-js.js │ │ │ ├── expect-js.js │ │ │ └── one-plus-one.js │ │ │ ├── setup.R │ │ │ ├── test-app-click.R │ │ │ ├── test-app-init-args.R │ │ │ ├── test-app-variant.R │ │ │ ├── test-app.R │ │ │ └── test-execute-js.R │ ├── image │ │ ├── app.R │ │ ├── bear.png │ │ └── tests │ │ │ ├── testthat.R │ │ │ └── testthat │ │ │ ├── _snaps │ │ │ ├── image │ │ │ │ ├── no-pic1-001.json │ │ │ │ ├── no-pic2-001.json │ │ │ │ ├── sa-user-001.json │ │ │ │ ├── sa-user-001_.png │ │ │ │ ├── sa-values-001.json │ │ │ │ ├── sa-values-001_.png │ │ │ │ ├── screen1-001.png │ │ │ │ └── screen2-001.png │ │ │ └── mac-4.1 │ │ │ │ └── image │ │ │ │ ├── 001.json │ │ │ │ ├── 001_.png │ │ │ │ ├── 002.json │ │ │ │ └── 002_.png │ │ │ ├── setup.R │ │ │ └── test-image.R │ ├── logs │ │ ├── app.R │ │ └── tests │ │ │ ├── testthat.R │ │ │ └── testthat │ │ │ ├── setup.R │ │ │ └── test-logs.R │ ├── plotly │ │ ├── app.R │ │ └── tests │ │ │ ├── testthat.R │ │ │ └── testthat │ │ │ ├── _snaps │ │ │ └── plotly │ │ │ │ └── 001.json │ │ │ ├── setup.R │ │ │ └── test-plotly.R │ ├── qmd │ │ ├── .gitignore │ │ ├── not-index.qmd │ │ └── tests │ │ │ ├── testthat.R │ │ │ └── testthat │ │ │ ├── _snaps │ │ │ └── quarto │ │ │ │ ├── 001.json │ │ │ │ └── 001_.png │ │ │ ├── setup.R │ │ │ └── test-quarto.R │ ├── rmd-not-shiny │ │ ├── report.Rmd │ │ ├── server.R │ │ ├── tests │ │ │ ├── testthat.R │ │ │ └── testthat │ │ │ │ ├── setup.R │ │ │ │ └── test-ignore-regular-rmd.R │ │ └── ui.R │ ├── rmd-pre │ │ ├── .gitignore │ │ ├── not-index.Rmd │ │ └── tests │ │ │ ├── testthat.R │ │ │ └── testthat │ │ │ ├── _snaps │ │ │ └── prerendered │ │ │ │ ├── 001.json │ │ │ │ └── 001_.png │ │ │ ├── setup.R │ │ │ └── test-prerendered.R │ ├── rmd-shiny │ │ ├── not-index.Rmd │ │ └── tests │ │ │ ├── testthat.R │ │ │ └── testthat │ │ │ ├── _snaps │ │ │ └── rmd │ │ │ │ ├── 001.json │ │ │ │ └── 001_.png │ │ │ ├── setup.R │ │ │ └── test-rmd.R │ ├── robust-ex │ │ ├── app.R │ │ └── tests │ │ │ ├── testthat.R │ │ │ └── testthat │ │ │ ├── _snaps │ │ │ ├── export-long │ │ │ │ ├── cars-points-10.svg │ │ │ │ └── cars-points-20.svg │ │ │ └── export-short │ │ │ │ ├── cars-points-10.svg │ │ │ │ └── cars-points-20.svg │ │ │ ├── setup.R │ │ │ ├── test-export-long.R │ │ │ └── test-export-short.R │ ├── stop │ │ ├── app.R │ │ └── tests │ │ │ ├── testthat.R │ │ │ └── testthat │ │ │ ├── setup.R │ │ │ └── test-stop.R │ ├── task-button │ │ ├── app.R │ │ └── tests │ │ │ ├── testthat.R │ │ │ └── testthat │ │ │ ├── setup-shinytest2.R │ │ │ └── test-bslib-task-btn.R │ ├── text_html │ │ ├── app.R │ │ └── tests │ │ │ ├── testthat.R │ │ │ └── testthat │ │ │ ├── _snaps │ │ │ └── expect-snapshot-js.md │ │ │ ├── setup.R │ │ │ └── test-expect-snapshot-js.R │ ├── update │ │ ├── app.R │ │ └── tests │ │ │ ├── testthat.R │ │ │ └── testthat │ │ │ ├── _snaps │ │ │ └── shinytest2 │ │ │ │ ├── click-001.json │ │ │ │ ├── click-001_.png │ │ │ │ ├── no-binding-001.json │ │ │ │ └── no-binding-001_.png │ │ │ ├── setup.R │ │ │ └── test-shinytest2.R │ ├── upload-multi │ │ ├── app.R │ │ └── tests │ │ │ ├── testthat.R │ │ │ └── testthat │ │ │ ├── _snaps │ │ │ └── app-upload-multi │ │ │ │ ├── upload-multi-001.json │ │ │ │ └── upload-multi-001_.png │ │ │ ├── cars.csv │ │ │ ├── cars_2.csv │ │ │ ├── setup.R │ │ │ └── test-app-upload-multi.R │ ├── upload │ │ ├── app.R │ │ └── tests │ │ │ ├── testthat.R │ │ │ └── testthat │ │ │ ├── _snaps │ │ │ └── app-upload │ │ │ │ ├── upload-001.json │ │ │ │ └── upload-001_.png │ │ │ ├── cars.csv │ │ │ ├── setup.R │ │ │ └── test-app-upload.R │ ├── wait-setup │ │ ├── R │ │ │ └── n.R │ │ ├── app.R │ │ └── tests │ │ │ ├── testthat.R │ │ │ └── testthat │ │ │ ├── setup.R │ │ │ └── test-wait-for-idle.R │ ├── wait │ │ ├── R │ │ │ └── n.R │ │ ├── app.R │ │ └── tests │ │ │ ├── testthat.R │ │ │ └── testthat │ │ │ ├── setup-shinytest2.R │ │ │ ├── test-get-value.R │ │ │ └── test-wait-for-idle.R │ ├── widgits │ │ ├── app.R │ │ └── tests │ │ │ ├── testthat.R │ │ │ └── testthat │ │ │ ├── _snaps │ │ │ └── app-set-inputs │ │ │ │ ├── 001.json │ │ │ │ ├── 001_.png │ │ │ │ ├── 002.json │ │ │ │ ├── 002_.png │ │ │ │ ├── 003.json │ │ │ │ ├── 003_.png │ │ │ │ ├── 004.json │ │ │ │ └── 004_.png │ │ │ ├── setup.R │ │ │ └── test-app-set-inputs.R │ └── window │ │ ├── app.R │ │ └── tests │ │ ├── testthat.R │ │ └── testthat │ │ ├── setup.R │ │ └── test-window-size.R │ ├── helper-migration-env.R │ ├── migrate-apps │ ├── 10 │ │ ├── app.R │ │ └── tests │ │ │ ├── shinytest.R │ │ │ └── shinytest │ │ │ ├── mytest-expected-mac-4.0 │ │ │ ├── 001.json │ │ │ ├── 001.png │ │ │ ├── 002.download │ │ │ ├── 003.json │ │ │ ├── 003.png │ │ │ ├── 004.json │ │ │ ├── 004.png │ │ │ └── 005.download │ │ │ └── mytest.R │ ├── 01 │ │ ├── app.R │ │ └── tests │ │ │ ├── shinytest.R │ │ │ └── shinytest │ │ │ ├── comments-only.R │ │ │ ├── empty-file.R │ │ │ ├── mytest-expected-mac │ │ │ ├── 001.json │ │ │ ├── 001.png │ │ │ ├── 002.json │ │ │ ├── 002.png │ │ │ ├── 003.json │ │ │ └── 003.png │ │ │ ├── mytest.R │ │ │ ├── othertest-expected │ │ │ ├── 001.json │ │ │ ├── 001.png │ │ │ ├── 002.json │ │ │ ├── 002.png │ │ │ ├── 003.json │ │ │ └── 003.png │ │ │ └── othertest.R │ ├── 01ex │ │ ├── app.R │ │ └── tests │ │ │ ├── testthat.R │ │ │ └── testthat │ │ │ ├── _snaps │ │ │ ├── mac │ │ │ │ └── mytest │ │ │ │ │ ├── 001.json │ │ │ │ │ ├── 002.png │ │ │ │ │ ├── 003.json │ │ │ │ │ ├── 004.png │ │ │ │ │ ├── 005.json │ │ │ │ │ └── 006.png │ │ │ └── othertest │ │ │ │ ├── 001.json │ │ │ │ ├── 002.png │ │ │ │ ├── 003.json │ │ │ │ ├── 004.png │ │ │ │ ├── 005.json │ │ │ │ └── 006.png │ │ │ ├── test-comments-only.R │ │ │ ├── test-empty-file.R │ │ │ ├── test-mytest.R │ │ │ └── test-othertest.R │ ├── 02 │ │ ├── app.R │ │ └── tests │ │ │ ├── shinytest.R │ │ │ └── shinytest │ │ │ ├── mytest-expected-mac-4.0 │ │ │ ├── 001.json │ │ │ ├── 001.png │ │ │ ├── 002.json │ │ │ └── 002.png │ │ │ ├── mytest-expected-mac-4.1 │ │ │ ├── 001.json │ │ │ ├── 001.png │ │ │ ├── 002.json │ │ │ └── 002.png │ │ │ └── mytest.R │ ├── 02ex │ │ ├── app.R │ │ └── tests │ │ │ ├── testthat.R │ │ │ └── testthat │ │ │ ├── _snaps │ │ │ ├── mac-4.0 │ │ │ │ └── mytest │ │ │ │ │ ├── 001.json │ │ │ │ │ ├── 002.png │ │ │ │ │ ├── 003.json │ │ │ │ │ └── 004.png │ │ │ └── mac-4.1 │ │ │ │ └── mytest │ │ │ │ ├── 001.json │ │ │ │ ├── 002.png │ │ │ │ ├── 003.json │ │ │ │ └── 004.png │ │ │ └── test-mytest.R │ ├── 05 │ │ ├── app.R │ │ └── tests │ │ │ ├── shinytest.R │ │ │ ├── shinytest │ │ │ ├── mytest-expected-mac-4.0 │ │ │ │ ├── 001.json │ │ │ │ ├── 001.png │ │ │ │ ├── 002.json │ │ │ │ └── 002.png │ │ │ └── mytest.R │ │ │ ├── testthat.R │ │ │ └── testthat │ │ │ └── test-shiny.R │ ├── 05ex │ │ ├── app.R │ │ └── tests │ │ │ ├── testthat.R │ │ │ └── testthat │ │ │ ├── _snaps │ │ │ └── mac-4.0 │ │ │ │ └── mytest │ │ │ │ ├── 001.json │ │ │ │ ├── 002.png │ │ │ │ ├── 003.json │ │ │ │ └── 004.png │ │ │ ├── test-mytest.R │ │ │ └── test-shiny.R │ ├── 08 │ │ ├── app.R │ │ ├── tests │ │ │ ├── shinytest.R │ │ │ └── shinytest │ │ │ │ ├── mytest-expected-mac-4.0 │ │ │ │ ├── 001.json │ │ │ │ └── 001.png │ │ │ │ └── mytest.R │ │ └── www │ │ │ └── index.html │ ├── 08ex │ │ ├── app.R │ │ ├── tests │ │ │ ├── testthat.R │ │ │ └── testthat │ │ │ │ ├── _snaps │ │ │ │ └── mac-4.0 │ │ │ │ │ └── mytest │ │ │ │ │ ├── 001.json │ │ │ │ │ └── 002.png │ │ │ │ └── test-mytest.R │ │ └── www │ │ │ └── index.html │ ├── 09 │ │ ├── app.R │ │ └── tests │ │ │ ├── shinytest.R │ │ │ └── shinytest │ │ │ ├── Rock.csv │ │ │ ├── mytest-expected-mac-4.0 │ │ │ ├── 001.json │ │ │ ├── 001.png │ │ │ ├── 002.json │ │ │ └── 002.png │ │ │ ├── mytest.R │ │ │ └── other │ │ │ └── Rock.csv │ ├── 09ex │ │ ├── app.R │ │ └── tests │ │ │ ├── testthat.R │ │ │ └── testthat │ │ │ ├── Rock.csv │ │ │ ├── _snaps │ │ │ └── mac-4.0 │ │ │ │ └── mytest │ │ │ │ ├── 001.json │ │ │ │ ├── 002.png │ │ │ │ ├── 003.json │ │ │ │ └── 004.png │ │ │ ├── other │ │ │ └── Rock.csv │ │ │ └── test-mytest.R │ └── 10ex │ │ ├── app.R │ │ └── tests │ │ ├── testthat.R │ │ └── testthat │ │ ├── _snaps │ │ └── mac-4.0 │ │ │ └── mytest │ │ │ ├── 001.json │ │ │ ├── 002.png │ │ │ ├── 003.download │ │ │ ├── 004.json │ │ │ ├── 005.png │ │ │ ├── 006.json │ │ │ ├── 007.png │ │ │ └── 008.download │ │ └── test-mytest.R │ ├── scripts │ ├── issue_295.R │ ├── issue_303.R │ └── pr_307.R │ ├── setup-disable-crashpad.R │ ├── test-app-duplicate-ids.R │ ├── test-app-eval-js.R │ ├── test-app-expect-file-transform.R │ ├── test-app-screenshot-size.R │ ├── test-app-shiny.R │ ├── test-app-stop.R │ ├── test-app-timeout.R │ ├── test-apps.R │ ├── test-image-diff.R │ ├── test-known-names.R │ ├── test-migration-file.R │ ├── test-migration-migrate.R │ ├── test-migration-transformation.R │ ├── test-not-testing.R │ ├── test-save-app.R │ ├── test-shinytest2.R │ ├── test-test-app-reporter.R │ ├── test-url.R │ └── test-use.R ├── todo.md └── vignettes ├── .gitignore ├── images ├── diffviewer-1.png ├── gremlins-attack-refined.gif ├── gremlins-attack.gif ├── gremlins-inject.png ├── gremlins-logs.png ├── gremlins-slider-handle.png ├── gremlins-start.png ├── plot-app.png ├── record-name.png ├── record-simple-app-2.png ├── record-simple-app.png ├── screenshot-exports-app.png ├── screenshot-recorder-random-seed.png ├── shinytest2-loadtest.png └── shinytest2-shinyloadtest-optimized.png ├── in-depth.Rmd ├── robust.Rmd ├── shinytest2.Rmd ├── simple-app ├── app.R └── tests │ ├── testthat.R │ └── testthat │ ├── _snaps │ └── shinytest2 │ │ ├── simple-app-001.json │ │ ├── simple-app-001.new.json │ │ ├── simple-app-001_.new.png │ │ └── simple-app-001_.png │ └── test-shinytest2.R ├── use-application-audit.Rmd ├── use-ci.Rmd ├── use-package.Rmd ├── using-monkey-testing.Rmd ├── z-migration.Rmd └── zzz-faq.Rmd /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^LICENSE\.md$ 2 | ^\.github$ 3 | .Rproj$ 4 | todo.md 5 | ^.*\.Rproj$ 6 | ^\.Rproj\.user$ 7 | ^man-roxygen$ 8 | ^\.lintr$ 9 | 10 | ^docs$ 11 | ^logo$ 12 | ^pkgdown$ 13 | _\.new\.png$ 14 | ^actions$ 15 | ^doc$ 16 | ^Meta$ 17 | ^cran-comments\.md$ 18 | ^revdep$ 19 | ^.vscode$ 20 | 21 | ^tests/testthat/migrate-apps$ 22 | ^tests/testthat/apps$ 23 | ^CRAN-SUBMISSION$ 24 | ^_dev$ 25 | -------------------------------------------------------------------------------- /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /.github/shiny-workflows/routine.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | Rscript -e 'rmarkdown::render("actions/test-app/README.Rmd")' 3 | git add -A actions/test-app/README.md && \ 4 | git commit -m '`rmarkdown::render("actions/test-app/README.Rmd")` (GitHub Actions)' || \ 5 | echo "No changes found in actions/test-app/README.md" 6 | -------------------------------------------------------------------------------- /.github/workflows/R-CMD-check.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/rstudio/shiny-workflows 2 | # 3 | # NOTE: This Shiny team GHA workflow is overkill for most R packages. 4 | # For most R packages it is better to use https://github.com/r-lib/actions 5 | on: 6 | push: 7 | branches: [main, rc-**] 8 | pull_request: 9 | branches: [main] 10 | schedule: 11 | - cron: '0 8 * * 1' # every monday 12 | 13 | name: Package checks 14 | 15 | jobs: 16 | website: 17 | uses: rstudio/shiny-workflows/.github/workflows/website.yaml@v1 18 | routine: 19 | uses: rstudio/shiny-workflows/.github/workflows/routine.yaml@v1 20 | R-CMD-check: 21 | uses: rstudio/shiny-workflows/.github/workflows/R-CMD-check.yaml@v1 22 | with: 23 | cache-version: "4" 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | 6 | docs 7 | # {shinytest2}: Ignore new debug snapshots for `$expect_values()` 8 | *_.new.png 9 | inst/doc 10 | /doc/ 11 | /Meta/ 12 | -------------------------------------------------------------------------------- /.lintr: -------------------------------------------------------------------------------- 1 | linters: linters_with_defaults( 2 | line_length_linter = NULL, 3 | indentation_linter = NULL, 4 | commented_code_linter = NULL, 5 | return_linter = NULL 6 | ) 7 | exclusions: list( 8 | "inst/gha/audit-app.R" = list( 9 | "object_usage_linter" = 81 10 | ), 11 | "R/cpp11.R" 12 | ) 13 | -------------------------------------------------------------------------------- /.vscode/c_cpp_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "Mac", 5 | "includePath": [ 6 | "${workspaceFolder}/**", 7 | "/Library/Frameworks/R.framework/Resources/include", 8 | "/Library/Frameworks/R.framework/Versions/Current/Resources/library/cpp11/include" 9 | ], 10 | "defines": [], 11 | "macFrameworkPath": [ 12 | "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks" 13 | ], 14 | "compilerPath": "/usr/bin/clang", 15 | "cStandard": "c99", 16 | "cppStandard": "c++11", 17 | "intelliSenseMode": "macos-clang-x64" 18 | } 19 | ], 20 | "version": 4 21 | } 22 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "vector": "cpp" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2021 2 | COPYRIGHT HOLDER: shinytest2 authors 3 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright (c) 2021 shinytest2 authors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method(format,shinytest2_log) 4 | S3method(print,shinytest2_log) 5 | export(AppDriver) 6 | export(compare_screenshot_threshold) 7 | export(get_input_processors) 8 | export(load_app_env) 9 | export(migrate_from_shinytest) 10 | export(platform_variant) 11 | export(record_test) 12 | export(register_input_processor) 13 | export(screenshot_max_difference) 14 | export(test_app) 15 | export(use_shinytest2) 16 | export(use_shinytest2_test) 17 | importFrom(R6,R6Class) 18 | importFrom(callr,process) 19 | importFrom(cli,col_blue) 20 | importFrom(cli,col_cyan) 21 | importFrom(cli,col_green) 22 | importFrom(cli,col_magenta) 23 | importFrom(cli,col_red) 24 | importFrom(cli,col_silver) 25 | importFrom(cli,make_ansi_style) 26 | importFrom(lifecycle,deprecated) 27 | importFrom(rlang,"%||%") 28 | importFrom(rlang,":=") 29 | importFrom(rlang,list2) 30 | importFrom(rlang,missing_arg) 31 | importFrom(testthat,default_reporter) 32 | useDynLib(shinytest2, .registration = TRUE) 33 | -------------------------------------------------------------------------------- /R/R6-helper.R: -------------------------------------------------------------------------------- 1 | 2 | Count <- R6Class( # nolint 3 | "Count", 4 | private = list( 5 | count = 0 6 | ), 7 | public = list( 8 | increment = function() { 9 | private$count <- private$count + 1 10 | private$count 11 | }, 12 | get = function() { 13 | private$count 14 | } 15 | ) 16 | ) 17 | 18 | app_next_temp_snapshot_path <- function( 19 | self, private, 20 | name, # full path or filename 21 | ext = "json" 22 | ) { 23 | ckm8_assert_app_driver(self, private) 24 | 25 | fs::path( 26 | private$save_dir, 27 | # set the file extension 28 | fs::path_ext_set( 29 | # take file name only 30 | fs::path_file( 31 | name %||% sprintf("%03d", private$counter$increment()) 32 | ), 33 | ext 34 | ) 35 | ) 36 | } 37 | 38 | 39 | Url <- R6Class( # nolint 40 | "Url", 41 | private = list( 42 | url = NULL 43 | ), 44 | public = list( 45 | get = function() { 46 | private$url 47 | }, 48 | set = function(url) { 49 | res <- httr::parse_url(url) 50 | 51 | checkmate::assert_subset(res$scheme, c("http", "https"), .var.name = "url scheme") 52 | 53 | if (!is.null(res$port)) { 54 | res$port <- as.integer(res$port) 55 | ckm8_assert_single_integer(res$port, .var.name = "url port") 56 | } 57 | 58 | ckm8_assert_single_string(res$hostname, .var.name = "url hostname") 59 | 60 | private$url <- httr::build_url(res) 61 | 62 | invisible(self) 63 | } 64 | ) 65 | ) 66 | -------------------------------------------------------------------------------- /R/app-driver-chromote.R: -------------------------------------------------------------------------------- 1 | app_get_chromote_session <- function(self, private) { 2 | ckm8_assert_app_driver(self, private) 3 | 4 | private$chromote_session 5 | } 6 | 7 | app_view <- function(self, private) { 8 | ckm8_assert_app_driver(self, private) 9 | self$log_message("Viewing chromote session") 10 | 11 | self$get_chromote_session()$view() 12 | } 13 | -------------------------------------------------------------------------------- /R/app-driver-log-message.R: -------------------------------------------------------------------------------- 1 | 2 | app_log_message <- function(self, private, message) { 3 | app_add_log_entry(self, private, location = "shinytest2", level = "info", message = message) 4 | } 5 | 6 | 7 | 8 | app_log_entry <- function( 9 | self, 10 | private, 11 | location = c("chromote", "shiny", "shinytest2"), 12 | level, 13 | message, 14 | timestamp = Sys.time() 15 | ) { 16 | ckm8_assert_app_driver(self, private) 17 | ckm8_assert_single_string(level) 18 | ckm8_assert_single_string(message) 19 | checkmate::assert_posixct(timestamp) 20 | 21 | entry <- data.frame( 22 | workerid = private$shiny_worker_id, 23 | timestamp = timestamp, 24 | location = match.arg(location), 25 | # do not match on a fixed set to allow console.trace() methods to work in browser. 26 | level, 27 | message = message, 28 | stringsAsFactors = FALSE 29 | ) 30 | # message("Making entry: ") 31 | # str(entry) 32 | entry 33 | } 34 | app_add_log_entry <- function( 35 | self, 36 | private, 37 | location, 38 | level, 39 | message, 40 | timestamp = Sys.time() 41 | ) { 42 | ckm8_assert_app_driver(self, private) 43 | 44 | 45 | entry <- app_log_entry( 46 | self, private, 47 | location = location, 48 | level = level, 49 | message = message, 50 | timestamp = timestamp 51 | ) 52 | 53 | 54 | private$logs[[length(private$logs) + 1]] <- entry 55 | 56 | invisible(entry) 57 | } 58 | -------------------------------------------------------------------------------- /R/app-driver-message.R: -------------------------------------------------------------------------------- 1 | app_warn <- function(self, private, ...) { 2 | ckm8_assert_app_driver(self, private) 3 | rlang::warn(..., app = self) 4 | } 5 | app_inform <- function(self, private, ...) { 6 | ckm8_assert_app_driver(self, private) 7 | rlang::inform(..., app = self) 8 | } 9 | app_abort <- function(self, private, ..., call = rlang::caller_env()) { 10 | ckm8_assert_app_driver(self, private) 11 | rlang::abort(..., app = self, call = call) 12 | } 13 | -------------------------------------------------------------------------------- /R/app-driver-variant.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | app_is_missing_variant <- function(self, private) { 4 | ckm8_assert_app_driver(self, private) 5 | is_missing_value(private$variant) 6 | } 7 | 8 | 9 | # Return NULL if the variant is missing 10 | app_get_variant <- function(self, private) { 11 | ckm8_assert_app_driver(self, private) 12 | 13 | variant <- private$variant 14 | if (is_missing_value(variant)) { 15 | NULL 16 | } else { 17 | variant 18 | } 19 | } 20 | 21 | 22 | app_set_variant <- function(self, private, variant) { 23 | ckm8_assert_app_driver(self, private) 24 | 25 | if (is_missing_value(variant)) { 26 | variant <- missing_value() 27 | } else { 28 | if (identical(variant, FALSE)) { 29 | variant <- NULL 30 | } 31 | } 32 | 33 | private$variant <- variant 34 | variant 35 | } 36 | -------------------------------------------------------------------------------- /R/app-driver-window.R: -------------------------------------------------------------------------------- 1 | app_set_window_size <- function(self, private, width, height, wait = TRUE) { 2 | "!DEBUG app_set_window_size() `width`x`height`" 3 | ckm8_assert_app_driver(self, private) 4 | 5 | self$log_message(paste0( 6 | "Setting window size to `", width, "`x`", height, "`" 7 | )) 8 | 9 | chromote_set_window_size(self$get_chromote_session(), width = width, height = height) 10 | 11 | if (isTRUE(wait)) { 12 | self$wait_for_idle() 13 | } 14 | # # Support this? No. Can manually call `app$wait_for_idle()` themselves 15 | # else if (is.list(wait)) { 16 | # rlang::eval_tidy(self$wait_for_idle(!!!wait)) 17 | # } 18 | invisible(self) 19 | } 20 | 21 | app_get_window_size <- function(self, private) { 22 | "!DEBUG app_get_window_size()" 23 | ckm8_assert_app_driver(self, private) 24 | 25 | viewport <- self$get_chromote_session()$Page$getLayoutMetrics()$cssLayoutViewport 26 | list( 27 | width = viewport$clientWidth, 28 | height = viewport$clientHeight 29 | ) 30 | } 31 | -------------------------------------------------------------------------------- /R/cpp11.R: -------------------------------------------------------------------------------- 1 | # Generated by cpp11: do not edit by hand 2 | 3 | image_diff_convolution_max_value <- function(diff_matrix, kernel_size) { 4 | .Call(`_shinytest2_image_diff_convolution_max_value`, diff_matrix, kernel_size) 5 | } 6 | -------------------------------------------------------------------------------- /R/expr-recurse.R: -------------------------------------------------------------------------------- 1 | expr_recurse <- function(expr, post_fn) { 2 | expr_recurse_ <- function(expr, post_fn, is_top_level = FALSE) { 3 | if (!is.language(expr)) { 4 | return(expr) 5 | } 6 | expr_list <- as.list(expr) 7 | 8 | if ( 9 | # Return early if it is a single item 10 | length(expr_list) == 1 && 11 | # Make sure not something like `app$getAllValues()` 12 | is.language(expr_list[[1]]) && 13 | length(expr_list[[1]]) == 1 14 | ) { 15 | return(expr) 16 | } 17 | for (i in seq_len(length(expr_list))) { 18 | val <- expr_recurse_(expr_list[[i]], post_fn, is_top_level = FALSE) 19 | # Support the setting of `NULL` values 20 | expr_list[i] <- list(val) 21 | } 22 | 23 | # By being after the for-loop, it alters from the leaf to the trunk 24 | post_fn(expr_list, is_top_level) 25 | } 26 | # Shim `is_top_level = TRUE` 27 | expr_recurse_(expr = expr, post_fn = post_fn, is_top_level = TRUE) 28 | } 29 | 30 | 31 | st2_expr_text <- function(expr) { 32 | if (is.null(expr) || is.character(expr)) return(expr) 33 | if (is.list(expr)) return(lapply(expr, st2_expr_text)) 34 | gsub( 35 | "\\s*\n ", 36 | "\n ", 37 | rlang::expr_text(expr, width = 60L) 38 | ) 39 | } 40 | for_each_expr_text <- function(exprs, expr_fn, ...) { 41 | unlist(lapply(exprs, function(expr) { 42 | st2_expr_text(expr_fn(expr, ...)) 43 | })) 44 | } 45 | -------------------------------------------------------------------------------- /R/httr.R: -------------------------------------------------------------------------------- 1 | app_httr_get <- function(self, private, url, fn_404 = NULL) { 2 | ckm8_assert_app_driver(self, private) 3 | 4 | pieces <- httr::parse_url(url) 5 | # Add in port information if it's missing 6 | # https://github.com/rstudio/shinytest2/issues/158 7 | if (is.null(pieces$port)) { 8 | pieces$port <- switch(pieces$scheme, "http" = 80, "https" = 443) 9 | } 10 | 11 | if (!pingr::is_up(pieces$hostname, pieces$port, check_online = FALSE)) { 12 | app_abort(self, private, "Could not find Shiny server. Shiny app is no longer running") 13 | } 14 | 15 | withCallingHandlers( # abort() on error 16 | { # nolint 17 | req <- httr::GET(url) 18 | }, 19 | # Attempt to capture empty reply error and provide better message 20 | error = function(e) { 21 | if (grepl("Empty reply from server", as.character(e), fixed = TRUE)) { 22 | app_abort(self, private, "Empty reply received from Shiny server. Shiny app is no longer running", parent = e) 23 | } 24 | # Unknown error, rethrow 25 | app_abort(self, private, e) 26 | } 27 | ) 28 | 29 | status <- httr::status_code(req) 30 | if (status == 200) { 31 | return(req) 32 | } 33 | if (status == 404 && is.function(fn_404)) { 34 | return(fn_404(req)) 35 | } 36 | 37 | cat("{shinytest2} query failed (", status, ")----------------------\n", sep = "") 38 | cat("URL: ", url, "\n", sep = "") 39 | cat(httr::content(req, "text"), "\n") 40 | cat("----------------------------------------\n") 41 | app_abort(self, private, "Unable request data from server") 42 | } 43 | -------------------------------------------------------------------------------- /R/missing-value.R: -------------------------------------------------------------------------------- 1 | # Note: `missing_value()` is used as it can be printed by `R6`, where as `rlang::missing_arg()` can not be printed. 2 | # If any `AppDriver` objects need to hold onto a `rlang::missing_arg()`, `missing_value()` should be used instead. 3 | 4 | # Basic missing value structure 5 | missing_value <- function() { 6 | structure(list(), class = "shinytest2_missing_value") 7 | } 8 | # Handle rlang::missing_arg() values too! 9 | is_missing_value <- function(value) { 10 | rlang::is_missing(value) || inherits(value, "shinytest2_missing_value") 11 | } 12 | 13 | # Mimic `rlang::maybe_missing()` 14 | # Handle rlang::missing_arg() values too! 15 | maybe_missing_value <- function(value, default = missing_value()) { 16 | if (is_missing_value(value)) { 17 | default 18 | } else { 19 | value 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /R/record-test-unique-name.R: -------------------------------------------------------------------------------- 1 | # Also used in recorder 2 | known_app_driver_name_values <- function(test_file) { 3 | 4 | exprs <- parse(file = test_file) 5 | 6 | is_appdriver_new <- function(expr_list) { 7 | length(expr_list) >= 1 && 8 | is.language(expr_list[[1]]) && 9 | st2_expr_text(expr_list[[1]]) %in% c( 10 | "AppDriver$new", 11 | "shinytest2::AppDriver$new", 12 | "shinytest2:::AppDriver$new" 13 | ) 14 | } 15 | 16 | known_names <- list() 17 | post_fn <- function(expr_list, is_top_level) { 18 | if (is_appdriver_new(expr_list)) { 19 | args <- rlang::call_args( 20 | rlang::call_match( 21 | as.call(expr_list), 22 | AppDriver$public_methods$initialize 23 | ) 24 | ) 25 | 26 | new_name <- args$name 27 | if ( 28 | is.null(new_name) || # allow `NULL` 29 | rlang::is_scalar_character(new_name) # allow single character value 30 | # Do not allow symbols or language expressions 31 | ) { 32 | # Allows the collecting of NULL name values 33 | known_names[length(known_names) + 1] <<- list(new_name) 34 | } 35 | } 36 | # Don't alter the expr_list, just return it 37 | as.call(expr_list) 38 | } 39 | # For all exprs, find a single shinytest::testApp() 40 | lapply(exprs, function(expr) { 41 | expr_recurse(expr, post_fn = post_fn) 42 | }) 43 | 44 | known_names 45 | } 46 | -------------------------------------------------------------------------------- /R/rstudio.R: -------------------------------------------------------------------------------- 1 | rstudio_is_available <- function() { 2 | rlang::check_installed("rstudioapi") 3 | rstudioapi::isAvailable() 4 | } 5 | -------------------------------------------------------------------------------- /R/shinytest2-package.R: -------------------------------------------------------------------------------- 1 | #' @useDynLib shinytest2, .registration = TRUE 2 | NULL 3 | 4 | release_bullets <- function() { 5 | c( 6 | "Is the `actions/test-app` sliding tag up-to-date? Check both `v1` and `actions/v1`." 7 | ) 8 | } 9 | -------------------------------------------------------------------------------- /actions/test-app/License: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | ===================== 3 | 4 | Copyright © 2021 RStudio and others. 5 | 6 | Permission is hereby granted, free of charge, to any person 7 | obtaining a copy of this software and associated documentation 8 | files (the “Software”), to deal in the Software without 9 | restriction, including without limitation the rights to use, 10 | copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the 12 | Software is furnished to do so, subject to the following 13 | conditions: 14 | 15 | The above copyright notice and this permission notice shall be 16 | included in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25 | OTHER DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /actions/test-app/example-test-app-description.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/rstudio/shinytest2/tree/main/actions/test-app/example-test-app-description.yaml 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | 9 | name: Test app w/ DESCRIPTION 10 | 11 | jobs: 12 | test-app: 13 | runs-on: ${{ matrix.config.os }} 14 | 15 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 16 | 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | config: 21 | - {os: ubuntu-latest, r: release} 22 | 23 | env: 24 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 25 | R_KEEP_PKG_SOURCE: yes 26 | 27 | steps: 28 | - uses: actions/checkout@v2 29 | 30 | - uses: r-lib/actions/setup-pandoc@v2 31 | 32 | - uses: r-lib/actions/setup-r@v2 33 | with: 34 | r-version: ${{ matrix.config.r }} 35 | http-user-agent: ${{ matrix.config.http-user-agent }} 36 | use-public-rspm: true 37 | 38 | - uses: r-lib/actions/setup-r-dependencies@v2 39 | with: 40 | extra-packages: 41 | shinytest2 42 | 43 | - uses: rstudio/shinytest2/actions/test-app@actions/v1 44 | with: 45 | app-dir: "." 46 | -------------------------------------------------------------------------------- /actions/test-app/example-test-app-package.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/rstudio/shinytest2/tree/main/actions/test-app/example-test-app-package.yaml 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | 9 | name: Test package app 10 | 11 | jobs: 12 | test-package-app: 13 | runs-on: ${{ matrix.config.os }} 14 | 15 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 16 | 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | config: 21 | - {os: ubuntu-latest, r: release} 22 | 23 | env: 24 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 25 | R_KEEP_PKG_SOURCE: yes 26 | 27 | steps: 28 | - uses: actions/checkout@v2 29 | 30 | - uses: r-lib/actions/setup-pandoc@v2 31 | 32 | - uses: r-lib/actions/setup-r@v2 33 | with: 34 | r-version: ${{ matrix.config.r }} 35 | http-user-agent: ${{ matrix.config.http-user-agent }} 36 | use-public-rspm: true 37 | 38 | - uses: r-lib/actions/setup-r-dependencies@v2 39 | with: 40 | extra-packages: 41 | local::. 42 | shinytest2 43 | 44 | - uses: rstudio/shinytest2/actions/test-app@actions/v1 45 | with: 46 | app-dir: "." 47 | -------------------------------------------------------------------------------- /actions/test-app/example-test-app-renv.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/rstudio/shinytest2/tree/main/actions/test-app/example-test-app-renv.yaml 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | 9 | name: Test app w/ {renv} 10 | 11 | jobs: 12 | test-app: 13 | runs-on: ${{ matrix.config.os }} 14 | 15 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 16 | 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | config: 21 | - {os: ubuntu-latest, r: release} 22 | 23 | env: 24 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 25 | R_KEEP_PKG_SOURCE: yes 26 | 27 | steps: 28 | - uses: actions/checkout@v2 29 | 30 | - uses: r-lib/actions/setup-pandoc@v2 31 | 32 | - uses: r-lib/actions/setup-r@v2 33 | with: 34 | r-version: ${{ matrix.config.r }} 35 | http-user-agent: ${{ matrix.config.http-user-agent }} 36 | use-public-rspm: true 37 | 38 | - uses: r-lib/actions/setup-renv@v2 39 | 40 | - uses: rstudio/shinytest2/actions/test-app@actions/v1 41 | with: 42 | app-dir: "." 43 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | ## CRAN comments 2 | 3 | #### 2025-04-11 4 | 5 | Critical bug to user interface fixed. 6 | 7 | I am sorry for the fast turn around. 8 | 9 | - Barret 10 | 11 | 12 | ## R CMD check results 13 | 14 | 0 errors | 0 warnings | 1 note 15 | 16 | * checking CRAN incoming feasibility ... [11s] NOTE 17 | Maintainer: 'Barret Schloerke ' 18 | 19 | Days since last update: 1 20 | 21 | ## revdepcheck results 22 | 23 | We checked 54 reverse dependencies, comparing R CMD check results across CRAN and dev versions of this package. 24 | 25 | * We saw 0 new problems 26 | * We failed to check 0 packages 27 | -------------------------------------------------------------------------------- /inst/WORDLIST: -------------------------------------------------------------------------------- 1 | AppDriver 2 | CDN 3 | CMD 4 | CRAN's 5 | Chromote 6 | DOI 7 | DOM 8 | DT 9 | DataTable 10 | Devtools 11 | GHA 12 | JS 13 | JSON 14 | Lifecycle 15 | POSIXct 16 | PhantomJS 17 | Prerendered 18 | README 19 | RGBA 20 | RStudio 21 | Rmd 22 | Shiny's 23 | Shinyapps 24 | UI 25 | WebSocket 26 | ci 27 | config 28 | der 29 | dir 30 | doubletap 31 | erroring 32 | ession 33 | flexdashboard 34 | htmlwidgets 35 | iframe 36 | incrementing 37 | ing 38 | io 39 | javascript 40 | js 41 | lintr 42 | lockfile 43 | md 44 | milli 45 | mogwais 46 | myfile 47 | plotly 48 | preprocessor 49 | prerendered 50 | prerendering 51 | programmatically 52 | reactives 53 | renderer 54 | renv 55 | repo 56 | reproducibility 57 | scrollable 58 | selectize 59 | serializable 60 | shinyapps 61 | shinycannon 62 | shinytest 63 | testthat 64 | usethis 65 | websocket 66 | yaml 67 | -------------------------------------------------------------------------------- /inst/example/imgs/bookmark-diff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/inst/example/imgs/bookmark-diff.png -------------------------------------------------------------------------------- /inst/example/imgs/bookmark-new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/inst/example/imgs/bookmark-new.png -------------------------------------------------------------------------------- /inst/example/imgs/bookmark-old.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/inst/example/imgs/bookmark-old.png -------------------------------------------------------------------------------- /inst/example/imgs/slider-diff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/inst/example/imgs/slider-diff.png -------------------------------------------------------------------------------- /inst/example/imgs/slider-new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/inst/example/imgs/slider-new.png -------------------------------------------------------------------------------- /inst/example/imgs/slider-old.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/inst/example/imgs/slider-old.png -------------------------------------------------------------------------------- /inst/internal/app-template.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | `_data` <- readRDS("data.rds") # nolint 4 | 5 | lapply(`_data`$packages, library, character.only = TRUE) 6 | for (prefix in names(`_data`$resources)) { 7 | shiny::addResourcePath(prefix, `_data`$resources[[prefix]]) 8 | } 9 | 10 | # cat("attaching globals: ", paste0(names(`_data`$globals), collapse = ", "), "\n", sep = "") 11 | 12 | # Assign to global environment so that everything is available to each other 13 | # `list2env(x, envir=globalenv())` is equivalent to multiple calls to `assign(names(x)[[i]], x[[i]], envir = globalenv())` 14 | list2env(`_data`$globals, envir = globalenv()) # nolint 15 | 16 | shinyApp(`_data`$ui, `_data`$server) 17 | -------------------------------------------------------------------------------- /inst/internal/recorder/www/exit-nosave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/inst/internal/recorder/www/exit-nosave.png -------------------------------------------------------------------------------- /inst/internal/recorder/www/exit-save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/inst/internal/recorder/www/exit-save.png -------------------------------------------------------------------------------- /inst/internal/recorder/www/shiny.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/inst/internal/recorder/www/shiny.png -------------------------------------------------------------------------------- /inst/internal/recorder/www/snapshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/inst/internal/recorder/www/snapshot.png -------------------------------------------------------------------------------- /inst/internal/template/test-shinytest2.R: -------------------------------------------------------------------------------- 1 | library(shinytest2) 2 | 3 | test_that("Initial Shiny values are consistent", { 4 | app <- AppDriver$new() 5 | 6 | app$expect_values() 7 | }) 8 | -------------------------------------------------------------------------------- /inst/internal/template/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /inst/internal/template/unused/DESCRIPTION: -------------------------------------------------------------------------------- 1 | Type: Shiny 2 | Version: 0.0.1 3 | Config/testthat/edition: 3 4 | -------------------------------------------------------------------------------- /inst/vig-apps/non-optimized-app/app.R: -------------------------------------------------------------------------------- 1 | library(deSolve) 2 | library(shiny) 3 | 4 | van_der_pol <- function(t, y, mu) { 5 | d_x <- y[2] 6 | d_y <- mu * (1 - y[1] ^ 2) * y[2] - y[1] 7 | list(c(X = d_x, Y = d_y)) 8 | } 9 | 10 | server <- function(input, output) { 11 | output$brussels <- renderPlot({ 12 | y0 <- c(X = input$X, Y = input$Y) 13 | # Not necessary to set .001 but to induce longer calculation 14 | times <- seq(0, 1000, .001) 15 | out <- ode(y0, times, van_der_pol, input$mu) 16 | par(mfrow = c(1, 1)) 17 | plot(out[, 2:3], type = "l", xlab = "X", ylab = "Y", main = "state diagram") 18 | }) 19 | } 20 | 21 | ui <- fluidPage( 22 | headerPanel("Van der Pol oscillator"), 23 | sidebarLayout( 24 | sidebarPanel( 25 | h3("Init values"), 26 | numericInput("X", label = "X", min = 0.0, max = 5, value = 1, step = 0.2), 27 | numericInput("Y", label = "Y", min = 0.0, max = 5, value = 1, step = 0.2), 28 | 29 | h3("Parameters"), 30 | numericInput("mu", label = "mu", min = 0.0, max = 5, value = 1, step = 0.1) 31 | ), 32 | mainPanel( 33 | h3("Simulation results"), 34 | plotOutput("brussels") 35 | ) 36 | ) 37 | ) 38 | 39 | shinyApp(ui = ui, server = server) 40 | -------------------------------------------------------------------------------- /logo/shinytest2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/logo/shinytest2.png -------------------------------------------------------------------------------- /man/load_app_env.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/test-app.R 3 | \name{load_app_env} 4 | \alias{load_app_env} 5 | \title{Load the Shiny application's support environment} 6 | \usage{ 7 | load_app_env( 8 | app_dir = "../../", 9 | renv = rlang::caller_env(), 10 | globalrenv = rlang::caller_env() 11 | ) 12 | } 13 | \arguments{ 14 | \item{app_dir}{The base directory for the Shiny application.} 15 | 16 | \item{renv}{The environment in which the files in the `R/`` directory should be evaluated.} 17 | 18 | \item{globalrenv}{The environment in which \code{global.R} should be evaluated. If 19 | \code{NULL}, \code{global.R} will not be evaluated at all.} 20 | } 21 | \description{ 22 | Executes all \code{./R} files and \code{global.R} into the current environment. 23 | This is useful when wanting access to functions or values created in the \code{./R} folder for testing purposes. 24 | } 25 | \details{ 26 | Loading these files is not automatically performed by \code{test_app()} and must 27 | be called in \code{./tests/testthat/setup-shinytest2.R} if access to support file objects is 28 | desired. 29 | } 30 | \seealso{ 31 | \code{\link[=use_shinytest2]{use_shinytest2()}} for creating a testing setup file that 32 | loads your Shiny app support environment into the testing environment. 33 | } 34 | -------------------------------------------------------------------------------- /man/migrate_from_shinytest.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/migrate.R 3 | \name{migrate_from_shinytest} 4 | \alias{migrate_from_shinytest} 5 | \title{Migrate \pkg{shinytest} tests} 6 | \usage{ 7 | migrate_from_shinytest( 8 | app_dir, 9 | ..., 10 | clean = TRUE, 11 | include_expect_screenshot = missing_arg(), 12 | quiet = FALSE 13 | ) 14 | } 15 | \arguments{ 16 | \item{app_dir}{Directory containing the Shiny application or Shiny Rmd file} 17 | 18 | \item{...}{Must be empty. Allows for parameter expansion.} 19 | 20 | \item{clean}{If TRUE, then the shinytest test directory and runner will be deleted after the migration to use \pkg{shinytest2}.} 21 | 22 | \item{include_expect_screenshot}{If \code{TRUE}, \code{ShinyDriver$snapshot()} will turn into both \code{AppDriver$expect_values()} and \code{AppDriver$expect_screenshot()}. If \code{FALSE}, \code{ShinyDriver$snapshot()} will only turn into \code{AppDriver$expect_values()}. If missing, \code{include_expect_screenshot} will behave as \code{FALSE} if \code{shinytest::testApp(compareImages = FALSE)} or \code{ShinyDriver$snapshotInit(screenshot = FALSE)} is called.} 23 | 24 | \item{quiet}{Logical that determines if migration information and steps should be printed to the console.} 25 | } 26 | \value{ 27 | Invisible \code{TRUE} 28 | } 29 | \description{ 30 | This function will migrate standard shinytest test files to the new \pkg{shinytest2} + \pkg{testthat} ed 3 snapshot format. 31 | } 32 | \details{ 33 | \pkg{shinytest} file contents will be traversed and converted to the new \pkg{shinytest2} format. If the \pkg{shinytest} code can not be directly seen in the code, then it will not be converted. 34 | } 35 | -------------------------------------------------------------------------------- /man/platform_variant.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/platform.R 3 | \name{platform_variant} 4 | \alias{platform_variant} 5 | \title{Platform specific variant} 6 | \usage{ 7 | platform_variant(..., os_name = TRUE, r_version = TRUE) 8 | } 9 | \arguments{ 10 | \item{...}{Must be empty. Allows for parameter expansion.} 11 | 12 | \item{os_name}{if \code{TRUE}, include the OS name in the output} 13 | 14 | \item{r_version}{if \code{TRUE}, include the major and minor version of the R version, no patch version} 15 | } 16 | \description{ 17 | Returns a string to be used within \pkg{testthat}'s' snapshot testing. Currently, the Operating System 18 | and R Version (major, minor, no patch version) are returned. 19 | } 20 | \details{ 21 | If more information is needed in the future to distinguish standard testing environments, this function 22 | will be updated accordingly. 23 | } 24 | \seealso{ 25 | \code{\link[testthat:test_dir]{testthat::test_dir()}} 26 | } 27 | -------------------------------------------------------------------------------- /man/register_input_processor.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/record-test.R 3 | \name{register_input_processor} 4 | \alias{register_input_processor} 5 | \alias{get_input_processors} 6 | \title{Register an input processor for the test recorder} 7 | \usage{ 8 | register_input_processor(input_type, processor) 9 | 10 | get_input_processors() 11 | } 12 | \arguments{ 13 | \item{input_type}{The name of an input type, for example, 14 | \code{"mypkg.numberinput"}.} 15 | 16 | \item{processor}{An input processor function.} 17 | } 18 | \description{ 19 | \code{register_input_processor()} registers an input processor which will be used by 20 | the test recorder. The input processor function should take one parameter, 21 | \code{value}, and return a string of R code which returns the desired value. 22 | 23 | \code{get_input_processors()} returns a named list of all registered input processor 24 | functions. 25 | } 26 | \keyword{internal} 27 | -------------------------------------------------------------------------------- /pkgdown/_pkgdown.yml: -------------------------------------------------------------------------------- 1 | url: https://rstudio.github.io/shinytest2/ 2 | 3 | # development: 4 | # mode: auto 5 | 6 | template: 7 | package: tidytemplate 8 | bootstrap: 5 9 | 10 | bslib: 11 | primary: "#A51D21" 12 | # https://mdigi.tools/lighten-color/#a51d21 @ 92% 13 | navbar-background: "#fbe9ea" 14 | trailing_slash_redirect: true 15 | 16 | 17 | reference: 18 | - title: Making tests 19 | desc: ~ 20 | contents: 21 | - AppDriver 22 | - record_test 23 | - platform_variant 24 | - compare_screenshot_threshold 25 | 26 | - title: Running tests 27 | desc: ~ 28 | contents: 29 | - test_app 30 | - load_app_env 31 | 32 | - title: Setting up tests 33 | desc: ~ 34 | contents: 35 | - use_shinytest2 36 | - use_shinytest2_test 37 | 38 | - title: Migrating tests 39 | desc: ~ 40 | contents: 41 | - migrate_from_shinytest 42 | -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/pkgdown/favicon/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/pkgdown/favicon/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/pkgdown/favicon/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/pkgdown/favicon/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/pkgdown/favicon/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/pkgdown/favicon/apple-touch-icon.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/pkgdown/favicon/favicon-16x16.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/pkgdown/favicon/favicon-32x32.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/pkgdown/favicon/favicon.ico -------------------------------------------------------------------------------- /revdep/.gitignore: -------------------------------------------------------------------------------- 1 | checks 2 | library 3 | checks.noindex 4 | library.noindex 5 | cloud.noindex 6 | data.sqlite 7 | *.html 8 | -------------------------------------------------------------------------------- /revdep/README.md: -------------------------------------------------------------------------------- 1 | # Revdeps 2 | 3 | -------------------------------------------------------------------------------- /revdep/cran.md: -------------------------------------------------------------------------------- 1 | ## revdepcheck results 2 | 3 | We checked 54 reverse dependencies, comparing R CMD check results across CRAN and dev versions of this package. 4 | 5 | * We saw 0 new problems 6 | * We failed to check 0 packages 7 | 8 | -------------------------------------------------------------------------------- /revdep/failures.md: -------------------------------------------------------------------------------- 1 | *Wow, no problems at all. :)* -------------------------------------------------------------------------------- /revdep/problems.md: -------------------------------------------------------------------------------- 1 | *Wow, no problems at all. :)* -------------------------------------------------------------------------------- /shinytest2.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | PackageRoxygenize: rd,collate,namespace 22 | -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.so 3 | *.dll 4 | -------------------------------------------------------------------------------- /src/cpp11.cpp: -------------------------------------------------------------------------------- 1 | // Generated by cpp11: do not edit by hand 2 | // clang-format off 3 | 4 | 5 | #include "cpp11/declarations.hpp" 6 | #include 7 | 8 | // code.cpp 9 | double image_diff_convolution_max_value(cpp11::doubles_matrix diff_matrix, int kernel_size); 10 | extern "C" SEXP _shinytest2_image_diff_convolution_max_value(SEXP diff_matrix, SEXP kernel_size) { 11 | BEGIN_CPP11 12 | return cpp11::as_sexp(image_diff_convolution_max_value(cpp11::as_cpp>>(diff_matrix), cpp11::as_cpp>(kernel_size))); 13 | END_CPP11 14 | } 15 | 16 | extern "C" { 17 | static const R_CallMethodDef CallEntries[] = { 18 | {"_shinytest2_image_diff_convolution_max_value", (DL_FUNC) &_shinytest2_image_diff_convolution_max_value, 2}, 19 | {NULL, NULL, 0} 20 | }; 21 | } 22 | 23 | extern "C" attribute_visible void R_init_shinytest2(DllInfo* dll){ 24 | R_registerRoutines(dll, NULL, CallEntries, NULL, NULL); 25 | R_useDynamicSymbols(dll, FALSE); 26 | R_forceSymbols(dll, TRUE); 27 | } 28 | -------------------------------------------------------------------------------- /tests/spelling.R: -------------------------------------------------------------------------------- 1 | 2 | if (requireNamespace("spelling", quietly = TRUE)) { 3 | spelling::spell_check_test( 4 | vignettes = TRUE, 5 | error = FALSE, 6 | skip_on_cran = TRUE 7 | ) 8 | } 9 | -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(shinytest2) 3 | 4 | test_check("shinytest2") 5 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/app-expect-file-transform.md: -------------------------------------------------------------------------------- 1 | # transform can be passed to expect_snapshot_file() 2 | 3 | "download-button.txt" 4 | 5 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/app-expect-file-transform/001-download-button.txt: -------------------------------------------------------------------------------- 1 | Download content! 2 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/app-expect-file-transform/002.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | 4 | }, 5 | "output": { 6 | "txt": "(app loaded)" 7 | }, 8 | "export": { 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/app-expect-file-transform/002_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/_snaps/app-expect-file-transform/002_.png -------------------------------------------------------------------------------- /tests/testthat/app-files/bear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/app-files/bear.png -------------------------------------------------------------------------------- /tests/testthat/apps/README.md: -------------------------------------------------------------------------------- 1 | > Note: Folders have short names to fit 100 char path limit 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/bookmark/app.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | ui <- function(request) { 4 | fluidPage( 5 | textInput("txt", "Enter text"), 6 | checkboxInput("caps", "Capitalize"), 7 | verbatimTextOutput("out"), 8 | bookmarkButton() 9 | ) 10 | } 11 | server <- function(input, output, session) { 12 | output$out <- renderText({ 13 | if (input$caps) { 14 | toupper(input$txt) 15 | } else { 16 | input$txt 17 | } 18 | }) 19 | } 20 | 21 | shinyApp(ui, server, enableBookmarking = "url") 22 | -------------------------------------------------------------------------------- /tests/testthat/apps/bookmark/tests/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/bookmark/tests/testthat/_snaps/bookmark/001.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "._bookmark_": 0, 4 | "caps": true, 5 | "txt": "abcd" 6 | }, 7 | "output": { 8 | "out": "ABCD" 9 | }, 10 | "export": { 11 | 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/testthat/apps/bookmark/tests/testthat/_snaps/bookmark/001_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/apps/bookmark/tests/testthat/_snaps/bookmark/001_.png -------------------------------------------------------------------------------- /tests/testthat/apps/bookmark/tests/testthat/setup-shinytest2.R: -------------------------------------------------------------------------------- 1 | # Load application support files into testing environment 2 | shinytest2::load_app_env() 3 | -------------------------------------------------------------------------------- /tests/testthat/apps/bookmark/tests/testthat/test-bookmark.R: -------------------------------------------------------------------------------- 1 | library(shinytest2) 2 | 3 | test_that("Bookmark works", { 4 | # Start local app in the background in test mode 5 | bg_app <- shinytest2::AppDriver$new() 6 | 7 | # Capture the background app's URL and add appropriate query parameters 8 | bookmark_url <- paste0(bg_app$get_url(), "?_inputs_&txt=%22abcd%22&caps=true") 9 | # Open the bookmark URL in a new AppDriver object 10 | app <- shinytest2::AppDriver$new(bookmark_url) 11 | 12 | # Run your tests on the bookmarked `app` 13 | app$expect_values() 14 | ## File: _snaps/bookmark/001.json 15 | # { 16 | # "input": { 17 | # "._bookmark_": 0, 18 | # "caps": true, 19 | # "txt": "abcd" 20 | # }, 21 | # "output": { 22 | # "out": "ABCD" 23 | # }, 24 | # "export": { 25 | # 26 | # } 27 | # } 28 | }) 29 | -------------------------------------------------------------------------------- /tests/testthat/apps/dir-profile/.Rprofile: -------------------------------------------------------------------------------- 1 | shinytest2_profile_value <- "found!" 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/dir-profile/app.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | txt_val <- get0("shinytest2_profile_value", ifnotfound = "Not found! 😔😭") 4 | 5 | ui <- fluidPage( 6 | "This app must be run in a clean R session that is started in the same directory as the app.R file.", 7 | textOutput("txt"), 8 | ) 9 | server <- function(input, output, session) { 10 | output$txt <- renderText(txt_val) 11 | } 12 | 13 | shinyApp(ui, server) 14 | -------------------------------------------------------------------------------- /tests/testthat/apps/dir-profile/tests/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/dir-profile/tests/testthat/setup-shinytest2.R: -------------------------------------------------------------------------------- 1 | # Load application support files into testing environment 2 | shinytest2::load_app_env() 3 | -------------------------------------------------------------------------------- /tests/testthat/apps/dir-profile/tests/testthat/test-shinytest2.R: -------------------------------------------------------------------------------- 1 | library(shinytest2) 2 | 3 | test_that("{shinytest2} recording: dir-profile", { 4 | app <- AppDriver$new(name = "dir-profile", height = 1133, width = 1282) 5 | 6 | expect_equal( 7 | app$get_value(output = "txt"), 8 | "found!" 9 | ) 10 | }) 11 | -------------------------------------------------------------------------------- /tests/testthat/apps/download/bear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/apps/download/bear.png -------------------------------------------------------------------------------- /tests/testthat/apps/download/tests/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/download/tests/testthat/_snaps/app-download.md: -------------------------------------------------------------------------------- 1 | # download files work from link and button 2 | 3 | "download-link.txt" 4 | 5 | --- 6 | 7 | "download-button.txt" 8 | 9 | --- 10 | 11 | "download-link.csv" 12 | 13 | --- 14 | 15 | "download-button.csv" 16 | 17 | --- 18 | 19 | "bear.png" 20 | 21 | --- 22 | 23 | "bear.png" 24 | 25 | --- 26 | 27 | "download-button.txt" 28 | 29 | -------------------------------------------------------------------------------- /tests/testthat/apps/download/tests/testthat/_snaps/app-download/001-download-link.txt: -------------------------------------------------------------------------------- 1 | Download content! 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/download/tests/testthat/_snaps/app-download/002-download-button.txt: -------------------------------------------------------------------------------- 1 | Download content! 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/download/tests/testthat/_snaps/app-download/003-download-link.csv: -------------------------------------------------------------------------------- 1 | "","speed","dist" 2 | "41",20,52 3 | "42",20,56 4 | "43",20,64 5 | "44",22,66 6 | "45",23,54 7 | "46",24,70 8 | "47",24,92 9 | "48",24,93 10 | "49",24,120 11 | "50",25,85 12 | -------------------------------------------------------------------------------- /tests/testthat/apps/download/tests/testthat/_snaps/app-download/004-download-button.csv: -------------------------------------------------------------------------------- 1 | "","speed","dist" 2 | "1",4,2 3 | "2",4,10 4 | "3",7,4 5 | "4",7,22 6 | "5",8,16 7 | "6",9,10 8 | "7",10,18 9 | "8",10,26 10 | "9",10,34 11 | "10",11,17 12 | -------------------------------------------------------------------------------- /tests/testthat/apps/download/tests/testthat/_snaps/app-download/005-bear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/apps/download/tests/testthat/_snaps/app-download/005-bear.png -------------------------------------------------------------------------------- /tests/testthat/apps/download/tests/testthat/_snaps/app-download/006-bear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/apps/download/tests/testthat/_snaps/app-download/006-bear.png -------------------------------------------------------------------------------- /tests/testthat/apps/download/tests/testthat/_snaps/app-download/007-my_custom_name.txt: -------------------------------------------------------------------------------- 1 | Download content! 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/download/tests/testthat/setup.R: -------------------------------------------------------------------------------- 1 | shinytest2::load_app_env() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/export/app.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | shinyApp( 4 | ui = basicPage( 5 | h4("Snapshot URL: "), 6 | uiOutput("url"), 7 | h4("Current values:"), 8 | verbatimTextOutput("values"), 9 | actionButton("inc", "Increment x") 10 | ), 11 | 12 | server = function(input, output, session) { 13 | vals <- reactiveValues(x = 1) 14 | y <- reactive({ 15 | vals$x + 1 16 | }) 17 | 18 | observeEvent(input$inc, { 19 | vals$x <<- vals$x + 1 20 | }) 21 | 22 | exportTestValues( 23 | x = vals$x, 24 | y = y() 25 | ) 26 | 27 | output$url <- renderUI({ 28 | url <- session$getTestSnapshotUrl(format = "json") 29 | a(href = url, url) 30 | }) 31 | 32 | output$values <- renderText({ 33 | paste0("vals$x: ", vals$x, "\ny: ", y()) 34 | }) 35 | } 36 | ) 37 | -------------------------------------------------------------------------------- /tests/testthat/apps/export/tests/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/export/tests/testthat/setup.R: -------------------------------------------------------------------------------- 1 | shinytest2::load_app_env() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/export/tests/testthat/test-app-export.R: -------------------------------------------------------------------------------- 1 | 2 | test_that("Exported values", { 3 | app <- AppDriver$new() 4 | 5 | x <- app$get_values() 6 | expect_identical(x$export$x, 1) 7 | expect_identical(x$export$y, 2) 8 | 9 | app$set_inputs(inc = "click") 10 | app$set_inputs(inc = "click") 11 | 12 | x <- app$get_values() 13 | expect_identical(x$export$x, 3) 14 | expect_identical(x$export$y, 4) 15 | }) 16 | -------------------------------------------------------------------------------- /tests/testthat/apps/files-app-rmd/app.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | ui <- fluidPage( 4 | textInput("name", "What is your name?"), 5 | actionButton("greet", "Greet"), 6 | textOutput("greeting"), 7 | tags$br(), 8 | # consistenly sized box and consistent across OS 9 | tags$div( 10 | id = "custom_div", 11 | style = "width: 100px;height: 100px;" 12 | ) 13 | ) 14 | server <- function(input, output, session) { 15 | output$greeting <- renderText({ 16 | shiny::req(input$greet) 17 | paste0("Hello ", shiny::isolate(input$name), "!") 18 | }) 19 | } 20 | 21 | shinyApp(ui, server) 22 | -------------------------------------------------------------------------------- /tests/testthat/apps/files-app-rmd/index.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Shiny RMD template" 3 | output: html_document 4 | runtime: shiny 5 | --- 6 | 7 | ```{r setup, include=FALSE} 8 | knitr::opts_chunk$set(echo = TRUE) 9 | ``` 10 | 11 | This R Markdown document is made interactive using Shiny. Unlike the more traditional workflow of creating static reports, you can now create documents that allow your readers to change the assumptions underlying your analysis and see the results immediately. 12 | 13 | To learn more, see [Interactive Documents](http://rmarkdown.rstudio.com/authoring_shiny.html). 14 | 15 | ## Inputs and Outputs 16 | 17 | You can embed Shiny inputs and outputs in your document. Outputs are automatically updated whenever inputs change. This demonstrates how a standard R plot can be made interactive by wrapping it in the Shiny `renderPlot` function. The `selectInput` and `sliderInput` functions create the input widgets used to drive the plot. 18 | 19 | ```{r eruptions, echo=FALSE} 20 | inputPanel( 21 | # selectInput("n_breaks", label = "Number of bins:", 22 | # choices = c(10, 20, 35, 50), selected = 20), 23 | 24 | sliderInput("bw_adjust", label = "Bandwidth adjustment:", 25 | min = 0.2, max = 2, value = 1, step = 0.2) 26 | ) 27 | 28 | output$plot <- renderPlot({ 29 | hist(faithful$eruptions, probability = TRUE, breaks = 20, # as.numeric(input$n_breaks), 30 | xlab = "Duration (minutes)", main = "Geyser eruption duration") 31 | 32 | dens <- density(faithful$eruptions, adjust = input$bw_adjust) 33 | lines(dens, col = "blue") 34 | }) 35 | plotOutput("plot") 36 | ``` 37 | -------------------------------------------------------------------------------- /tests/testthat/apps/files-app-rmd/tests/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/files-app-rmd/tests/testthat/setup.R: -------------------------------------------------------------------------------- 1 | shinytest2::load_app_env() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/files-app-rmd/tests/testthat/test-shinytest2.R: -------------------------------------------------------------------------------- 1 | library(shinytest2) 2 | 3 | test_that("rmarkdown and app.R are not compatible", { 4 | expect_error( 5 | AppDriver$new(), 6 | "`app_dir` must be a directory containing", 7 | fixed = TRUE 8 | ) 9 | }) 10 | -------------------------------------------------------------------------------- /tests/testthat/apps/files-app-server/app.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | ui <- fluidPage( 4 | textInput("name", "What is your name?"), 5 | actionButton("greet", "Greet"), 6 | textOutput("greeting"), 7 | tags$br(), 8 | # consistenly sized box and consistent across OS 9 | tags$div( 10 | id = "custom_div", 11 | style = "width: 100px;height: 100px;" 12 | ) 13 | ) 14 | server <- function(input, output, session) { 15 | output$greeting <- renderText({ 16 | shiny::req(input$greet) 17 | paste0("Hello ", shiny::isolate(input$name), "!") 18 | }) 19 | } 20 | 21 | shinyApp(ui, server) 22 | -------------------------------------------------------------------------------- /tests/testthat/apps/files-app-server/server.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | 4 | function(input, output, session) { 5 | output$greeting <- renderText({ 6 | shiny::req(input$greet) 7 | paste0("Hello ", shiny::isolate(input$name), "!") 8 | }) 9 | } 10 | -------------------------------------------------------------------------------- /tests/testthat/apps/files-app-server/tests/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/files-app-server/tests/testthat/setup.R: -------------------------------------------------------------------------------- 1 | shinytest2::load_app_env() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/files-app-server/tests/testthat/test-shinytest2.R: -------------------------------------------------------------------------------- 1 | library(shinytest2) 2 | 3 | test_that("server.R and app.R are not compatible", { 4 | expect_error( 5 | AppDriver$new()$stop(), 6 | "Unintented behavior may occur", 7 | fixed = TRUE 8 | ) 9 | }) 10 | -------------------------------------------------------------------------------- /tests/testthat/apps/files-app-server/ui.R: -------------------------------------------------------------------------------- 1 | fluidPage( 2 | textInput("name", "What is your name?"), 3 | actionButton("greet", "Greet"), 4 | textOutput("greeting"), 5 | tags$br(), 6 | # consistenly sized box and consistent across OS 7 | tags$div( 8 | id = "custom_div", 9 | style = "width: 100px;height: 100px;" 10 | ) 11 | ) 12 | -------------------------------------------------------------------------------- /tests/testthat/apps/files-server-ui/server.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | server <- function(input, output, session) { 4 | output$g <- renderText(paste0("Weight (in g): ", input$kg * 1000)) 5 | } 6 | -------------------------------------------------------------------------------- /tests/testthat/apps/files-server-ui/tests/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/files-server-ui/tests/testthat/_snaps/shinytest2/kgs-001.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "kg": 100 4 | }, 5 | "output": { 6 | "g": "Weight (in g): 1e+05" 7 | }, 8 | "export": { 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/testthat/apps/files-server-ui/tests/testthat/_snaps/shinytest2/kgs-001_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/apps/files-server-ui/tests/testthat/_snaps/shinytest2/kgs-001_.png -------------------------------------------------------------------------------- /tests/testthat/apps/files-server-ui/tests/testthat/setup-shinytest2.R: -------------------------------------------------------------------------------- 1 | # Load application support files into testing environment 2 | shinytest2::load_app_env() 3 | -------------------------------------------------------------------------------- /tests/testthat/apps/files-server-ui/tests/testthat/test-shinytest2.R: -------------------------------------------------------------------------------- 1 | library(shinytest2) 2 | 3 | test_that("{shinytest2} recording: kgs", { 4 | app <- AppDriver$new(name = "kgs", height = 1321, width = 1221) 5 | app$set_inputs(kg = 100) 6 | app$expect_values() 7 | }) 8 | -------------------------------------------------------------------------------- /tests/testthat/apps/files-server-ui/ui.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | ui <- fluidPage( 4 | titlePanel("Convert kilograms to grams"), 5 | p("From", a(href = "https://github.com/rstudio/shinytest2/issues/244", "Issue #244")), 6 | numericInput("kg", "Weight (in kg)", value = 0), 7 | textOutput("g") 8 | ) 9 | -------------------------------------------------------------------------------- /tests/testthat/apps/hello/app.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | ui <- fluidPage( 4 | textInput("name", "What is your name?"), 5 | actionButton("greet", "Greet"), 6 | textOutput("greeting"), 7 | tags$br(), 8 | # consistenly sized box and consistent across OS 9 | tags$div( 10 | id = "custom_div", 11 | style = "width: 100px;height: 100px;" 12 | ) 13 | ) 14 | server <- function(input, output, session) { 15 | output$greeting <- renderText({ 16 | shiny::req(input$greet) 17 | paste0("Hello ", shiny::isolate(input$name), "!") 18 | }) 19 | } 20 | 21 | shinyApp(ui, server) 22 | -------------------------------------------------------------------------------- /tests/testthat/apps/hello/tests/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/hello/tests/testthat/_snaps/app-click/001.json: -------------------------------------------------------------------------------- 1 | { 2 | "output": { 3 | "greeting": "Hello Hadley!" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /tests/testthat/apps/hello/tests/testthat/_snaps/app-click/001_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/apps/hello/tests/testthat/_snaps/app-click/001_.png -------------------------------------------------------------------------------- /tests/testthat/apps/hello/tests/testthat/_snaps/app-click/002.json: -------------------------------------------------------------------------------- 1 | { 2 | "output": { 3 | "greeting": "Hello Barret!" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /tests/testthat/apps/hello/tests/testthat/_snaps/app-click/002_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/apps/hello/tests/testthat/_snaps/app-click/002_.png -------------------------------------------------------------------------------- /tests/testthat/apps/hello/tests/testthat/_snaps/app-init-args/test-001.json: -------------------------------------------------------------------------------- 1 | { 2 | "output": { 3 | "greeting": "Hello Hadley!" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /tests/testthat/apps/hello/tests/testthat/_snaps/app-init-args/test-custom.json: -------------------------------------------------------------------------------- 1 | { 2 | "output": { 3 | "greeting": "Hello Hadley!" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /tests/testthat/apps/hello/tests/testthat/_snaps/app-variant/001.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "greet": 1, 4 | "name": "Hadley" 5 | }, 6 | "output": { 7 | "greeting": "Hello Hadley!" 8 | }, 9 | "export": { 10 | 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/testthat/apps/hello/tests/testthat/_snaps/app-variant/001_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/apps/hello/tests/testthat/_snaps/app-variant/001_.png -------------------------------------------------------------------------------- /tests/testthat/apps/hello/tests/testthat/_snaps/execute-js.md: -------------------------------------------------------------------------------- 1 | # JS can take a file or script 2 | 3 | "testExpectJs" 4 | 5 | -------------------------------------------------------------------------------- /tests/testthat/apps/hello/tests/testthat/_snaps/mac-4.1/app.md: -------------------------------------------------------------------------------- 1 | # basic website example works using shinytest 2 | 3 | "Hello Hadley!" 4 | 5 | --- 6 | 7 | "
Hello Hadley!<\/div>" 8 | 9 | -------------------------------------------------------------------------------- /tests/testthat/apps/hello/tests/testthat/_snaps/mac-4.1/app/001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/apps/hello/tests/testthat/_snaps/mac-4.1/app/001.png -------------------------------------------------------------------------------- /tests/testthat/apps/hello/tests/testthat/_snaps/mac-4.1/app/002.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "greet": 1, 4 | "name": "Hadley" 5 | }, 6 | "output": { 7 | "greeting": "Hello Hadley!" 8 | }, 9 | "export": { 10 | 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/testthat/apps/hello/tests/testthat/_snaps/mac-4.1/app/002_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/apps/hello/tests/testthat/_snaps/mac-4.1/app/002_.png -------------------------------------------------------------------------------- /tests/testthat/apps/hello/tests/testthat/_snaps/mac-4.1/app/003.json: -------------------------------------------------------------------------------- 1 | { 2 | "output": { 3 | "greeting": "Hello Hadley!" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /tests/testthat/apps/hello/tests/testthat/_snaps/mac-4.1/app/003_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/apps/hello/tests/testthat/_snaps/mac-4.1/app/003_.png -------------------------------------------------------------------------------- /tests/testthat/apps/hello/tests/testthat/_snaps/mac-4.1/app/manual-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/apps/hello/tests/testthat/_snaps/mac-4.1/app/manual-screenshot.png -------------------------------------------------------------------------------- /tests/testthat/apps/hello/tests/testthat/js/execute-js.js: -------------------------------------------------------------------------------- 1 | window.testVal = "testFile"; 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/hello/tests/testthat/js/expect-js.js: -------------------------------------------------------------------------------- 1 | "testExpectJs"; 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/hello/tests/testthat/js/one-plus-one.js: -------------------------------------------------------------------------------- 1 | 1 + 1; 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/hello/tests/testthat/setup.R: -------------------------------------------------------------------------------- 1 | shinytest2::load_app_env() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/hello/tests/testthat/test-app-click.R: -------------------------------------------------------------------------------- 1 | test_that("basic website example works", { 2 | app <- AppDriver$new(variant = NULL) 3 | 4 | app$set_inputs(name = "Hadley") 5 | app$set_inputs(greet = "click") 6 | app$expect_values(output = "greeting") # Hadley 7 | app$set_inputs(name = "Barret") 8 | app$click("greet") 9 | app$expect_values(output = "greeting") # Barret 10 | 11 | 12 | # Track clicks on `#greeting` and `#custom_div` 13 | app$run_js(" 14 | window.greeting_count = 0; 15 | 16 | $('#greeting').click(function () { 17 | window.greeting_count += 1; 18 | }); 19 | ") 20 | app$run_js(" 21 | window.custom_count = 0; 22 | 23 | $('#custom_div').click(function () { 24 | window.custom_count += 1; 25 | }); 26 | ") 27 | 28 | expect_equal(app$get_js("window.greeting_count"), 0) 29 | expect_equal(app$get_js("window.custom_count"), 0) 30 | 31 | app$click(output = "greeting") 32 | app$click(output = "greeting") 33 | 34 | expect_equal(app$get_js("window.greeting_count"), 2) 35 | expect_equal(app$get_js("window.custom_count"), 0) 36 | 37 | app$click(selector = "#custom_div") 38 | app$click(selector = "#custom_div") 39 | app$click(selector = "#custom_div") 40 | 41 | expect_equal(app$get_js("window.greeting_count"), 2) 42 | expect_equal(app$get_js("window.custom_count"), 3) 43 | }) 44 | -------------------------------------------------------------------------------- /tests/testthat/apps/hello/tests/testthat/test-app-init-args.R: -------------------------------------------------------------------------------- 1 | test_that("name arg works", { 2 | app <- AppDriver$new( 3 | test_path("../../."), 4 | name = "test", 5 | variant = NULL 6 | ) 7 | 8 | app$set_inputs(name = "Hadley") 9 | app$set_inputs(greet = "click") 10 | app$expect_values(output = "greeting", screenshot_args = FALSE) 11 | app$expect_values(output = "greeting", screenshot_args = FALSE, name = "custom") 12 | }) 13 | -------------------------------------------------------------------------------- /tests/testthat/apps/hello/tests/testthat/test-app-variant.R: -------------------------------------------------------------------------------- 1 | # shinytest2 code using `app$**()`: 2 | test_that("screenshots need a variant", { 3 | app <- AppDriver$new() 4 | 5 | app$set_inputs(name = "Hadley") 6 | app$set_inputs(greet = "click") 7 | 8 | # Can save values. Variant acts like `NULL` 9 | app$expect_values() 10 | 11 | expect_error( 12 | app$expect_screenshot(), 13 | "can not call `$expect_screenshot()`", fixed = TRUE 14 | ) 15 | }) 16 | 17 | # Tests where the variant is supplied (both `NULL` and `platform_variant()`) are done in many other files. 18 | -------------------------------------------------------------------------------- /tests/testthat/apps/hello/tests/testthat/test-execute-js.R: -------------------------------------------------------------------------------- 1 | test_that("JS can take a file or script", { 2 | app <- AppDriver$new() 3 | 4 | app$set_inputs(name = "Hadley") 5 | app$run_js("window.testVal = 'testLocal';") 6 | expect_equal( 7 | app$get_js("window.testVal;"), 8 | "testLocal" 9 | ) 10 | 11 | app$run_js(file = test_path("js/execute-js.js")) 12 | expect_equal( 13 | app$get_js("window.testVal;"), 14 | "testFile" 15 | ) 16 | 17 | expect_equal( 18 | app$get_js(file = test_path("js/expect-js.js")), 19 | "testExpectJs" 20 | ) 21 | app$expect_js(file = test_path("js/expect-js.js")) 22 | 23 | expect_warning( 24 | app$get_js("1 + 1", file = test_path("js/one-plus-one.js")), 25 | "Both `file` and `script` are specified", fixed = TRUE 26 | ) 27 | 28 | expect_error( 29 | app$wait_for_js("1 +"), 30 | "Error found while waiting for JavaScript script to" 31 | ) 32 | }) 33 | -------------------------------------------------------------------------------- /tests/testthat/apps/image/app.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | # App that uses `renderImage()` 4 | 5 | ui <- fluidPage( 6 | h3("A bear"), 7 | actionButton("rawr", "Rawr!"), 8 | tags$br(), 9 | imageOutput("img", width = 500, height = 500), 10 | 11 | tags$br(), 12 | h3("A red box"), 13 | div(id = "red", style = "background-color: red; width: 100px; height: 100px;"), 14 | h3("A green box"), 15 | div(id = "green", style = "background-color: darkgreen; width: 100px; height: 100px;"), 16 | ) 17 | 18 | server <- function(input, output, session) { 19 | output$img <- renderImage({ 20 | shiny::req(input$rawr) 21 | 22 | list(src = "bear.png") 23 | }, deleteFile = FALSE) 24 | 25 | } 26 | 27 | shinyApp(ui, server) 28 | -------------------------------------------------------------------------------- /tests/testthat/apps/image/bear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/apps/image/bear.png -------------------------------------------------------------------------------- /tests/testthat/apps/image/tests/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/image/tests/testthat/_snaps/image/no-pic1-001.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "rawr": 0 4 | }, 5 | "output": { 6 | "img": { 7 | "message": "", 8 | "call": "NULL", 9 | "type": [ 10 | "shiny.silent.error", 11 | "validation" 12 | ] 13 | } 14 | }, 15 | "export": { 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/testthat/apps/image/tests/testthat/_snaps/image/no-pic2-001.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "rawr": 0 4 | }, 5 | "output": { 6 | "img": { 7 | "message": "", 8 | "call": "NULL", 9 | "type": [ 10 | "shiny.silent.error", 11 | "validation" 12 | ] 13 | } 14 | }, 15 | "export": { 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/testthat/apps/image/tests/testthat/_snaps/image/sa-user-001.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "rawr": 0 4 | }, 5 | "output": { 6 | "img": { 7 | "message": "", 8 | "call": "NULL", 9 | "type": [ 10 | "shiny.silent.error", 11 | "validation" 12 | ] 13 | } 14 | }, 15 | "export": { 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/testthat/apps/image/tests/testthat/_snaps/image/sa-user-001_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/apps/image/tests/testthat/_snaps/image/sa-user-001_.png -------------------------------------------------------------------------------- /tests/testthat/apps/image/tests/testthat/_snaps/image/sa-values-001.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "rawr": 0 4 | }, 5 | "output": { 6 | "img": { 7 | "message": "", 8 | "call": "NULL", 9 | "type": [ 10 | "shiny.silent.error", 11 | "validation" 12 | ] 13 | } 14 | }, 15 | "export": { 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/testthat/apps/image/tests/testthat/_snaps/image/sa-values-001_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/apps/image/tests/testthat/_snaps/image/sa-values-001_.png -------------------------------------------------------------------------------- /tests/testthat/apps/image/tests/testthat/_snaps/image/screen1-001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/apps/image/tests/testthat/_snaps/image/screen1-001.png -------------------------------------------------------------------------------- /tests/testthat/apps/image/tests/testthat/_snaps/image/screen2-001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/apps/image/tests/testthat/_snaps/image/screen2-001.png -------------------------------------------------------------------------------- /tests/testthat/apps/image/tests/testthat/_snaps/mac-4.1/image/001.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "rawr": 1 4 | }, 5 | "output": { 6 | "img": { 7 | "src": "[image data hash: 29837440fa6116731e3cfdb9c02bc1e1]" 8 | } 9 | }, 10 | "export": { 11 | 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/testthat/apps/image/tests/testthat/_snaps/mac-4.1/image/001_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/apps/image/tests/testthat/_snaps/mac-4.1/image/001_.png -------------------------------------------------------------------------------- /tests/testthat/apps/image/tests/testthat/_snaps/mac-4.1/image/002.json: -------------------------------------------------------------------------------- 1 | { 2 | "output": { 3 | "img": { 4 | "src": "[image data hash: 29837440fa6116731e3cfdb9c02bc1e1]" 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tests/testthat/apps/image/tests/testthat/_snaps/mac-4.1/image/002_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/apps/image/tests/testthat/_snaps/mac-4.1/image/002_.png -------------------------------------------------------------------------------- /tests/testthat/apps/image/tests/testthat/setup.R: -------------------------------------------------------------------------------- 1 | shinytest2::load_app_env() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/logs/app.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | ui <- fluidPage( 4 | "For testing logging purposes only", 5 | verbatimTextOutput("time"), 6 | # Print all known types 7 | tags$script("console.log('Nullish', null, undefined)"), 8 | tags$script("console.log('Boolean', false, true)"), 9 | tags$script("console.log('Character', 'abc')"), 10 | tags$script("console.log('Number', 123)"), 11 | tags$script("console.log('BigInt', 10n)"), 12 | tags$script("console.log('Object', {'a': 'b'})"), 13 | tags$script("console.log('Math', Math)"), 14 | tags$script("console.log('Symbol', Symbol('abc'))"), 15 | tags$script("console.log('Array', [1,2, 3])"), 16 | tags$script("console.log('Function', Date)"), 17 | # Capture throw 18 | tags$script("setTimeout(function() { throw 'Exception msg' }, 2)"), 19 | # Capture exception 20 | tags$script("setTimeout(function() { window.test_method(); }, 4)"), 21 | ) 22 | server <- function(input, output, session) { 23 | cat("Cat msg!\n") 24 | 25 | message("Message msg!") 26 | 27 | output$time <- renderText({ 28 | shiny::invalidateLater(3 * 1000) 29 | Sys.time() 30 | }) 31 | } 32 | 33 | shinyApp(ui, server) 34 | -------------------------------------------------------------------------------- /tests/testthat/apps/logs/tests/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/logs/tests/testthat/setup.R: -------------------------------------------------------------------------------- 1 | shinytest2::load_app_env() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/plotly/app.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | ui <- fluidPage( 4 | plotly::plotlyOutput(outputId = "p") 5 | ) 6 | 7 | server <- function(input, output, session, ...) { 8 | output$p <- shiny::snapshotPreprocessOutput( 9 | plotly::renderPlotly({ 10 | plotly::plot_ly(x = cars[, 1], y = cars[, 2], type = "scattergl", mode = "markers") 11 | }), 12 | function(p) { 13 | jsonlite::parse_json(p, simplifyVector = TRUE, simplifyDataFrame = FALSE, 14 | simplifyMatrix = FALSE)$x$data[[1]][c("x", "y")] 15 | } 16 | ) 17 | } 18 | 19 | shinyApp(ui, server) 20 | -------------------------------------------------------------------------------- /tests/testthat/apps/plotly/tests/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/plotly/tests/testthat/setup.R: -------------------------------------------------------------------------------- 1 | shinytest2::load_app_env() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/plotly/tests/testthat/test-plotly.R: -------------------------------------------------------------------------------- 1 | 2 | test_that("plotly webgl works", { 3 | skip_if_not_installed("plotly") 4 | # TODO-future; Good candidate for fuzzy picture matching 5 | 6 | app <- AppDriver$new() 7 | 8 | app$wait_for_value(output = "p", ignore = list(NULL)) 9 | 10 | app$expect_values(output = "p", screenshot_args = FALSE) 11 | }) 12 | -------------------------------------------------------------------------------- /tests/testthat/apps/qmd/.gitignore: -------------------------------------------------------------------------------- 1 | not-index.html 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/qmd/not-index.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Old Faithful" 3 | format: html 4 | server: shiny 5 | --- 6 | 7 | ```{r, echo=FALSE} 8 | textInput("name", "What is your name?") 9 | actionButton("greet", "Greet") 10 | textOutput("greeting") 11 | ``` 12 | 13 | ```{r} 14 | #| context: server 15 | output$greeting <- renderText({ 16 | shiny::req(input$greet) 17 | paste0("Hello ", shiny::isolate(input$name), "!") 18 | }) 19 | ``` 20 | -------------------------------------------------------------------------------- /tests/testthat/apps/qmd/tests/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/qmd/tests/testthat/_snaps/quarto/001.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "greet": 1, 4 | "name": "barret" 5 | }, 6 | "output": { 7 | "greeting": "Hello barret!" 8 | }, 9 | "export": { 10 | 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/testthat/apps/qmd/tests/testthat/_snaps/quarto/001_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/apps/qmd/tests/testthat/_snaps/quarto/001_.png -------------------------------------------------------------------------------- /tests/testthat/apps/qmd/tests/testthat/setup.R: -------------------------------------------------------------------------------- 1 | shinytest2::load_app_env() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/qmd/tests/testthat/test-quarto.R: -------------------------------------------------------------------------------- 1 | library(shinytest2) 2 | 3 | test_that("Quarto documents can test", { 4 | app <- AppDriver$new(seed = 68850) 5 | 6 | app$set_inputs(name = "barret") 7 | app$click("greet") 8 | app$expect_values() 9 | expect_equal( 10 | app$get_value(output = "greeting"), 11 | "Hello barret!" 12 | ) 13 | }) 14 | -------------------------------------------------------------------------------- /tests/testthat/apps/rmd-not-shiny/report.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: rmarkdown::html_document 3 | --- 4 | Here is my regression model: 5 | 6 | ```{r model, collapse=TRUE} 7 | options(digits = 4) 8 | fit <- lm(reg_formula(), data = mtcars) 9 | b <- coef(fit) 10 | summary(fit) 11 | ``` 12 | 13 | The fitting result is $mpg = `r b[1]` + `r b[2]``r input$x`$. 14 | Below is a scatter plot with the regression line. 15 | 16 | ```{r plot, fig.height=5} 17 | par(mar = c(4, 4, 1, 1)) 18 | plot(reg_formula(), data = mtcars, pch = 19, col = "gray") 19 | abline(fit, col = "red", lwd = 2) 20 | ``` 21 | -------------------------------------------------------------------------------- /tests/testthat/apps/rmd-not-shiny/server.R: -------------------------------------------------------------------------------- 1 | function(input, output) { 2 | 3 | reg_formula <- reactive({ 4 | as.formula(paste("mpg ~", input$x)) 5 | }) 6 | 7 | output$reg_plot <- renderPlot({ 8 | par(mar = c(4, 4, .1, .1)) 9 | plot(reg_formula(), data = mtcars, pch = 19) 10 | }) 11 | 12 | output$format_type <- renderText({ 13 | input$format 14 | }) 15 | 16 | output$download_report <- downloadHandler( 17 | filename = function() { 18 | paste("my-report", sep = ".", switch( 19 | input$format, PDF = "pdf", HTML = "html", Word = "docx" 20 | )) 21 | }, 22 | 23 | content = function(file) { 24 | src <- normalizePath("report.Rmd") 25 | 26 | # temporarily switch to the temp dir, in case you do not have write 27 | # permission to the current working directory 28 | owd <- setwd(tempdir()) 29 | on.exit(setwd(owd)) 30 | file.copy(src, "report.Rmd", overwrite = TRUE) 31 | 32 | library(rmarkdown) 33 | out <- render("report.Rmd", switch( 34 | input$format, 35 | PDF = pdf_document(), HTML = html_document(), Word = word_document() 36 | )) 37 | file.rename(out, file) 38 | } 39 | ) 40 | 41 | } 42 | -------------------------------------------------------------------------------- /tests/testthat/apps/rmd-not-shiny/tests/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/rmd-not-shiny/tests/testthat/setup.R: -------------------------------------------------------------------------------- 1 | shinytest2::load_app_env() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/rmd-not-shiny/tests/testthat/test-ignore-regular-rmd.R: -------------------------------------------------------------------------------- 1 | library(shinytest2) 2 | 3 | test_that("Regular Rmd files are ignored", { 4 | app <- AppDriver$new() 5 | 6 | expect_equal( 7 | app$get_value(output = "format_type"), 8 | "PDF" 9 | ) 10 | }) 11 | -------------------------------------------------------------------------------- /tests/testthat/apps/rmd-not-shiny/ui.R: -------------------------------------------------------------------------------- 1 | fluidPage( 2 | title = "Download a PDF report", 3 | sidebarLayout( 4 | sidebarPanel( 5 | helpText(), 6 | selectInput("x", "Build a regression model of mpg against:", 7 | choices = names(mtcars)[-1]), 8 | radioButtons("format", "Document format", c("PDF", "HTML", "Word"), 9 | inline = TRUE), 10 | downloadButton("download_report") 11 | ), 12 | mainPanel( 13 | plotOutput("reg_plot"), 14 | verbatimTextOutput("format_type") 15 | ) 16 | ) 17 | ) 18 | -------------------------------------------------------------------------------- /tests/testthat/apps/rmd-pre/.gitignore: -------------------------------------------------------------------------------- 1 | not-index.html 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/rmd-pre/not-index.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Hello Prerendered Shiny" 3 | output: html_document 4 | runtime: shiny_prerendered 5 | --- 6 | 7 | ```{r, echo=FALSE} 8 | textInput("name", "What is your name?") 9 | actionButton("greet", "Greet") 10 | textOutput("greeting") 11 | ``` 12 | 13 | ```{r, context="server"} 14 | output$greeting <- renderText({ 15 | shiny::req(input$greet) 16 | paste0("Hello ", shiny::isolate(input$name), "!") 17 | }) 18 | ``` 19 | -------------------------------------------------------------------------------- /tests/testthat/apps/rmd-pre/tests/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/rmd-pre/tests/testthat/_snaps/prerendered/001.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "greet": 1, 4 | "name": "barret" 5 | }, 6 | "output": { 7 | "greeting": "Hello barret!" 8 | }, 9 | "export": { 10 | 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/testthat/apps/rmd-pre/tests/testthat/_snaps/prerendered/001_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/apps/rmd-pre/tests/testthat/_snaps/prerendered/001_.png -------------------------------------------------------------------------------- /tests/testthat/apps/rmd-pre/tests/testthat/setup.R: -------------------------------------------------------------------------------- 1 | shinytest2::load_app_env() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/rmd-pre/tests/testthat/test-prerendered.R: -------------------------------------------------------------------------------- 1 | library(shinytest2) 2 | 3 | test_that("Prerendered Shiny R Markdown documents can test", { 4 | app <- AppDriver$new(seed = 9767) 5 | 6 | app$set_inputs(name = "barret") 7 | app$click("greet") 8 | app$expect_values() 9 | expect_equal( 10 | app$get_value(output = "greeting"), 11 | "Hello barret!" 12 | ) 13 | }) 14 | -------------------------------------------------------------------------------- /tests/testthat/apps/rmd-shiny/not-index.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Hello Shiny" 3 | output: html_document 4 | runtime: shiny 5 | --- 6 | 7 | ```{r, echo=FALSE} 8 | textInput("name", "What is your name?") 9 | actionButton("greet", "Greet") 10 | textOutput("greeting") 11 | ``` 12 | 13 | ```{r, echo = FALSE} 14 | output$greeting <- renderText({ 15 | shiny::req(input$greet) 16 | paste0("Hello ", shiny::isolate(input$name), "!") 17 | }) 18 | ``` 19 | -------------------------------------------------------------------------------- /tests/testthat/apps/rmd-shiny/tests/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/rmd-shiny/tests/testthat/_snaps/rmd/001.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "greet": 1, 4 | "name": "barret" 5 | }, 6 | "output": { 7 | "greeting": "Hello barret!" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/testthat/apps/rmd-shiny/tests/testthat/_snaps/rmd/001_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/apps/rmd-shiny/tests/testthat/_snaps/rmd/001_.png -------------------------------------------------------------------------------- /tests/testthat/apps/rmd-shiny/tests/testthat/setup.R: -------------------------------------------------------------------------------- 1 | shinytest2::load_app_env() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/rmd-shiny/tests/testthat/test-rmd.R: -------------------------------------------------------------------------------- 1 | library(shinytest2) 2 | 3 | test_that("Shiny R Markdown documents can test", { 4 | app <- AppDriver$new(seed = 9767) 5 | 6 | app$set_inputs(name = "barret") 7 | app$click("greet") 8 | app$expect_values(input = TRUE, output = "greeting") 9 | expect_equal( 10 | app$get_value(output = "greeting"), 11 | "Hello barret!" 12 | ) 13 | }) 14 | -------------------------------------------------------------------------------- /tests/testthat/apps/robust-ex/app.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | library(ggplot2) 3 | 4 | ui <- fluidPage( 5 | numericInput("n", "Number of rows", 10, 1, nrow(cars)), 6 | plotOutput("plot") 7 | ) 8 | server <- function(input, output) { 9 | dt <- reactive({ 10 | head(cars, input$n) 11 | }) 12 | plot_obj <- reactive({ 13 | ggplot2::ggplot(dt(), ggplot2::aes_string("speed", "dist")) + ggplot2::geom_point() 14 | }) 15 | 16 | output$plot <- renderPlot({ 17 | plot_obj() 18 | }) 19 | 20 | exportTestValues( 21 | dt = dt(), 22 | plot_obj = plot_obj() 23 | ) 24 | } 25 | 26 | shinyApp(ui = ui, server = server) 27 | -------------------------------------------------------------------------------- /tests/testthat/apps/robust-ex/tests/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/robust-ex/tests/testthat/setup.R: -------------------------------------------------------------------------------- 1 | shinytest2::load_app_env() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/robust-ex/tests/testthat/test-export-long.R: -------------------------------------------------------------------------------- 1 | library(shinytest2) 2 | 3 | test_that("`export`ed `plot_obj` is updated by `n`", { 4 | skip_if_not_installed("vdiffr") 5 | 6 | app <- AppDriver$new() 7 | 8 | # Verify `dt()` uses first 10 lines of `cars` 9 | n10 <- app$get_value(input = "n") 10 | expect_equal(n10, 10) 11 | # Verify `dt10()` data is first 10 lines of `cars` 12 | dt10 <- app$get_value(export = "dt") 13 | expect_equal(dt10, head(cars, n10)) 14 | 15 | # Verify `plot_obj()` data is `dt()` 16 | plot_obj_10 <- app$get_value(export = "plot_obj") 17 | expect_equal(plot_obj_10$data, dt10) 18 | # Verify `plot_obj()` is consistent 19 | vdiffr::expect_doppelganger("cars-points-10", plot_obj_10) 20 | 21 | ## Update `n` to 20 22 | app$set_inputs(n = 20) 23 | 24 | # Verify `n` was updated 25 | n20 <- app$get_value(input = "n") 26 | expect_equal(n20, 20) 27 | # Verify `dt()` uses first 20 lines of `cars` 28 | dt20 <- app$get_value(export = "dt") 29 | expect_equal(dt20, head(cars, n20)) 30 | 31 | # Verify `plot_obj()` data is `dt()` 32 | plot_obj_20 <- app$get_value(export = "plot_obj") 33 | expect_equal(plot_obj_20$data, dt20) 34 | vdiffr::expect_doppelganger("cars-points-20", plot_obj_20) 35 | }) 36 | -------------------------------------------------------------------------------- /tests/testthat/apps/robust-ex/tests/testthat/test-export-short.R: -------------------------------------------------------------------------------- 1 | library(shinytest2) 2 | 3 | 4 | test_that("`export`ed `plot_obj` is updated by `n`", { 5 | 6 | skip_if_not_installed("vdiffr") 7 | 8 | app <- AppDriver$new() 9 | 10 | expect_n_and_plot <- function(n) { 11 | # Verify `n` input equals `n` 12 | n_val <- app$get_value(input = "n") 13 | testthat::expect_equal(n_val, n, expected.label = n) 14 | # Verify `dt()` data is first `n` lines of `cars` 15 | dt <- app$get_value(export = "dt") 16 | testthat::expect_equal(dt, head(cars, n), expected.label = paste0("head(cars, ", n, ")")) 17 | 18 | # Verify `plot_obj()` data is `dt()` 19 | plot_obj <- app$get_value(export = "plot_obj") 20 | testthat::expect_equal(plot_obj$data, dt, info = paste0("n = ", n)) 21 | # Verify `plot_obj()` is consistent 22 | vdiffr::expect_doppelganger(paste0("cars-points-", n), plot_obj) 23 | } 24 | 25 | expect_n_and_plot(10) 26 | 27 | app$set_inputs(n = 20) 28 | expect_n_and_plot(20) 29 | }) 30 | -------------------------------------------------------------------------------- /tests/testthat/apps/stop/app.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | ui <- fluidPage( 4 | h1("Click the button and the app dies and returns `42`"), 5 | actionButton("button", "What is the meaning of life?") 6 | ) 7 | server <- function(input, output, session) { 8 | observeEvent(input$button, { 9 | shiny::stopApp(42) 10 | }) 11 | } 12 | 13 | shinyApp(ui, server) 14 | -------------------------------------------------------------------------------- /tests/testthat/apps/stop/tests/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/stop/tests/testthat/setup.R: -------------------------------------------------------------------------------- 1 | shinytest2::load_app_env() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/stop/tests/testthat/test-stop.R: -------------------------------------------------------------------------------- 1 | 2 | test_that("App returns value from script", { 3 | app <- AppDriver$new() 4 | app$click("button") 5 | app$wait_for_idle() # Wait for the app to stop 6 | 7 | meaning_of_life <- app$stop() 8 | expect_equal(meaning_of_life, 42) 9 | }) 10 | 11 | test_that("App returns value from script", { 12 | app <- AppDriver$new() 13 | # app$click("button") 14 | 15 | normal_return <- app$stop() 16 | expect_equal(normal_return, NULL) 17 | }) 18 | -------------------------------------------------------------------------------- /tests/testthat/apps/task-button/tests/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/task-button/tests/testthat/setup-shinytest2.R: -------------------------------------------------------------------------------- 1 | # Load application support files into testing environment 2 | shinytest2::load_app_env() 3 | -------------------------------------------------------------------------------- /tests/testthat/apps/task-button/tests/testthat/test-bslib-task-btn.R: -------------------------------------------------------------------------------- 1 | # Related https://github.com/rstudio/shinytest2/issues/388 2 | # Reprex altered from https://stackoverflow.com/questions/78517385/testing-async-extendedtask-with-shinytest2 3 | # 2 issues from reprex: 4 | # * $click() did not work as task button preprocessor wasn't registered 5 | # * Asserting the value of the resolved async output needs to happen after the output value updates due to timeing issues 6 | test_that("bslib task button", { 7 | skip_on_cran() 8 | skip_on_os("windows") 9 | skip_if_not_installed("bslib") 10 | skip_if_not_installed("promises") 11 | skip_if_not_installed("later") 12 | 13 | 14 | app <- AppDriver$new() 15 | 16 | app$click("run_normal") 17 | expect_equal(app$get_value(export = "normal"), 10) 18 | 19 | # Get current value 20 | cur_async_value <- app$get_value(export = "async") 21 | app$click("run_async") 22 | # Wait until expected output changes 23 | new_async_value <- app$wait_for_value(export = "async", ignore = list(cur_async_value)) 24 | # Assert new value 25 | expect_equal(new_async_value, 10) 26 | }) 27 | -------------------------------------------------------------------------------- /tests/testthat/apps/text_html/app.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | ui <- fluidPage( 4 | textInput("val", "UI Output", "Insert HTML here"), 5 | uiOutput("html"), 6 | verbatimTextOutput("text") 7 | ) 8 | server <- function(input, output, session) { 9 | output$html <- renderText({ 10 | shiny::req(input$val) 11 | shiny::HTML(input$val) 12 | }) 13 | output$text <- renderText({ 14 | shiny::req(input$val) 15 | input$val 16 | }) 17 | } 18 | shinyApp(ui, server) 19 | -------------------------------------------------------------------------------- /tests/testthat/apps/text_html/tests/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/text_html/tests/testthat/_snaps/expect-snapshot-js.md: -------------------------------------------------------------------------------- 1 | # basic text and dom outputs are expected 2 | 3 | "

My Custom Output<\/p><\/div>" 4 | 5 | --- 6 | 7 | "My Custom Output" 8 | 9 | --- 10 | 11 | "

My Custom Output<\/p><\/div>" 12 | 13 | --- 14 | 15 | "

My Custom Output<\/p>" 16 | 17 | -------------------------------------------------------------------------------- /tests/testthat/apps/text_html/tests/testthat/setup.R: -------------------------------------------------------------------------------- 1 | shinytest2::load_app_env() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/text_html/tests/testthat/test-expect-snapshot-js.R: -------------------------------------------------------------------------------- 1 | test_that("basic text and dom outputs are expected", { 2 | app <- AppDriver$new(variant = NULL) 3 | 4 | app$set_inputs(val = "

My Custom Output

") 5 | 6 | app$expect_text("#text") 7 | app$expect_text("#custom") 8 | 9 | app$expect_html("#custom", outer_html = TRUE) 10 | app$expect_html("#custom", outer_html = FALSE) 11 | }) 12 | 13 | test_that("basic text and dom outputs are captured", { 14 | app <- AppDriver$new(variant = NULL) 15 | 16 | app$set_inputs(val = "

My Custom Output

") 17 | 18 | expect_equal( 19 | app$get_text("#text"), 20 | "

My Custom Output

" 21 | ) 22 | expect_equal( 23 | app$get_text("#custom"), 24 | "My Custom Output" 25 | ) 26 | 27 | expect_equal( 28 | app$get_html("#custom", outer_html = TRUE), 29 | "

My Custom Output

" 30 | ) 31 | expect_equal( 32 | app$get_html("#custom", outer_html = FALSE), 33 | "

My Custom Output

" 34 | ) 35 | }) 36 | -------------------------------------------------------------------------------- /tests/testthat/apps/update/app.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | ui <- fluidPage( 4 | tags$h1("Do not touch slider"), 5 | actionButton("click", "Click me!"), 6 | tagAppendAttributes(sliderInput("slider", "Slider", 0, 100, value = 50), class = "disabled"), 7 | tags$h4("Click count"), 8 | verbatimTextOutput("clicks"), 9 | tags$h4("JS Click count"), 10 | verbatimTextOutput("js_clicks"), 11 | tags$script(HTML(' 12 | $(function() { 13 | Shiny.addCustomMessageHandler("count", function(message) { 14 | Shiny.setInputValue("counter", message, {priority: "event"}); 15 | }); 16 | }); 17 | ')) 18 | ) 19 | 20 | server <- function(input, output, session) { 21 | 22 | observe({ 23 | shiny::updateSliderInput(inputId = "slider", value = input$click) 24 | session$sendCustomMessage("count", input$click) 25 | }) 26 | 27 | output$clicks <- renderText({ 28 | input$click 29 | }) 30 | output$js_clicks <- renderText({ 31 | input$counter 32 | }) 33 | 34 | } 35 | 36 | shinyApp(ui, server) 37 | -------------------------------------------------------------------------------- /tests/testthat/apps/update/tests/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/update/tests/testthat/_snaps/shinytest2/click-001.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "click": 4, 4 | "counter": 4, 5 | "slider": 4 6 | }, 7 | "output": { 8 | "clicks": "4", 9 | "js_clicks": "4" 10 | }, 11 | "export": { 12 | 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/testthat/apps/update/tests/testthat/_snaps/shinytest2/click-001_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/apps/update/tests/testthat/_snaps/shinytest2/click-001_.png -------------------------------------------------------------------------------- /tests/testthat/apps/update/tests/testthat/_snaps/shinytest2/no-binding-001.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "click": 0, 4 | "counter": 4, 5 | "slider": 0 6 | }, 7 | "output": { 8 | "clicks": "0", 9 | "js_clicks": "4" 10 | }, 11 | "export": { 12 | 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/testthat/apps/update/tests/testthat/_snaps/shinytest2/no-binding-001_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/apps/update/tests/testthat/_snaps/shinytest2/no-binding-001_.png -------------------------------------------------------------------------------- /tests/testthat/apps/update/tests/testthat/setup.R: -------------------------------------------------------------------------------- 1 | shinytest2::load_app_env() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/update/tests/testthat/test-shinytest2.R: -------------------------------------------------------------------------------- 1 | library(shinytest2) 2 | 3 | test_that("click causes input without binding to update", { 4 | app <- AppDriver$new(name = "click") 5 | 6 | app$click("click") 7 | app$click("click") 8 | app$click("click") 9 | app$click("click") 10 | app$expect_values() 11 | }) 12 | 13 | test_that("Can update the input without biding individually", { 14 | app <- AppDriver$new(name = "no-binding") 15 | 16 | app$set_inputs(counter = 1, allow_no_input_binding_ = TRUE, priority_ = "event") 17 | app$set_inputs(counter = 2, allow_no_input_binding_ = TRUE, priority_ = "event") 18 | app$set_inputs(counter = 3, allow_no_input_binding_ = TRUE, priority_ = "event") 19 | app$set_inputs(counter = 4, allow_no_input_binding_ = TRUE, priority_ = "event") 20 | app$expect_values() 21 | }) 22 | -------------------------------------------------------------------------------- /tests/testthat/apps/upload-multi/app.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | ui <- fluidPage( 4 | "Upload multiple files:", 5 | fileInput("files", label = NULL, multiple = TRUE), 6 | verbatimTextOutput("file_out"), 7 | ) 8 | 9 | server <- function(input, output) { 10 | 11 | # Display `file` output 12 | output$file_out <- renderPrint({ 13 | if (is.null(input$files)) 14 | return(NULL) 15 | df <- input$files 16 | df$datapath <- paste0("/", basename(df$datapath)) 17 | df 18 | }) 19 | } 20 | 21 | shinyApp(ui, server) 22 | -------------------------------------------------------------------------------- /tests/testthat/apps/upload-multi/tests/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/upload-multi/tests/testthat/_snaps/app-upload-multi/upload-multi-001.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "files": { 4 | "name": [ 5 | "cars.csv", 6 | "cars_2.csv" 7 | ], 8 | "size": [ 9 | 308, 10 | 229 11 | ], 12 | "type": [ 13 | "text/csv", 14 | "text/csv" 15 | ], 16 | "datapath": [ 17 | "0.csv", 18 | "1.csv" 19 | ] 20 | } 21 | }, 22 | "output": { 23 | "file_out": " name size type datapath\n1 cars.csv 308 text/csv /0.csv\n2 cars_2.csv 229 text/csv /1.csv" 24 | }, 25 | "export": { 26 | 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /tests/testthat/apps/upload-multi/tests/testthat/_snaps/app-upload-multi/upload-multi-001_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/apps/upload-multi/tests/testthat/_snaps/app-upload-multi/upload-multi-001_.png -------------------------------------------------------------------------------- /tests/testthat/apps/upload-multi/tests/testthat/cars.csv: -------------------------------------------------------------------------------- 1 | "speed","dist" 2 | 4,2 3 | 4,10 4 | 7,4 5 | 7,22 6 | 8,16 7 | 9,10 8 | 10,18 9 | 10,26 10 | 10,34 11 | 11,17 12 | 11,28 13 | 12,14 14 | 12,20 15 | 12,24 16 | 12,28 17 | 13,26 18 | 13,34 19 | 13,34 20 | 13,46 21 | 14,26 22 | 14,36 23 | 14,60 24 | 14,80 25 | 15,20 26 | 15,26 27 | 15,54 28 | 16,32 29 | 16,40 30 | 17,32 31 | 17,40 32 | 17,50 33 | 18,42 34 | 18,56 35 | 18,76 36 | 18,84 37 | 19,36 38 | 19,46 39 | 19,68 40 | 20,32 41 | 20,48 42 | 20,52 43 | 20,56 44 | 20,64 45 | 22,66 46 | 23,54 47 | 24,70 48 | 24,92 49 | 24,93 50 | 24,120 51 | 25,85 52 | -------------------------------------------------------------------------------- /tests/testthat/apps/upload-multi/tests/testthat/cars_2.csv: -------------------------------------------------------------------------------- 1 | "speed","dist" 2 | 4,2 3 | 4,10 4 | 7,4 5 | 7,22 6 | 8,16 7 | 9,10 8 | 10,18 9 | 10,26 10 | 10,34 11 | 11,17 12 | 11,28 13 | 12,14 14 | 12,20 15 | 12,24 16 | 12,28 17 | 13,26 18 | 13,34 19 | 13,34 20 | 13,46 21 | 14,26 22 | 14,36 23 | 14,60 24 | 14,80 25 | 15,20 26 | 15,26 27 | 15,54 28 | 16,32 29 | 16,40 30 | 17,32 31 | 17,40 32 | 17,50 33 | 18,42 34 | 18,56 35 | 18,76 36 | 18,84 37 | 19,36 38 | 19,46 39 | -------------------------------------------------------------------------------- /tests/testthat/apps/upload-multi/tests/testthat/setup.R: -------------------------------------------------------------------------------- 1 | shinytest2::load_app_env() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/upload-multi/tests/testthat/test-app-upload-multi.R: -------------------------------------------------------------------------------- 1 | library(shinytest2) 2 | 3 | test_that("Make sure upload can use two local files", { 4 | app <- AppDriver$new(name = "upload-multi") 5 | 6 | app$upload_file(files = c("cars.csv", "cars_2.csv")) 7 | app$expect_values() 8 | 9 | expect_error( 10 | app$upload_file(files = "missing_file.csv"), 11 | "Error finding upload file at path", fixed = TRUE 12 | ) 13 | }) 14 | -------------------------------------------------------------------------------- /tests/testthat/apps/upload/app.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | ui <- fluidPage( 4 | "Upload a file:", 5 | fileInput("file", label = NULL), 6 | verbatimTextOutput("file_out"), 7 | ) 8 | 9 | server <- function(input, output) { 10 | 11 | # Display `file` output 12 | output$file_out <- renderPrint({ 13 | if (is.null(input$file)) 14 | return(NULL) 15 | df <- input$file 16 | df$datapath <- paste0("/", basename(df$datapath)) 17 | df 18 | }) 19 | } 20 | 21 | shinyApp(ui, server) 22 | -------------------------------------------------------------------------------- /tests/testthat/apps/upload/tests/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/upload/tests/testthat/_snaps/app-upload/upload-001.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "file": { 4 | "name": [ 5 | "cars.csv" 6 | ], 7 | "size": [ 8 | 308 9 | ], 10 | "type": [ 11 | "text/csv" 12 | ], 13 | "datapath": [ 14 | "0.csv" 15 | ] 16 | } 17 | }, 18 | "output": { 19 | "file_out": " name size type datapath\n1 cars.csv 308 text/csv /0.csv" 20 | }, 21 | "export": { 22 | 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/testthat/apps/upload/tests/testthat/_snaps/app-upload/upload-001_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/apps/upload/tests/testthat/_snaps/app-upload/upload-001_.png -------------------------------------------------------------------------------- /tests/testthat/apps/upload/tests/testthat/cars.csv: -------------------------------------------------------------------------------- 1 | "speed","dist" 2 | 4,2 3 | 4,10 4 | 7,4 5 | 7,22 6 | 8,16 7 | 9,10 8 | 10,18 9 | 10,26 10 | 10,34 11 | 11,17 12 | 11,28 13 | 12,14 14 | 12,20 15 | 12,24 16 | 12,28 17 | 13,26 18 | 13,34 19 | 13,34 20 | 13,46 21 | 14,26 22 | 14,36 23 | 14,60 24 | 14,80 25 | 15,20 26 | 15,26 27 | 15,54 28 | 16,32 29 | 16,40 30 | 17,32 31 | 17,40 32 | 17,50 33 | 18,42 34 | 18,56 35 | 18,76 36 | 18,84 37 | 19,36 38 | 19,46 39 | 19,68 40 | 20,32 41 | 20,48 42 | 20,52 43 | 20,56 44 | 20,64 45 | 22,66 46 | 23,54 47 | 24,70 48 | 24,92 49 | 24,93 50 | 24,120 51 | 25,85 52 | -------------------------------------------------------------------------------- /tests/testthat/apps/upload/tests/testthat/setup.R: -------------------------------------------------------------------------------- 1 | shinytest2::load_app_env() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/upload/tests/testthat/test-app-upload.R: -------------------------------------------------------------------------------- 1 | library(shinytest2) 2 | 3 | test_that("Make sure upload can use a local file", { 4 | app <- AppDriver$new(name = "upload") 5 | 6 | app$upload_file(file = "cars.csv") 7 | app$expect_values() 8 | 9 | expect_error( 10 | app$upload_file(file = "missing_file.csv"), 11 | "Error finding upload file at path", fixed = TRUE 12 | ) 13 | }) 14 | -------------------------------------------------------------------------------- /tests/testthat/apps/wait-setup/R/n.R: -------------------------------------------------------------------------------- 1 | # Keep this file. 2 | # This is a good candidate for knowing that `shinytest2::test_app()` is being called in `tests/testthat.R` 3 | 4 | n <- 750 5 | -------------------------------------------------------------------------------- /tests/testthat/apps/wait-setup/tests/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/wait-setup/tests/testthat/setup.R: -------------------------------------------------------------------------------- 1 | shinytest2::load_app_env() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/wait-setup/tests/testthat/test-wait-for-idle.R: -------------------------------------------------------------------------------- 1 | 2 | # Testing that `./setup.R` is loaded 3 | 4 | test_that("wait for idle works", { 5 | 6 | app <- AppDriver$new() 7 | 8 | app$wait_for_idle(duration = 2 * n) 9 | 10 | expect_equal(app$get_value(output = "txt"), "1 2 3") 11 | }) 12 | -------------------------------------------------------------------------------- /tests/testthat/apps/wait/R/n.R: -------------------------------------------------------------------------------- 1 | # Keep this file. 2 | # This is a good candidate for knowing that `shinytest2::test_app()` is being called in `tests/testthat.R` 3 | 4 | n <- 750 5 | -------------------------------------------------------------------------------- /tests/testthat/apps/wait/tests/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/wait/tests/testthat/setup-shinytest2.R: -------------------------------------------------------------------------------- 1 | shinytest2::load_app_env() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/wait/tests/testthat/test-get-value.R: -------------------------------------------------------------------------------- 1 | test_that("$get_value errors are caught", { 2 | 3 | app <- AppDriver$new() 4 | 5 | expect_error( 6 | app$get_value("txt"), 7 | ) 8 | 9 | expect_error( 10 | app$get_value(input = "something", output = "txt"), 11 | "specify only one" 12 | ) 13 | expect_error( 14 | app$get_value(input = "something", export = "txt"), 15 | "specify only one" 16 | ) 17 | expect_error( 18 | app$get_value(output = "something", export = "txt"), 19 | "specify only one" 20 | ) 21 | expect_error( 22 | app$get_value(output = c("A", "B")), 23 | "length 2" 24 | ) 25 | expect_error( 26 | app$get_value(output = character(0)), 27 | "length 0" 28 | ) 29 | 30 | 31 | expect_error( 32 | app$wait_for_value(input = "something", output = "txt"), 33 | "specify only one" 34 | ) 35 | expect_error( 36 | app$wait_for_value(input = "something", export = "txt"), 37 | "specify only one" 38 | ) 39 | expect_error( 40 | app$wait_for_value(output = "something", export = "txt"), 41 | "specify only one" 42 | ) 43 | expect_error( 44 | app$wait_for_value(output = c("A", "B")), 45 | "length 2" 46 | ) 47 | expect_error( 48 | app$wait_for_value(output = character(0)), 49 | "length 0" 50 | ) 51 | }) 52 | 53 | 54 | test_that("wait for value works on output", { 55 | 56 | app <- AppDriver$new() 57 | 58 | expect_equal( 59 | app$wait_for_value(output = "txt"), 60 | "1 2 3" 61 | ) 62 | }) 63 | 64 | test_that("wait for value works on input", { 65 | 66 | app <- AppDriver$new() 67 | 68 | expect_equal( 69 | app$wait_for_value(input = "slider3"), 70 | 3 71 | ) 72 | }) 73 | -------------------------------------------------------------------------------- /tests/testthat/apps/wait/tests/testthat/test-wait-for-idle.R: -------------------------------------------------------------------------------- 1 | # Testing that `./setup-shinytest2.R` is loaded 2 | 3 | test_that("wait for idle works", { 4 | 5 | app <- AppDriver$new() 6 | 7 | app$wait_for_idle(duration = 2 * n) 8 | 9 | expect_equal(app$get_value(output = "txt"), "1 2 3") 10 | }) 11 | 12 | 13 | test_that("waiting a lesser value will not be enough", { 14 | 15 | app <- AppDriver$new() 16 | 17 | app$wait_for_idle(duration = n / 2) 18 | 19 | expect_failure( 20 | expect_equal(app$get_value(output = "txt"), "1 2 3") 21 | ) 22 | }) 23 | -------------------------------------------------------------------------------- /tests/testthat/apps/widgits/tests/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/widgits/tests/testthat/_snaps/app-set-inputs/001.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "action": 0, 4 | "bsSwitch": false, 5 | "checkGroup": "1", 6 | "checkbox": false, 7 | "checkboxGroupButtons": null, 8 | "date": "2014-01-01", 9 | "dates": [ 10 | "2014-01-01", 11 | "2014-02-20" 12 | ], 13 | "file": null, 14 | "knob": 0, 15 | "matSwitch": false, 16 | "num": 1, 17 | "picker": null, 18 | "prettyCheckbox": false, 19 | "radio": "1", 20 | "search": "", 21 | "search_text": "", 22 | "select": "1", 23 | "slider1": 50, 24 | "slider2": [ 25 | 25, 26 | 75 27 | ], 28 | "sliderText": "Strongly disagree", 29 | "tabset": "shiny", 30 | "text": "Enter text..." 31 | }, 32 | "output": { 33 | "action_out": "[1] 0\nattr(,\"class\")\n[1] \"shinyActionButtonValue\" \"integer\" ", 34 | "checkGroup_out": "[1] \"1\"", 35 | "checkbox_out": "[1] FALSE", 36 | "date_out": "[1] \"2014-01-01\"", 37 | "dates_out": "[1] \"2014-01-01\" \"2014-02-20\"", 38 | "file_out": "NULL", 39 | "num_out": "[1] 1", 40 | "radio_out": "[1] \"1\"", 41 | "select_out": "[1] \"1\"", 42 | "slider1_out": "[1] 50", 43 | "slider2_out": "[1] 25 75", 44 | "tabset_out": "[1] \"shiny\"", 45 | "text_out": "[1] \"Enter text...\"" 46 | }, 47 | "export": { 48 | 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tests/testthat/apps/widgits/tests/testthat/_snaps/app-set-inputs/001_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/apps/widgits/tests/testthat/_snaps/app-set-inputs/001_.png -------------------------------------------------------------------------------- /tests/testthat/apps/widgits/tests/testthat/_snaps/app-set-inputs/002_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/apps/widgits/tests/testthat/_snaps/app-set-inputs/002_.png -------------------------------------------------------------------------------- /tests/testthat/apps/widgits/tests/testthat/_snaps/app-set-inputs/003_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/apps/widgits/tests/testthat/_snaps/app-set-inputs/003_.png -------------------------------------------------------------------------------- /tests/testthat/apps/widgits/tests/testthat/_snaps/app-set-inputs/004_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/apps/widgits/tests/testthat/_snaps/app-set-inputs/004_.png -------------------------------------------------------------------------------- /tests/testthat/apps/widgits/tests/testthat/setup.R: -------------------------------------------------------------------------------- 1 | shinytest2::load_app_env() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/widgits/tests/testthat/test-app-set-inputs.R: -------------------------------------------------------------------------------- 1 | # Current shinytest2 code using `app$**()`: 2 | test_that("set kitchen sink of inputs", { 3 | skip_if_not_installed("shinyWidgets") 4 | 5 | app <- AppDriver$new( 6 | # variant = platform_variant() 7 | variant = NULL 8 | ) 9 | 10 | app$expect_values() 11 | # app$expect_screenshot() 12 | 13 | app$set_inputs( 14 | "action" = "click", 15 | "checkbox" = TRUE, 16 | "checkGroup" = c("2", "3"), 17 | "date" = "2015-01-01", 18 | "dates" = c( 19 | "2015-01-01", 20 | "2015-02-20" 21 | ), 22 | "num" = 100, 23 | "radio" = "2", 24 | # "file" = NULL, 25 | "select" = "2", 26 | "slider1" = 65, 27 | "slider2" = c(35, 85), 28 | "text" = "Text entered", 29 | ) 30 | # File upload 31 | local({ 32 | tmpfile <- "__tmpfile.txt" 33 | cat("tmpfile content", file = tmpfile) 34 | withr::defer(unlink(tmpfile)) 35 | app$upload_file(file = tmpfile) 36 | }) 37 | 38 | app$expect_values() 39 | # app$expect_screenshot() 40 | 41 | app$set_inputs(tabset = "shinyWidgets") 42 | 43 | app$expect_values() 44 | # app$expect_screenshot() 45 | 46 | app$set_inputs( 47 | "bsSwitch" = TRUE, 48 | "matSwitch" = TRUE, 49 | "picker" = c("T", "E", "S"), 50 | "prettyCheckbox" = TRUE, 51 | ) 52 | 53 | # TODO-future; Currently do not work 54 | # "checkboxGroupButtons" = c(2,3), 55 | # "knob" = 50, 56 | # "search" = "Test text", # must hit enter to submit 57 | # "sliderText" = "Strongly agree", 58 | 59 | Sys.sleep(0.5) # css animations 60 | app$expect_values() 61 | # app$expect_screenshot() 62 | }) 63 | -------------------------------------------------------------------------------- /tests/testthat/apps/window/app.R: -------------------------------------------------------------------------------- 1 | 2 | # Empty app to test window sizes 3 | shinyApp("", function(input, output) {}) # nolint: brace_linter 4 | -------------------------------------------------------------------------------- /tests/testthat/apps/window/tests/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/window/tests/testthat/setup.R: -------------------------------------------------------------------------------- 1 | shinytest2::load_app_env() 2 | -------------------------------------------------------------------------------- /tests/testthat/apps/window/tests/testthat/test-window-size.R: -------------------------------------------------------------------------------- 1 | 2 | test_that("Init and Set window size", { 3 | 4 | app <- AppDriver$new( 5 | name = "set", 6 | variant = NULL, 7 | height = 100, 8 | width = 150 9 | ) 10 | 11 | expect_equal(app$get_js("let size = {height: window.innerHeight, width: window.innerWidth}; size"), list(height = 100, width = 150)) 12 | 13 | app$set_window_size(height = 200, width = 250) 14 | expect_equal(app$get_js("let size = {height: window.innerHeight, width: window.innerWidth}; size"), list(height = 200, width = 250)) 15 | }) 16 | 17 | 18 | test_that("AppDriver height and width must be positive numbers", { 19 | expect_error(AppDriver$new(height = 100, width = "150")) 20 | expect_error(AppDriver$new(height = "100", width = 150)) 21 | 22 | expect_error(AppDriver$new(height = 0, width = 150)) 23 | expect_error(AppDriver$new(height = 100, width = 0)) 24 | }) 25 | -------------------------------------------------------------------------------- /tests/testthat/helper-migration-env.R: -------------------------------------------------------------------------------- 1 | suppressPackageStartupMessages(library(shiny)) 2 | 3 | make_info_env <- function( 4 | suffix = missing_arg(), 5 | compare_images = TRUE, 6 | app_var = "app", 7 | verbose = FALSE, 8 | include_expect_screenshot = NULL 9 | ) { 10 | as.environment(list( 11 | suffix = suffix, 12 | compare_images = compare_images, 13 | app_var = app_var, 14 | verbose = verbose, 15 | include_expect_screenshot = include_expect_screenshot 16 | )) 17 | } 18 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01/app.R: -------------------------------------------------------------------------------- 1 | # Old Faithful 2 | library(shiny) 3 | 4 | 5 | # Define UI for app that draws a histogram ---- 6 | ui <- fluidPage( 7 | 8 | # App title ---- 9 | titlePanel("Hello Shiny!"), 10 | 11 | # Sidebar layout with input and output definitions ---- 12 | sidebarLayout( 13 | 14 | # Sidebar panel for inputs ---- 15 | sidebarPanel( 16 | 17 | # Input: Slider for the number of bins ---- 18 | sliderInput(inputId = "bins", 19 | label = "Number of bins:", 20 | min = 1, 21 | max = 50, 22 | value = 30) 23 | 24 | ), 25 | 26 | # Main panel for displaying outputs ---- 27 | mainPanel( 28 | 29 | # Output: Histogram ---- 30 | plotOutput(outputId = "dist") 31 | 32 | ) 33 | ) 34 | ) 35 | 36 | # Define server logic required to draw a histogram ---- 37 | server <- function(input, output, session) { 38 | 39 | x <- faithful$waiting 40 | 41 | bins <- reactive({ 42 | seq(min(x), max(x), length.out = input$bins + 1) 43 | }) 44 | 45 | output$dist <- renderPlot({ 46 | 47 | hist(x, breaks = bins(), col = "#75AADB", border = "white", 48 | xlab = "Waiting time to next eruption (in mins)", 49 | main = "Histogram of waiting times") 50 | 51 | }) 52 | 53 | } 54 | 55 | # Create Shiny app ---- 56 | shinyApp(ui = ui, server = server) 57 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01/tests/shinytest.R: -------------------------------------------------------------------------------- 1 | 2 | library(shinytest) 3 | expect_pass(testApp("../", suffix = osName())) 4 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01/tests/shinytest/comments-only.R: -------------------------------------------------------------------------------- 1 | # Comment line 1 2 | 3 | # Comment line 3 4 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01/tests/shinytest/empty-file.R: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/01/tests/shinytest/empty-file.R -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01/tests/shinytest/mytest-expected-mac/001.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "bins": 30 4 | }, 5 | "output": { 6 | "distPlot": { 7 | "src": "[image data sha1: e09d98e82336538663a2b938c92b52ae47ec366f]", 8 | "width": 631, 9 | "height": 400, 10 | "alt": "Plot object", 11 | "coordmap": { 12 | "panels": [ 13 | { 14 | "domain": { 15 | "left": 40.88, 16 | "right": 98.12, 17 | "bottom": -1.08, 18 | "top": 28.08 19 | }, 20 | "range": { 21 | "left": 59.04, 22 | "right": 600.76, 23 | "bottom": 325.56, 24 | "top": 58.04 25 | }, 26 | "log": { 27 | "x": null, 28 | "y": null 29 | }, 30 | "mapping": { 31 | 32 | } 33 | } 34 | ], 35 | "dims": { 36 | "width": 631, 37 | "height": 400 38 | } 39 | } 40 | } 41 | }, 42 | "export": { 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01/tests/shinytest/mytest-expected-mac/001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/01/tests/shinytest/mytest-expected-mac/001.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01/tests/shinytest/mytest-expected-mac/002.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "bins": 8 4 | }, 5 | "output": { 6 | "distPlot": { 7 | "src": "[image data sha1: 145b2714251bd342b58c0e95913922469a596cc9]", 8 | "width": 631, 9 | "height": 400, 10 | "alt": "Plot object", 11 | "coordmap": { 12 | "panels": [ 13 | { 14 | "domain": { 15 | "left": 40.88, 16 | "right": 98.12, 17 | "bottom": -2.8, 18 | "top": 72.8 19 | }, 20 | "range": { 21 | "left": 59.04, 22 | "right": 600.76, 23 | "bottom": 325.56, 24 | "top": 58.04 25 | }, 26 | "log": { 27 | "x": null, 28 | "y": null 29 | }, 30 | "mapping": { 31 | 32 | } 33 | } 34 | ], 35 | "dims": { 36 | "width": 631, 37 | "height": 400 38 | } 39 | } 40 | } 41 | }, 42 | "export": { 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01/tests/shinytest/mytest-expected-mac/002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/01/tests/shinytest/mytest-expected-mac/002.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01/tests/shinytest/mytest-expected-mac/003.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "bins": 22 4 | }, 5 | "output": { 6 | "distPlot": { 7 | "src": "[image data sha1: d7505b9166d013de01887deba9ffdb484ec3291d]", 8 | "width": 631, 9 | "height": 400, 10 | "alt": "Plot object", 11 | "coordmap": { 12 | "panels": [ 13 | { 14 | "domain": { 15 | "left": 40.88, 16 | "right": 98.12, 17 | "bottom": -1.48, 18 | "top": 38.48 19 | }, 20 | "range": { 21 | "left": 59.04, 22 | "right": 600.76, 23 | "bottom": 325.56, 24 | "top": 58.04 25 | }, 26 | "log": { 27 | "x": null, 28 | "y": null 29 | }, 30 | "mapping": { 31 | 32 | } 33 | } 34 | ], 35 | "dims": { 36 | "width": 631, 37 | "height": 400 38 | } 39 | } 40 | } 41 | }, 42 | "export": { 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01/tests/shinytest/mytest-expected-mac/003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/01/tests/shinytest/mytest-expected-mac/003.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01/tests/shinytest/mytest.R: -------------------------------------------------------------------------------- 1 | # Comment 2 | # app <- ShinyDriver$new("../../", seed = 100, shinyOptions = list(display.mode = "normal")) 3 | app <- 4 | ShinyDriver$new( 5 | 6 | "../../", seed = 100, shinyOptions = list(display.mode = "normal") 7 | ) 8 | 9 | app$snapshotInit( 10 | # Inner comment 11 | "mytest", 12 | screenshot = FALSE 13 | ) 14 | 15 | # Another comment 16 | # Only values 17 | app$snapshot() 18 | 19 | app$setInputs( 20 | bins = 21 | 8 22 | ) 23 | app$setInputs(bins = 9) 24 | # Values and screenshot 25 | app$snapshot(screenshot = TRUE) 26 | 27 | app$setInputs(bins = 5) 28 | app$setInputs(bins = 22) 29 | # Only values 30 | app$snapshot() 31 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01/tests/shinytest/othertest-expected/001.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "bins": 30 4 | }, 5 | "output": { 6 | "distPlot": { 7 | "src": "[image data sha1: fd386bc0dd417f05869d927c0f4fa9fe5306e814]", 8 | "width": 631, 9 | "height": 400, 10 | "alt": "Plot object", 11 | "coordmap": { 12 | "panels": [ 13 | { 14 | "domain": { 15 | "left": 40.88, 16 | "right": 98.12, 17 | "bottom": -1.08, 18 | "top": 28.08 19 | }, 20 | "range": { 21 | "left": 59.04, 22 | "right": 600.76, 23 | "bottom": 325.56, 24 | "top": 58.04 25 | }, 26 | "log": { 27 | "x": null, 28 | "y": null 29 | }, 30 | "mapping": { 31 | 32 | } 33 | } 34 | ], 35 | "dims": { 36 | "width": 631, 37 | "height": 400 38 | } 39 | } 40 | } 41 | }, 42 | "export": { 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01/tests/shinytest/othertest-expected/001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/01/tests/shinytest/othertest-expected/001.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01/tests/shinytest/othertest-expected/002.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "bins": 8 4 | }, 5 | "output": { 6 | "distPlot": { 7 | "src": "[image data sha1: 1f14fd9a1ba3953978442667cf8175a6e73a67d9]", 8 | "width": 631, 9 | "height": 400, 10 | "alt": "Plot object", 11 | "coordmap": { 12 | "panels": [ 13 | { 14 | "domain": { 15 | "left": 40.88, 16 | "right": 98.12, 17 | "bottom": -2.8, 18 | "top": 72.8 19 | }, 20 | "range": { 21 | "left": 59.04, 22 | "right": 600.76, 23 | "bottom": 325.56, 24 | "top": 58.04 25 | }, 26 | "log": { 27 | "x": null, 28 | "y": null 29 | }, 30 | "mapping": { 31 | 32 | } 33 | } 34 | ], 35 | "dims": { 36 | "width": 631, 37 | "height": 400 38 | } 39 | } 40 | } 41 | }, 42 | "export": { 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01/tests/shinytest/othertest-expected/002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/01/tests/shinytest/othertest-expected/002.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01/tests/shinytest/othertest-expected/003.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "bins": 22 4 | }, 5 | "output": { 6 | "distPlot": { 7 | "src": "[image data sha1: 13eef30f9dd6b201785abda9f556f3fbcdb50b75]", 8 | "width": 631, 9 | "height": 400, 10 | "alt": "Plot object", 11 | "coordmap": { 12 | "panels": [ 13 | { 14 | "domain": { 15 | "left": 40.88, 16 | "right": 98.12, 17 | "bottom": -1.48, 18 | "top": 38.48 19 | }, 20 | "range": { 21 | "left": 59.04, 22 | "right": 600.76, 23 | "bottom": 325.56, 24 | "top": 58.04 25 | }, 26 | "log": { 27 | "x": null, 28 | "y": null 29 | }, 30 | "mapping": { 31 | 32 | } 33 | } 34 | ], 35 | "dims": { 36 | "width": 631, 37 | "height": 400 38 | } 39 | } 40 | } 41 | }, 42 | "export": { 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01/tests/shinytest/othertest-expected/003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/01/tests/shinytest/othertest-expected/003.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01/tests/shinytest/othertest.R: -------------------------------------------------------------------------------- 1 | # Comment 2 | # app <- ShinyDriver$new("../../", seed = 100, shinyOptions = list(display.mode = "normal")) 3 | app <- ShinyDriver$new( 4 | 5 | "../../", seed = 100, shinyOptions = list(display.mode = "normal") 6 | ) 7 | 8 | # expect_pass(shinytest::testApp("../", suffix = osName(), compareImages = TRUE)) 9 | 10 | app$snapshotInit( 11 | # Inner comment 12 | "barret", 13 | screenshot = FALSE 14 | ) 15 | 16 | # Another comment 17 | app$snapshot(screenshot = FALSE) 18 | 19 | app$setInputs( 20 | bins = 21 | 8 22 | ) 23 | app$setInputs(bins = 9) 24 | app$snapshot(screenshot = TRUE) 25 | 26 | app$setInputs(bins = 5) 27 | app$setInputs(bins = 22) 28 | app$snapshot() 29 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01ex/app.R: -------------------------------------------------------------------------------- 1 | # Old Faithful 2 | library(shiny) 3 | 4 | 5 | # Define UI for app that draws a histogram ---- 6 | ui <- fluidPage( 7 | 8 | # App title ---- 9 | titlePanel("Hello Shiny!"), 10 | 11 | # Sidebar layout with input and output definitions ---- 12 | sidebarLayout( 13 | 14 | # Sidebar panel for inputs ---- 15 | sidebarPanel( 16 | 17 | # Input: Slider for the number of bins ---- 18 | sliderInput(inputId = "bins", 19 | label = "Number of bins:", 20 | min = 1, 21 | max = 50, 22 | value = 30) 23 | 24 | ), 25 | 26 | # Main panel for displaying outputs ---- 27 | mainPanel( 28 | 29 | # Output: Histogram ---- 30 | plotOutput(outputId = "dist") 31 | 32 | ) 33 | ) 34 | ) 35 | 36 | # Define server logic required to draw a histogram ---- 37 | server <- function(input, output, session) { 38 | 39 | x <- faithful$waiting 40 | 41 | bins <- reactive({ 42 | seq(min(x), max(x), length.out = input$bins + 1) 43 | }) 44 | 45 | output$dist <- renderPlot({ 46 | 47 | hist(x, breaks = bins(), col = "#75AADB", border = "white", 48 | xlab = "Waiting time to next eruption (in mins)", 49 | main = "Histogram of waiting times") 50 | 51 | }) 52 | 53 | } 54 | 55 | # Create Shiny app ---- 56 | shinyApp(ui = ui, server = server) 57 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01ex/tests/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01ex/tests/testthat/_snaps/mac/mytest/001.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "bins": 30 4 | }, 5 | "output": { 6 | "distPlot": { 7 | "src": "[image data sha1: e09d98e82336538663a2b938c92b52ae47ec366f]", 8 | "width": 631, 9 | "height": 400, 10 | "alt": "Plot object", 11 | "coordmap": { 12 | "panels": [ 13 | { 14 | "domain": { 15 | "left": 40.88, 16 | "right": 98.12, 17 | "bottom": -1.08, 18 | "top": 28.08 19 | }, 20 | "range": { 21 | "left": 59.04, 22 | "right": 600.76, 23 | "bottom": 325.56, 24 | "top": 58.04 25 | }, 26 | "log": { 27 | "x": null, 28 | "y": null 29 | }, 30 | "mapping": { 31 | 32 | } 33 | } 34 | ], 35 | "dims": { 36 | "width": 631, 37 | "height": 400 38 | } 39 | } 40 | } 41 | }, 42 | "export": { 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01ex/tests/testthat/_snaps/mac/mytest/002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/01ex/tests/testthat/_snaps/mac/mytest/002.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01ex/tests/testthat/_snaps/mac/mytest/003.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "bins": 8 4 | }, 5 | "output": { 6 | "distPlot": { 7 | "src": "[image data sha1: 145b2714251bd342b58c0e95913922469a596cc9]", 8 | "width": 631, 9 | "height": 400, 10 | "alt": "Plot object", 11 | "coordmap": { 12 | "panels": [ 13 | { 14 | "domain": { 15 | "left": 40.88, 16 | "right": 98.12, 17 | "bottom": -2.8, 18 | "top": 72.8 19 | }, 20 | "range": { 21 | "left": 59.04, 22 | "right": 600.76, 23 | "bottom": 325.56, 24 | "top": 58.04 25 | }, 26 | "log": { 27 | "x": null, 28 | "y": null 29 | }, 30 | "mapping": { 31 | 32 | } 33 | } 34 | ], 35 | "dims": { 36 | "width": 631, 37 | "height": 400 38 | } 39 | } 40 | } 41 | }, 42 | "export": { 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01ex/tests/testthat/_snaps/mac/mytest/004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/01ex/tests/testthat/_snaps/mac/mytest/004.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01ex/tests/testthat/_snaps/mac/mytest/005.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "bins": 22 4 | }, 5 | "output": { 6 | "distPlot": { 7 | "src": "[image data sha1: d7505b9166d013de01887deba9ffdb484ec3291d]", 8 | "width": 631, 9 | "height": 400, 10 | "alt": "Plot object", 11 | "coordmap": { 12 | "panels": [ 13 | { 14 | "domain": { 15 | "left": 40.88, 16 | "right": 98.12, 17 | "bottom": -1.48, 18 | "top": 38.48 19 | }, 20 | "range": { 21 | "left": 59.04, 22 | "right": 600.76, 23 | "bottom": 325.56, 24 | "top": 58.04 25 | }, 26 | "log": { 27 | "x": null, 28 | "y": null 29 | }, 30 | "mapping": { 31 | 32 | } 33 | } 34 | ], 35 | "dims": { 36 | "width": 631, 37 | "height": 400 38 | } 39 | } 40 | } 41 | }, 42 | "export": { 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01ex/tests/testthat/_snaps/mac/mytest/006.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/01ex/tests/testthat/_snaps/mac/mytest/006.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01ex/tests/testthat/_snaps/othertest/001.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "bins": 30 4 | }, 5 | "output": { 6 | "distPlot": { 7 | "src": "[image data sha1: fd386bc0dd417f05869d927c0f4fa9fe5306e814]", 8 | "width": 631, 9 | "height": 400, 10 | "alt": "Plot object", 11 | "coordmap": { 12 | "panels": [ 13 | { 14 | "domain": { 15 | "left": 40.88, 16 | "right": 98.12, 17 | "bottom": -1.08, 18 | "top": 28.08 19 | }, 20 | "range": { 21 | "left": 59.04, 22 | "right": 600.76, 23 | "bottom": 325.56, 24 | "top": 58.04 25 | }, 26 | "log": { 27 | "x": null, 28 | "y": null 29 | }, 30 | "mapping": { 31 | 32 | } 33 | } 34 | ], 35 | "dims": { 36 | "width": 631, 37 | "height": 400 38 | } 39 | } 40 | } 41 | }, 42 | "export": { 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01ex/tests/testthat/_snaps/othertest/002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/01ex/tests/testthat/_snaps/othertest/002.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01ex/tests/testthat/_snaps/othertest/003.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "bins": 8 4 | }, 5 | "output": { 6 | "distPlot": { 7 | "src": "[image data sha1: 1f14fd9a1ba3953978442667cf8175a6e73a67d9]", 8 | "width": 631, 9 | "height": 400, 10 | "alt": "Plot object", 11 | "coordmap": { 12 | "panels": [ 13 | { 14 | "domain": { 15 | "left": 40.88, 16 | "right": 98.12, 17 | "bottom": -2.8, 18 | "top": 72.8 19 | }, 20 | "range": { 21 | "left": 59.04, 22 | "right": 600.76, 23 | "bottom": 325.56, 24 | "top": 58.04 25 | }, 26 | "log": { 27 | "x": null, 28 | "y": null 29 | }, 30 | "mapping": { 31 | 32 | } 33 | } 34 | ], 35 | "dims": { 36 | "width": 631, 37 | "height": 400 38 | } 39 | } 40 | } 41 | }, 42 | "export": { 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01ex/tests/testthat/_snaps/othertest/004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/01ex/tests/testthat/_snaps/othertest/004.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01ex/tests/testthat/_snaps/othertest/005.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "bins": 22 4 | }, 5 | "output": { 6 | "distPlot": { 7 | "src": "[image data sha1: 13eef30f9dd6b201785abda9f556f3fbcdb50b75]", 8 | "width": 631, 9 | "height": 400, 10 | "alt": "Plot object", 11 | "coordmap": { 12 | "panels": [ 13 | { 14 | "domain": { 15 | "left": 40.88, 16 | "right": 98.12, 17 | "bottom": -1.48, 18 | "top": 38.48 19 | }, 20 | "range": { 21 | "left": 59.04, 22 | "right": 600.76, 23 | "bottom": 325.56, 24 | "top": 58.04 25 | }, 26 | "log": { 27 | "x": null, 28 | "y": null 29 | }, 30 | "mapping": { 31 | 32 | } 33 | } 34 | ], 35 | "dims": { 36 | "width": 631, 37 | "height": 400 38 | } 39 | } 40 | } 41 | }, 42 | "export": { 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01ex/tests/testthat/_snaps/othertest/006.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/01ex/tests/testthat/_snaps/othertest/006.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01ex/tests/testthat/test-comments-only.R: -------------------------------------------------------------------------------- 1 | # Comment line 1 2 | 3 | # Comment line 3 4 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01ex/tests/testthat/test-empty-file.R: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/01ex/tests/testthat/test-empty-file.R -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01ex/tests/testthat/test-mytest.R: -------------------------------------------------------------------------------- 1 | library(shinytest2) 2 | 3 | test_that("Migrated shinytest test: mytest.R", { 4 | # Comment 5 | # app <- ShinyDriver$new("../../", seed = 100, shinyOptions = list(display.mode = "normal")) 6 | app <- AppDriver$new(variant = osName(), seed = 100, shiny_args = list(display.mode = "normal")) 7 | 8 | 9 | # Another comment 10 | # Only values 11 | app$expect_values() 12 | 13 | app$set_inputs(bins = 8) 14 | app$set_inputs(bins = 9) 15 | # Values and screenshot 16 | app$expect_values() 17 | app$expect_screenshot() 18 | 19 | app$set_inputs(bins = 5) 20 | app$set_inputs(bins = 22) 21 | # Only values 22 | app$expect_values() 23 | }) 24 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/01ex/tests/testthat/test-othertest.R: -------------------------------------------------------------------------------- 1 | library(shinytest2) 2 | 3 | test_that("Migrated shinytest test: othertest.R", { 4 | # Comment 5 | # app <- ShinyDriver$new("../../", seed = 100, shinyOptions = list(display.mode = "normal")) 6 | app <- AppDriver$new(variant = osName(), seed = 100, shiny_args = list(display.mode = "normal")) 7 | 8 | # expect_pass(shinytest::testApp("../", suffix = osName(), compareImages = TRUE)) 9 | 10 | 11 | # Another comment 12 | app$expect_values() 13 | 14 | app$set_inputs(bins = 8) 15 | app$set_inputs(bins = 9) 16 | app$expect_values() 17 | app$expect_screenshot() 18 | 19 | app$set_inputs(bins = 5) 20 | app$set_inputs(bins = 22) 21 | app$expect_values() 22 | }) 23 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/02/tests/shinytest.R: -------------------------------------------------------------------------------- 1 | 2 | library(shinytest) 3 | expect_pass(testApp("../", suffix = shinytest2::platform_variant())) 4 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/02/tests/shinytest/mytest-expected-mac-4.0/001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/02/tests/shinytest/mytest-expected-mac-4.0/001.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/02/tests/shinytest/mytest-expected-mac-4.0/002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/02/tests/shinytest/mytest-expected-mac-4.0/002.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/02/tests/shinytest/mytest-expected-mac-4.1/001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/02/tests/shinytest/mytest-expected-mac-4.1/001.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/02/tests/shinytest/mytest-expected-mac-4.1/002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/02/tests/shinytest/mytest-expected-mac-4.1/002.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/02/tests/shinytest/mytest.R: -------------------------------------------------------------------------------- 1 | app <- ShinyDriver$new("../../", seed = 100, shinyOptions = list(display.mode = "normal")) 2 | app$snapshotInit("mytest") 3 | 4 | app$snapshot() 5 | app$setInputs(dataset = "pressure") 6 | app$setInputs(obs = 1000) 7 | app$snapshot() 8 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/02ex/tests/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/02ex/tests/testthat/_snaps/mac-4.0/mytest/002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/02ex/tests/testthat/_snaps/mac-4.0/mytest/002.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/02ex/tests/testthat/_snaps/mac-4.0/mytest/004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/02ex/tests/testthat/_snaps/mac-4.0/mytest/004.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/02ex/tests/testthat/_snaps/mac-4.1/mytest/002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/02ex/tests/testthat/_snaps/mac-4.1/mytest/002.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/02ex/tests/testthat/_snaps/mac-4.1/mytest/004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/02ex/tests/testthat/_snaps/mac-4.1/mytest/004.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/02ex/tests/testthat/test-mytest.R: -------------------------------------------------------------------------------- 1 | library(shinytest2) 2 | 3 | test_that("Migrated shinytest test: mytest.R", { 4 | app <- AppDriver$new(variant = shinytest2::platform_variant(), 5 | seed = 100, shiny_args = list(display.mode = "normal")) 6 | 7 | app$expect_values() 8 | app$expect_screenshot() 9 | app$set_inputs(dataset = "pressure") 10 | app$set_inputs(obs = 1000) 11 | app$expect_values() 12 | app$expect_screenshot() 13 | }) 14 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/05/tests/shinytest.R: -------------------------------------------------------------------------------- 1 | 2 | library(shinytest) 3 | expect_pass(testApp("../", suffix = shinytest2::platform_variant())) 4 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/05/tests/shinytest/mytest-expected-mac-4.0/001.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "animation": 1, 4 | "decimal": 1, 5 | "format": 0, 6 | "integer": 500, 7 | "range": [ 8 | 200, 9 | 500 10 | ] 11 | }, 12 | "output": { 13 | "values": "\n\n
Name <\/th> Value <\/th> <\/tr> <\/thead>
Integer <\/td> 500 <\/td> <\/tr>\n
Decimal <\/td> 1 <\/td> <\/tr>\n
Range <\/td> 200 500 <\/td> <\/tr>\n
Custom Format <\/td> 0 <\/td> <\/tr>\n
Animation <\/td> 1 <\/td> <\/tr>\n <\/tbody> <\/table>" 14 | }, 15 | "export": { 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/05/tests/shinytest/mytest-expected-mac-4.0/001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/05/tests/shinytest/mytest-expected-mac-4.0/001.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/05/tests/shinytest/mytest-expected-mac-4.0/002.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "animation": 1051, 4 | "decimal": 1, 5 | "format": 7500, 6 | "integer": 500, 7 | "range": [ 8 | 200, 9 | 1000 10 | ] 11 | }, 12 | "output": { 13 | "values": "\n\n
Name <\/th> Value <\/th> <\/tr> <\/thead>
Integer <\/td> 500 <\/td> <\/tr>\n
Decimal <\/td> 1 <\/td> <\/tr>\n
Range <\/td> 200 1000 <\/td> <\/tr>\n
Custom Format <\/td> 7500 <\/td> <\/tr>\n
Animation <\/td> 1051 <\/td> <\/tr>\n <\/tbody> <\/table>" 14 | }, 15 | "export": { 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/05/tests/shinytest/mytest-expected-mac-4.0/002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/05/tests/shinytest/mytest-expected-mac-4.0/002.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/05/tests/shinytest/mytest.R: -------------------------------------------------------------------------------- 1 | app <- ShinyDriver$new("../../", seed = 100, shinyOptions = list(display.mode = "normal")) 2 | app$snapshotInit("mytest") 3 | 4 | app$setInputs(decimal = 1) 5 | app$snapshot() 6 | app$setInputs(range = c(200, 1000)) 7 | app$setInputs(format = 7500) 8 | app$setInputs(animation = 1051) 9 | app$snapshot() 10 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/05/tests/testthat.R: -------------------------------------------------------------------------------- 1 | # Not shinytest2::test_app() 2 | shinycoreci::test_testhat_app() 3 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/05/tests/testthat/test-shiny.R: -------------------------------------------------------------------------------- 1 | context("app") 2 | 3 | test_that("inputs are stored", { 4 | testServer(expr = { 5 | session$setInputs( 6 | integer = 593, 7 | decimal = 0.6, 8 | range = c(100, 300), 9 | format = 5000, 10 | animation = 100 11 | ) 12 | 13 | # The data frame should have these properties 14 | df <- slider_values() 15 | expect_equal(nrow(df), 5) 16 | expect_equal(ncol(df), 2) 17 | expect_is(df$Value, "character") 18 | 19 | # Updating an input should result in a new plot 20 | plot1 <- output$values 21 | session$setInputs(integer = 594) 22 | plot2 <- output$values 23 | expect_true(plot1 != plot2) 24 | }) 25 | }) 26 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/05ex/tests/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/05ex/tests/testthat/_snaps/mac-4.0/mytest/001.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "animation": 1, 4 | "decimal": 1, 5 | "format": 0, 6 | "integer": 500, 7 | "range": [ 8 | 200, 9 | 500 10 | ] 11 | }, 12 | "output": { 13 | "values": "\n\n
Name <\/th> Value <\/th> <\/tr> <\/thead>
Integer <\/td> 500 <\/td> <\/tr>\n
Decimal <\/td> 1 <\/td> <\/tr>\n
Range <\/td> 200 500 <\/td> <\/tr>\n
Custom Format <\/td> 0 <\/td> <\/tr>\n
Animation <\/td> 1 <\/td> <\/tr>\n <\/tbody> <\/table>" 14 | }, 15 | "export": { 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/05ex/tests/testthat/_snaps/mac-4.0/mytest/002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/05ex/tests/testthat/_snaps/mac-4.0/mytest/002.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/05ex/tests/testthat/_snaps/mac-4.0/mytest/003.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "animation": 1051, 4 | "decimal": 1, 5 | "format": 7500, 6 | "integer": 500, 7 | "range": [ 8 | 200, 9 | 1000 10 | ] 11 | }, 12 | "output": { 13 | "values": "\n\n
Name <\/th> Value <\/th> <\/tr> <\/thead>
Integer <\/td> 500 <\/td> <\/tr>\n
Decimal <\/td> 1 <\/td> <\/tr>\n
Range <\/td> 200 1000 <\/td> <\/tr>\n
Custom Format <\/td> 7500 <\/td> <\/tr>\n
Animation <\/td> 1051 <\/td> <\/tr>\n <\/tbody> <\/table>" 14 | }, 15 | "export": { 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/05ex/tests/testthat/_snaps/mac-4.0/mytest/004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/05ex/tests/testthat/_snaps/mac-4.0/mytest/004.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/05ex/tests/testthat/test-mytest.R: -------------------------------------------------------------------------------- 1 | library(shinytest2) 2 | 3 | test_that("Migrated shinytest test: mytest.R", { 4 | app <- AppDriver$new(variant = shinytest2::platform_variant(), 5 | seed = 100, shiny_args = list(display.mode = "normal")) 6 | 7 | app$set_inputs(decimal = 1) 8 | app$expect_values() 9 | app$expect_screenshot() 10 | app$set_inputs(range = c(200, 1000)) 11 | app$set_inputs(format = 7500) 12 | app$set_inputs(animation = 1051) 13 | app$expect_values() 14 | app$expect_screenshot() 15 | }) 16 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/05ex/tests/testthat/test-shiny.R: -------------------------------------------------------------------------------- 1 | context("app") 2 | 3 | test_that("inputs are stored", { 4 | testServer(expr = { 5 | session$setInputs( 6 | integer = 593, 7 | decimal = 0.6, 8 | range = c(100, 300), 9 | format = 5000, 10 | animation = 100 11 | ) 12 | 13 | # The data frame should have these properties 14 | df <- slider_values() 15 | expect_equal(nrow(df), 5) 16 | expect_equal(ncol(df), 2) 17 | expect_is(df$Value, "character") 18 | 19 | # Updating an input should result in a new plot 20 | plot1 <- output$values 21 | session$setInputs(integer = 594) 22 | plot2 <- output$values 23 | expect_true(plot1 != plot2) 24 | }) 25 | }) 26 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/08/app.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | # Define server logic for random distribution app ---- 4 | server <- function(input, output) { 5 | 6 | # Reactive expression to generate the requested distribution ---- 7 | # This is called whenever the inputs change. The output functions 8 | # defined below then use the value computed from this expression 9 | d <- reactive({ 10 | dist <- switch(input$dist, 11 | norm = rnorm, 12 | unif = runif, 13 | lnorm = rlnorm, 14 | exp = rexp, 15 | rnorm) 16 | 17 | dist(input$n) 18 | }) 19 | 20 | # Generate a plot of the data ---- 21 | # Also uses the inputs to build the plot label. Note that the 22 | # dependencies on the inputs and the data reactive expression are 23 | # both tracked, and all expressions are called in the sequence 24 | # implied by the dependency graph. 25 | output$plot <- renderPlot({ 26 | dist <- input$dist 27 | n <- input$n 28 | 29 | hist(d(), 30 | main = paste("r", dist, "(", n, ")", sep = ""), 31 | col = "#75AADB", border = "white") 32 | }) 33 | 34 | # Generate a summary of the data ---- 35 | output$summary <- renderPrint({ 36 | summary(d()) 37 | }) 38 | 39 | # Generate an HTML table view of the head of the data ---- 40 | output$table <- renderTable({ 41 | head(data.frame(x = d(), stringsAsFactors = FALSE)) 42 | }) 43 | 44 | } 45 | 46 | # Create Shiny app ---- 47 | shinyApp(ui = htmlTemplate("www/index.html"), server) 48 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/08/tests/shinytest.R: -------------------------------------------------------------------------------- 1 | 2 | library(shinytest) 3 | expect_pass(testApp("../", suffix = shinytest2::platform_variant())) 4 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/08/tests/shinytest/mytest-expected-mac-4.0/001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/08/tests/shinytest/mytest-expected-mac-4.0/001.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/08/tests/shinytest/mytest.R: -------------------------------------------------------------------------------- 1 | app <- ShinyDriver$new("../../", seed = 100, shinyOptions = list(display.mode = "normal")) 2 | app$snapshotInit("mytest") 3 | app$snapshot() 4 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/08/www/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |

HTML UI

12 | 13 |

14 |
15 | 21 |

22 | 23 |

24 | 25 |
26 | 27 | 28 |

29 | 30 |

Summary of data:

31 |

32 | 
33 |   

Plot of data:

34 |
36 | 37 |

Head of data:

38 |
39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/08ex/app.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | # Define server logic for random distribution app ---- 4 | server <- function(input, output) { 5 | 6 | # Reactive expression to generate the requested distribution ---- 7 | # This is called whenever the inputs change. The output functions 8 | # defined below then use the value computed from this expression 9 | d <- reactive({ 10 | dist <- switch(input$dist, 11 | norm = rnorm, 12 | unif = runif, 13 | lnorm = rlnorm, 14 | exp = rexp, 15 | rnorm) 16 | 17 | dist(input$n) 18 | }) 19 | 20 | # Generate a plot of the data ---- 21 | # Also uses the inputs to build the plot label. Note that the 22 | # dependencies on the inputs and the data reactive expression are 23 | # both tracked, and all expressions are called in the sequence 24 | # implied by the dependency graph. 25 | output$plot <- renderPlot({ 26 | dist <- input$dist 27 | n <- input$n 28 | 29 | hist(d(), 30 | main = paste("r", dist, "(", n, ")", sep = ""), 31 | col = "#75AADB", border = "white") 32 | }) 33 | 34 | # Generate a summary of the data ---- 35 | output$summary <- renderPrint({ 36 | summary(d()) 37 | }) 38 | 39 | # Generate an HTML table view of the head of the data ---- 40 | output$table <- renderTable({ 41 | head(data.frame(x = d(), stringsAsFactors = FALSE)) 42 | }) 43 | 44 | } 45 | 46 | # Create Shiny app ---- 47 | shinyApp(ui = htmlTemplate("www/index.html"), server) 48 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/08ex/tests/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/08ex/tests/testthat/_snaps/mac-4.0/mytest/002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/08ex/tests/testthat/_snaps/mac-4.0/mytest/002.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/08ex/tests/testthat/test-mytest.R: -------------------------------------------------------------------------------- 1 | library(shinytest2) 2 | 3 | test_that("Migrated shinytest test: mytest.R", { 4 | app <- AppDriver$new(variant = shinytest2::platform_variant(), 5 | seed = 100, shiny_args = list(display.mode = "normal")) 6 | app$expect_values() 7 | app$expect_screenshot() 8 | }) 9 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/08ex/www/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |

HTML UI

12 | 13 |

14 |
15 | 21 |

22 | 23 |

24 | 25 |
26 | 27 | 28 |

29 | 30 |

Summary of data:

31 |

32 | 
33 |   

Plot of data:

34 |
36 | 37 |

Head of data:

38 |
39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/09/tests/shinytest.R: -------------------------------------------------------------------------------- 1 | 2 | library(shinytest) 3 | expect_pass(testApp("../", suffix = shinytest2::platform_variant())) 4 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/09/tests/shinytest/Rock.csv: -------------------------------------------------------------------------------- 1 | "area","peri","shape","perm" 2 | 4990,2791.9,0.0903296,6.3 3 | 7002,3892.6,0.148622,6.3 4 | 7558,3930.66,0.183312,6.3 5 | 7352,3869.32,0.117063,6.3 6 | 7943,3948.54,0.122417,17.1 7 | 7979,4010.15,0.167045,17.1 8 | 9333,4345.75,0.189651,17.1 9 | 8209,4344.75,0.164127,17.1 10 | 8393,3682.04,0.203654,119 11 | 6425,3098.65,0.162394,119 12 | 9364,4480.05,0.150944,119 13 | 8624,3986.24,0.148141,119 14 | 10651,4036.54,0.228595,82.4 15 | 8868,3518.04,0.231623,82.4 16 | 9417,3999.37,0.172567,82.4 17 | 8874,3629.07,0.153481,82.4 18 | 10962,4608.66,0.204314,58.6 19 | 10743,4787.62,0.262727,58.6 20 | 11878,4864.22,0.200071,58.6 21 | 9867,4479.41,0.14481,58.6 22 | 7838,3428.74,0.113852,142 23 | 11876,4353.14,0.291029,142 24 | 12212,4697.65,0.240077,142 25 | 8233,3518.44,0.161865,142 26 | 6360,1977.39,0.280887,740 27 | 4193,1379.35,0.179455,740 28 | 7416,1916.24,0.191802,740 29 | 5246,1585.42,0.133083,740 30 | 6509,1851.21,0.225214,890 31 | 4895,1239.66,0.341273,890 32 | 6775,1728.14,0.311646,890 33 | 7894,1461.06,0.276016,890 34 | 5980,1426.76,0.197653,950 35 | 5318,990.388,0.326635,950 36 | 7392,1350.76,0.154192,950 37 | 7894,1461.06,0.276016,950 38 | 3469,1376.7,0.176969,100 39 | 1468,476.322,0.438712,100 40 | 3524,1189.46,0.163586,100 41 | 5267,1644.96,0.253832,100 42 | 5048,941.543,0.328641,1300 43 | 1016,308.642,0.230081,1300 44 | 5605,1145.69,0.464125,1300 45 | 8793,2280.49,0.420477,1300 46 | 3475,1174.11,0.200744,580 47 | 1651,597.808,0.262651,580 48 | 5514,1455.88,0.182453,580 49 | 9718,1485.58,0.200447,580 50 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/09/tests/shinytest/mytest-expected-mac-4.0/001.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "disp": "head", 4 | "file1": { 5 | "name": [ 6 | "Rock.csv" 7 | ], 8 | "size": [ 9 | 1296 10 | ], 11 | "type": [ 12 | "text/csv" 13 | ], 14 | "datapath": [ 15 | "0.csv" 16 | ] 17 | }, 18 | "header": true, 19 | "quote": "\"", 20 | "sep": "," 21 | }, 22 | "output": { 23 | "contents": "\n\n
area <\/th> peri <\/th> shape <\/th> perm <\/th> <\/tr> <\/thead>
4990 <\/td> 2791.90 <\/td> 0.09 <\/td> 6.30 <\/td> <\/tr>\n
7002 <\/td> 3892.60 <\/td> 0.15 <\/td> 6.30 <\/td> <\/tr>\n
7558 <\/td> 3930.66 <\/td> 0.18 <\/td> 6.30 <\/td> <\/tr>\n
7352 <\/td> 3869.32 <\/td> 0.12 <\/td> 6.30 <\/td> <\/tr>\n
7943 <\/td> 3948.54 <\/td> 0.12 <\/td> 17.10 <\/td> <\/tr>\n
7979 <\/td> 4010.15 <\/td> 0.17 <\/td> 17.10 <\/td> <\/tr>\n <\/tbody> <\/table>" 24 | }, 25 | "export": { 26 | 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/09/tests/shinytest/mytest-expected-mac-4.0/001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/09/tests/shinytest/mytest-expected-mac-4.0/001.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/09/tests/shinytest/mytest-expected-mac-4.0/002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/09/tests/shinytest/mytest-expected-mac-4.0/002.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/09/tests/shinytest/mytest.R: -------------------------------------------------------------------------------- 1 | app <- ShinyDriver$new("../../", seed = 100, shinyOptions = list(display.mode = "normal")) 2 | app$snapshotInit("mytest") 3 | 4 | app$uploadFile(file1 = "Rock.csv") 5 | app$snapshot() 6 | app$uploadFile(file1 = "other/Rock.csv") 7 | app$snapshot() 8 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/09/tests/shinytest/other/Rock.csv: -------------------------------------------------------------------------------- 1 | "area","peri","shape","perm" 2 | 4990,2791.9,0.0903296,6.3 3 | 7002,3892.6,0.148622,6.3 4 | 7558,3930.66,0.183312,6.3 5 | 7352,3869.32,0.117063,6.3 6 | 7943,3948.54,0.122417,17.1 7 | 7979,4010.15,0.167045,17.1 8 | 9333,4345.75,0.189651,17.1 9 | 8209,4344.75,0.164127,17.1 10 | 8393,3682.04,0.203654,119 11 | 6425,3098.65,0.162394,119 12 | 9364,4480.05,0.150944,119 13 | 8624,3986.24,0.148141,119 14 | 10651,4036.54,0.228595,82.4 15 | 8868,3518.04,0.231623,82.4 16 | 9417,3999.37,0.172567,82.4 17 | 8874,3629.07,0.153481,82.4 18 | 10962,4608.66,0.204314,58.6 19 | 10743,4787.62,0.262727,58.6 20 | 11878,4864.22,0.200071,58.6 21 | 9867,4479.41,0.14481,58.6 22 | 7838,3428.74,0.113852,142 23 | 11876,4353.14,0.291029,142 24 | 12212,4697.65,0.240077,142 25 | 8233,3518.44,0.161865,142 26 | 6360,1977.39,0.280887,740 27 | 4193,1379.35,0.179455,740 28 | 7416,1916.24,0.191802,740 29 | 5246,1585.42,0.133083,740 30 | 6509,1851.21,0.225214,890 31 | 4895,1239.66,0.341273,890 32 | 6775,1728.14,0.311646,890 33 | 7894,1461.06,0.276016,890 34 | 5980,1426.76,0.197653,950 35 | 5318,990.388,0.326635,950 36 | 7392,1350.76,0.154192,950 37 | 7894,1461.06,0.276016,950 38 | 3469,1376.7,0.176969,100 39 | 1468,476.322,0.438712,100 40 | 3524,1189.46,0.163586,100 41 | 5267,1644.96,0.253832,100 42 | 5048,941.543,0.328641,1300 43 | 1016,308.642,0.230081,1300 44 | 5605,1145.69,0.464125,1300 45 | 8793,2280.49,0.420477,1300 46 | 3475,1174.11,0.200744,580 47 | 1651,597.808,0.262651,580 48 | 5514,1455.88,0.182453,580 49 | 9718,1485.58,0.200447,580 50 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/09ex/tests/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/09ex/tests/testthat/Rock.csv: -------------------------------------------------------------------------------- 1 | "area","peri","shape","perm" 2 | 4990,2791.9,0.0903296,6.3 3 | 7002,3892.6,0.148622,6.3 4 | 7558,3930.66,0.183312,6.3 5 | 7352,3869.32,0.117063,6.3 6 | 7943,3948.54,0.122417,17.1 7 | 7979,4010.15,0.167045,17.1 8 | 9333,4345.75,0.189651,17.1 9 | 8209,4344.75,0.164127,17.1 10 | 8393,3682.04,0.203654,119 11 | 6425,3098.65,0.162394,119 12 | 9364,4480.05,0.150944,119 13 | 8624,3986.24,0.148141,119 14 | 10651,4036.54,0.228595,82.4 15 | 8868,3518.04,0.231623,82.4 16 | 9417,3999.37,0.172567,82.4 17 | 8874,3629.07,0.153481,82.4 18 | 10962,4608.66,0.204314,58.6 19 | 10743,4787.62,0.262727,58.6 20 | 11878,4864.22,0.200071,58.6 21 | 9867,4479.41,0.14481,58.6 22 | 7838,3428.74,0.113852,142 23 | 11876,4353.14,0.291029,142 24 | 12212,4697.65,0.240077,142 25 | 8233,3518.44,0.161865,142 26 | 6360,1977.39,0.280887,740 27 | 4193,1379.35,0.179455,740 28 | 7416,1916.24,0.191802,740 29 | 5246,1585.42,0.133083,740 30 | 6509,1851.21,0.225214,890 31 | 4895,1239.66,0.341273,890 32 | 6775,1728.14,0.311646,890 33 | 7894,1461.06,0.276016,890 34 | 5980,1426.76,0.197653,950 35 | 5318,990.388,0.326635,950 36 | 7392,1350.76,0.154192,950 37 | 7894,1461.06,0.276016,950 38 | 3469,1376.7,0.176969,100 39 | 1468,476.322,0.438712,100 40 | 3524,1189.46,0.163586,100 41 | 5267,1644.96,0.253832,100 42 | 5048,941.543,0.328641,1300 43 | 1016,308.642,0.230081,1300 44 | 5605,1145.69,0.464125,1300 45 | 8793,2280.49,0.420477,1300 46 | 3475,1174.11,0.200744,580 47 | 1651,597.808,0.262651,580 48 | 5514,1455.88,0.182453,580 49 | 9718,1485.58,0.200447,580 50 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/09ex/tests/testthat/_snaps/mac-4.0/mytest/002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/09ex/tests/testthat/_snaps/mac-4.0/mytest/002.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/09ex/tests/testthat/_snaps/mac-4.0/mytest/004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/09ex/tests/testthat/_snaps/mac-4.0/mytest/004.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/09ex/tests/testthat/other/Rock.csv: -------------------------------------------------------------------------------- 1 | "area","peri","shape","perm" 2 | 4990,2791.9,0.0903296,6.3 3 | 7002,3892.6,0.148622,6.3 4 | 7558,3930.66,0.183312,6.3 5 | 7352,3869.32,0.117063,6.3 6 | 7943,3948.54,0.122417,17.1 7 | 7979,4010.15,0.167045,17.1 8 | 9333,4345.75,0.189651,17.1 9 | 8209,4344.75,0.164127,17.1 10 | 8393,3682.04,0.203654,119 11 | 6425,3098.65,0.162394,119 12 | 9364,4480.05,0.150944,119 13 | 8624,3986.24,0.148141,119 14 | 10651,4036.54,0.228595,82.4 15 | 8868,3518.04,0.231623,82.4 16 | 9417,3999.37,0.172567,82.4 17 | 8874,3629.07,0.153481,82.4 18 | 10962,4608.66,0.204314,58.6 19 | 10743,4787.62,0.262727,58.6 20 | 11878,4864.22,0.200071,58.6 21 | 9867,4479.41,0.14481,58.6 22 | 7838,3428.74,0.113852,142 23 | 11876,4353.14,0.291029,142 24 | 12212,4697.65,0.240077,142 25 | 8233,3518.44,0.161865,142 26 | 6360,1977.39,0.280887,740 27 | 4193,1379.35,0.179455,740 28 | 7416,1916.24,0.191802,740 29 | 5246,1585.42,0.133083,740 30 | 6509,1851.21,0.225214,890 31 | 4895,1239.66,0.341273,890 32 | 6775,1728.14,0.311646,890 33 | 7894,1461.06,0.276016,890 34 | 5980,1426.76,0.197653,950 35 | 5318,990.388,0.326635,950 36 | 7392,1350.76,0.154192,950 37 | 7894,1461.06,0.276016,950 38 | 3469,1376.7,0.176969,100 39 | 1468,476.322,0.438712,100 40 | 3524,1189.46,0.163586,100 41 | 5267,1644.96,0.253832,100 42 | 5048,941.543,0.328641,1300 43 | 1016,308.642,0.230081,1300 44 | 5605,1145.69,0.464125,1300 45 | 8793,2280.49,0.420477,1300 46 | 3475,1174.11,0.200744,580 47 | 1651,597.808,0.262651,580 48 | 5514,1455.88,0.182453,580 49 | 9718,1485.58,0.200447,580 50 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/09ex/tests/testthat/test-mytest.R: -------------------------------------------------------------------------------- 1 | library(shinytest2) 2 | 3 | test_that("Migrated shinytest test: mytest.R", { 4 | app <- AppDriver$new(variant = shinytest2::platform_variant(), 5 | seed = 100, shiny_args = list(display.mode = "normal")) 6 | 7 | app$upload_file(file1 = "Rock.csv") 8 | app$expect_values() 9 | app$expect_screenshot() 10 | app$upload_file(file1 = "other/Rock.csv") 11 | app$expect_values() 12 | app$expect_screenshot() 13 | }) 14 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/10/app.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | # Define UI for data download app ---- 4 | ui <- fluidPage( 5 | 6 | # App title ---- 7 | titlePanel("Downloading Data"), 8 | 9 | # Sidebar layout with input and output definitions ---- 10 | sidebarLayout( 11 | 12 | # Sidebar panel for inputs ---- 13 | sidebarPanel( 14 | 15 | # Input: Choose dataset ---- 16 | selectInput("dataset", "Choose a dataset:", 17 | choices = c("rock", "pressure", "cars")), 18 | 19 | # Button 20 | downloadButton("download_data", "Download") 21 | 22 | ), 23 | 24 | # Main panel for displaying outputs ---- 25 | mainPanel( 26 | 27 | tableOutput("table") 28 | 29 | ) 30 | 31 | ) 32 | ) 33 | 34 | # Define server logic to display and download selected file ---- 35 | server <- function(input, output) { 36 | 37 | # Reactive value for selected dataset ---- 38 | dataset_input <- reactive({ 39 | dt <- switch(input$dataset, 40 | "rock" = rock, 41 | "pressure" = pressure, 42 | "cars" = cars) 43 | head(dt, 10) 44 | }) 45 | 46 | # Table of selected dataset ---- 47 | output$table <- renderTable({ 48 | dataset_input() 49 | }) 50 | 51 | # Downloadable csv of selected dataset ---- 52 | output$download_data <- downloadHandler( 53 | filename = function() { 54 | paste(input$dataset, ".csv", sep = "") 55 | }, 56 | content = function(file) { 57 | write.csv(dataset_input(), file, row.names = FALSE) 58 | } 59 | ) 60 | 61 | } 62 | 63 | # Create Shiny app ---- 64 | shinyApp(ui, server) 65 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/10/tests/shinytest.R: -------------------------------------------------------------------------------- 1 | 2 | library(shinytest) 3 | expect_pass(testApp("../", suffix = shinytest2::platform_variant())) 4 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/10/tests/shinytest/mytest-expected-mac-4.0/001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/10/tests/shinytest/mytest-expected-mac-4.0/001.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/10/tests/shinytest/mytest-expected-mac-4.0/002.download: -------------------------------------------------------------------------------- 1 | "speed","dist" 2 | 4,2 3 | 4,10 4 | 7,4 5 | 7,22 6 | 8,16 7 | 9,10 8 | 10,18 9 | 10,26 10 | 10,34 11 | 11,17 12 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/10/tests/shinytest/mytest-expected-mac-4.0/003.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "dataset": "cars" 4 | }, 5 | "output": { 6 | "table": "\n\n
speed <\/th> dist <\/th> <\/tr> <\/thead>
4.00 <\/td> 2.00 <\/td> <\/tr>\n
4.00 <\/td> 10.00 <\/td> <\/tr>\n
7.00 <\/td> 4.00 <\/td> <\/tr>\n
7.00 <\/td> 22.00 <\/td> <\/tr>\n
8.00 <\/td> 16.00 <\/td> <\/tr>\n
9.00 <\/td> 10.00 <\/td> <\/tr>\n
10.00 <\/td> 18.00 <\/td> <\/tr>\n
10.00 <\/td> 26.00 <\/td> <\/tr>\n
10.00 <\/td> 34.00 <\/td> <\/tr>\n
11.00 <\/td> 17.00 <\/td> <\/tr>\n <\/tbody> <\/table>" 7 | }, 8 | "export": { 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/10/tests/shinytest/mytest-expected-mac-4.0/003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/10/tests/shinytest/mytest-expected-mac-4.0/003.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/10/tests/shinytest/mytest-expected-mac-4.0/004.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "dataset": "pressure" 4 | }, 5 | "output": { 6 | "table": "\n\n
temperature <\/th> pressure <\/th> <\/tr> <\/thead>
0.00 <\/td> 0.00 <\/td> <\/tr>\n
20.00 <\/td> 0.00 <\/td> <\/tr>\n
40.00 <\/td> 0.01 <\/td> <\/tr>\n
60.00 <\/td> 0.03 <\/td> <\/tr>\n
80.00 <\/td> 0.09 <\/td> <\/tr>\n
100.00 <\/td> 0.27 <\/td> <\/tr>\n
120.00 <\/td> 0.75 <\/td> <\/tr>\n
140.00 <\/td> 1.85 <\/td> <\/tr>\n
160.00 <\/td> 4.20 <\/td> <\/tr>\n
180.00 <\/td> 8.80 <\/td> <\/tr>\n <\/tbody> <\/table>" 7 | }, 8 | "export": { 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/10/tests/shinytest/mytest-expected-mac-4.0/004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/10/tests/shinytest/mytest-expected-mac-4.0/004.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/10/tests/shinytest/mytest-expected-mac-4.0/005.download: -------------------------------------------------------------------------------- 1 | "temperature","pressure" 2 | 0,2e-04 3 | 20,0.0012 4 | 40,0.006 5 | 60,0.03 6 | 80,0.09 7 | 100,0.27 8 | 120,0.75 9 | 140,1.85 10 | 160,4.2 11 | 180,8.8 12 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/10/tests/shinytest/mytest.R: -------------------------------------------------------------------------------- 1 | app <- ShinyDriver$new("../../", seed = 100, shinyOptions = list(display.mode = "normal")) 2 | app$snapshotInit("mytest") 3 | 4 | app$snapshot() 5 | app$setInputs(dataset = "pressure") 6 | app$setInputs(dataset = "cars") 7 | app$snapshotDownload("download_data") 8 | app$snapshot() 9 | app$setInputs(dataset = "pressure") 10 | app$snapshot() 11 | app$snapshotDownload("download_data") 12 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/10ex/app.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | # Define UI for data download app ---- 4 | ui <- fluidPage( 5 | 6 | # App title ---- 7 | titlePanel("Downloading Data"), 8 | 9 | # Sidebar layout with input and output definitions ---- 10 | sidebarLayout( 11 | 12 | # Sidebar panel for inputs ---- 13 | sidebarPanel( 14 | 15 | # Input: Choose dataset ---- 16 | selectInput("dataset", "Choose a dataset:", 17 | choices = c("rock", "pressure", "cars")), 18 | 19 | # Button 20 | downloadButton("download_data", "Download") 21 | 22 | ), 23 | 24 | # Main panel for displaying outputs ---- 25 | mainPanel( 26 | 27 | tableOutput("table") 28 | 29 | ) 30 | 31 | ) 32 | ) 33 | 34 | # Define server logic to display and download selected file ---- 35 | server <- function(input, output) { 36 | 37 | # Reactive value for selected dataset ---- 38 | dataset_input <- reactive({ 39 | dt <- switch(input$dataset, 40 | "rock" = rock, 41 | "pressure" = pressure, 42 | "cars" = cars) 43 | head(dt, 10) 44 | }) 45 | 46 | # Table of selected dataset ---- 47 | output$table <- renderTable({ 48 | dataset_input() 49 | }) 50 | 51 | # Downloadable csv of selected dataset ---- 52 | output$download_data <- downloadHandler( 53 | filename = function() { 54 | paste(input$dataset, ".csv", sep = "") 55 | }, 56 | content = function(file) { 57 | write.csv(dataset_input(), file, row.names = FALSE) 58 | } 59 | ) 60 | 61 | } 62 | 63 | # Create Shiny app ---- 64 | shinyApp(ui, server) 65 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/10ex/tests/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/10ex/tests/testthat/_snaps/mac-4.0/mytest/002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/10ex/tests/testthat/_snaps/mac-4.0/mytest/002.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/10ex/tests/testthat/_snaps/mac-4.0/mytest/003.download: -------------------------------------------------------------------------------- 1 | "speed","dist" 2 | 4,2 3 | 4,10 4 | 7,4 5 | 7,22 6 | 8,16 7 | 9,10 8 | 10,18 9 | 10,26 10 | 10,34 11 | 11,17 12 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/10ex/tests/testthat/_snaps/mac-4.0/mytest/004.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "dataset": "cars" 4 | }, 5 | "output": { 6 | "table": "\n\n
speed <\/th> dist <\/th> <\/tr> <\/thead>
4.00 <\/td> 2.00 <\/td> <\/tr>\n
4.00 <\/td> 10.00 <\/td> <\/tr>\n
7.00 <\/td> 4.00 <\/td> <\/tr>\n
7.00 <\/td> 22.00 <\/td> <\/tr>\n
8.00 <\/td> 16.00 <\/td> <\/tr>\n
9.00 <\/td> 10.00 <\/td> <\/tr>\n
10.00 <\/td> 18.00 <\/td> <\/tr>\n
10.00 <\/td> 26.00 <\/td> <\/tr>\n
10.00 <\/td> 34.00 <\/td> <\/tr>\n
11.00 <\/td> 17.00 <\/td> <\/tr>\n <\/tbody> <\/table>" 7 | }, 8 | "export": { 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/10ex/tests/testthat/_snaps/mac-4.0/mytest/005.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/10ex/tests/testthat/_snaps/mac-4.0/mytest/005.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/10ex/tests/testthat/_snaps/mac-4.0/mytest/006.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "dataset": "pressure" 4 | }, 5 | "output": { 6 | "table": "\n\n
temperature <\/th> pressure <\/th> <\/tr> <\/thead>
0.00 <\/td> 0.00 <\/td> <\/tr>\n
20.00 <\/td> 0.00 <\/td> <\/tr>\n
40.00 <\/td> 0.01 <\/td> <\/tr>\n
60.00 <\/td> 0.03 <\/td> <\/tr>\n
80.00 <\/td> 0.09 <\/td> <\/tr>\n
100.00 <\/td> 0.27 <\/td> <\/tr>\n
120.00 <\/td> 0.75 <\/td> <\/tr>\n
140.00 <\/td> 1.85 <\/td> <\/tr>\n
160.00 <\/td> 4.20 <\/td> <\/tr>\n
180.00 <\/td> 8.80 <\/td> <\/tr>\n <\/tbody> <\/table>" 7 | }, 8 | "export": { 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/10ex/tests/testthat/_snaps/mac-4.0/mytest/007.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/tests/testthat/migrate-apps/10ex/tests/testthat/_snaps/mac-4.0/mytest/007.png -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/10ex/tests/testthat/_snaps/mac-4.0/mytest/008.download: -------------------------------------------------------------------------------- 1 | "temperature","pressure" 2 | 0,2e-04 3 | 20,0.0012 4 | 40,0.006 5 | 60,0.03 6 | 80,0.09 7 | 100,0.27 8 | 120,0.75 9 | 140,1.85 10 | 160,4.2 11 | 180,8.8 12 | -------------------------------------------------------------------------------- /tests/testthat/migrate-apps/10ex/tests/testthat/test-mytest.R: -------------------------------------------------------------------------------- 1 | library(shinytest2) 2 | 3 | test_that("Migrated shinytest test: mytest.R", { 4 | app <- AppDriver$new(variant = shinytest2::platform_variant(), 5 | seed = 100, shiny_args = list(display.mode = "normal")) 6 | 7 | app$expect_values() 8 | app$expect_screenshot() 9 | app$set_inputs(dataset = "pressure") 10 | app$set_inputs(dataset = "cars") 11 | app$expect_download("download_data") 12 | app$expect_values() 13 | app$expect_screenshot() 14 | app$set_inputs(dataset = "pressure") 15 | app$expect_values() 16 | app$expect_screenshot() 17 | app$expect_download("download_data") 18 | }) 19 | -------------------------------------------------------------------------------- /tests/testthat/scripts/issue_295.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | my_mod_ui <- function(id) { 4 | ns <- NS(id) 5 | tagList( 6 | textInput(ns("name"), "name", "test"), 7 | textOutput(ns("greet")) 8 | ) 9 | } 10 | 11 | my_mod_server <- function(id) { 12 | moduleServer(id, function(input, output, session) { 13 | output$greet <- renderText(input$name) 14 | }) 15 | } 16 | 17 | make_app2 <- function(mod_ui, mod_server_gen) { 18 | force(mod_server_gen) 19 | shiny::shinyApp( 20 | shiny::fluidPage(mod_ui), 21 | function(input, output, session) mod_server_gen() 22 | ) 23 | } 24 | 25 | app <- make_app2( 26 | my_mod_ui("test"), 27 | function() { 28 | my_mod_server("test") 29 | } 30 | ) 31 | 32 | driver <- shinytest2::AppDriver$new(app) 33 | 34 | # Keep here to print to `stdout` 35 | print(driver$get_logs()) 36 | -------------------------------------------------------------------------------- /tests/testthat/scripts/pr_307.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | mod_ui <- function(id) { 4 | ns <- NS(id) 5 | textOutput(ns("foo")) 6 | } 7 | 8 | mod_server <- function(id) { 9 | moduleServer( 10 | id, 11 | function(input, output, session) { 12 | output$foo <- renderText("bar") 13 | } 14 | ) 15 | } 16 | 17 | app <- shinyApp( 18 | mod_ui("test"), 19 | function(input, output, session) { 20 | mod_server("test") 21 | } 22 | ) 23 | 24 | driver <- shinytest2::AppDriver$new(app) 25 | 26 | # Keep here to print to `stdout` 27 | print(driver$get_logs()) 28 | -------------------------------------------------------------------------------- /tests/testthat/setup-disable-crashpad.R: -------------------------------------------------------------------------------- 1 | # testthat on_cran 2 | on_cran <- function() { 3 | !identical(Sys.getenv("NOT_CRAN"), "true") 4 | } 5 | 6 | # Check: for detritus in the temp directory 7 | # Result: NOTE 8 | # Found the following files/directories: 9 | # ‘Crashpad’ 10 | # Flavors: r-devel-linux-x86_64-fedora-clang, r-devel-linux-x86_64-fedora-gcc 11 | if (on_cran()) { 12 | 13 | # Disable crash reporting on CRAN machines. (Can't get the report anyways) 14 | chromote::set_chrome_args(c( 15 | # https://peter.sh/experiments/chromium-command-line-switches/#disable-crash-reporter 16 | #> Disable crash reporter for headless. It is enabled by default in official builds 17 | "--disable-crash-reporter", 18 | chromote::default_chrome_args() 19 | )) 20 | 21 | # Make sure the temp folder is removed when testing is complete 22 | withr::defer({ 23 | # Close the browser 24 | try(chromote::default_chromote_object()$get_browser()$close()) 25 | 26 | # Clean up chromote sessions 27 | gc() # Run R6 finalizer methods 28 | Sys.sleep(2) # Wait for any supervisors to exit 29 | 30 | # Delete the Crashpad folder if it exists 31 | unlink(file.path(tempdir(), "Crashpad"), recursive = TRUE) 32 | }, envir = testthat::teardown_env()) 33 | } 34 | -------------------------------------------------------------------------------- /tests/testthat/test-app-eval-js.R: -------------------------------------------------------------------------------- 1 | require("shiny", quietly = TRUE, character.only = TRUE) 2 | 3 | shiny_app <- shinyApp( 4 | ui = fluidPage( 5 | "Eval JS", 6 | tags$script(" 7 | var test_value = 42; 8 | var test_string = 'Hello world!'; 9 | "), 10 | verbatimTextOutput("txt") 11 | ), 12 | server = function(input, output) { 13 | # empty 14 | output$txt <- renderText({ 15 | "(app loaded)" 16 | }) 17 | } 18 | ) 19 | 20 | 21 | 22 | test_that("Duplicate input ids are found", { 23 | app <- AppDriver$new(shiny_app) 24 | 25 | app$wait_for_js("test_value === 42") 26 | app$wait_for_js("let a = test_value; let b = 42; a === b") 27 | 28 | app$wait_for_js("test_value === 42;") 29 | app$wait_for_js("test_string != '\"';") 30 | app$wait_for_js("test_string !== \"'\";") 31 | app$wait_for_js("test_string === 'Hello world!';") 32 | 33 | # https://github.com/rstudio/shinytest2/issues/236 34 | app$wait_for_js("'test'==='test'") 35 | app$wait_for_js('"test"==="test"') 36 | 37 | # Provide a test 38 | # Errors will be thrown above if the conditions can not be met 39 | expect_true(TRUE) 40 | }) 41 | 42 | 43 | test_that("Errors are caught in $wait_for_js()", { 44 | app <- AppDriver$new(shiny_app) 45 | 46 | expect_error( 47 | app$wait_for_js("test_value === /"), 48 | "test_value === /" 49 | ) 50 | 51 | expect_error( 52 | app$wait_for_js("false", timeout = 100), 53 | "Timed out waiting for JavaScript script to return `true`" 54 | ) 55 | }) 56 | -------------------------------------------------------------------------------- /tests/testthat/test-app-expect-file-transform.R: -------------------------------------------------------------------------------- 1 | require("shiny", quietly = TRUE, character.only = TRUE) 2 | 3 | shiny_app <- shinyApp( 4 | ui = fluidPage( 5 | downloadButton("download_button_txt", "Download Button - Text"), 6 | verbatimTextOutput("txt") 7 | ), 8 | server = function(input, output) { 9 | output$download_button_txt <- downloadHandler( 10 | filename = function() { 11 | "download-button.txt" 12 | }, 13 | content = function(file) { 14 | cat("Download content!\n", file = file) 15 | } 16 | ) 17 | 18 | output$txt <- renderText({ 19 | "(app loaded)" 20 | }) 21 | } 22 | ) 23 | 24 | 25 | test_that("transform can be passed to expect_snapshot_file()", { 26 | app <- AppDriver$new(shiny_app) 27 | 28 | download_called <- 0 29 | values_called <- 0 30 | 31 | app$expect_download("download_button_txt", transform = function(...) { 32 | download_called <<- download_called + 1 33 | list(...)[[1]] 34 | }) 35 | app$expect_values(transform = function(...) { 36 | values_called <<- values_called + 1 37 | list(...)[[1]] 38 | }) 39 | 40 | expect_equal(download_called, 1) 41 | expect_equal(values_called, 1) 42 | }) 43 | -------------------------------------------------------------------------------- /tests/testthat/test-app-shiny.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | 4 | hello_app <- shinyApp( 5 | ui = fluidPage( 6 | textInput("name", "What is your name?"), 7 | actionButton("greet", "Greet"), 8 | textOutput("greeting"), 9 | tags$br(), 10 | # consistenly sized box and consistent across OS 11 | tags$div( 12 | id = "custom_div", 13 | style = "width: 100px;height: 100px;" 14 | ) 15 | ), 16 | server = function(input, output, session) { 17 | output$greeting <- renderText({ 18 | shiny::req(input$greet) 19 | paste0("Hello ", shiny::isolate(input$name), "!") 20 | }) 21 | } 22 | ) 23 | 24 | 25 | test_that("AppDriver can receive a shiny.obj object", { 26 | 27 | app <- AppDriver$new(hello_app, name = "app-shiny_app", expect_values_screenshot_args = FALSE) 28 | 29 | app$set_inputs(name = "Barret") 30 | app$click("greet") 31 | 32 | expect_true(fs::path_has_parent(app$get_dir(), tempdir())) 33 | }) 34 | 35 | test_that("AppDriver can receive a shinyAppDir object", { 36 | 37 | ex_app_dir <- shinyAppDir(system.file("examples/01_hello", package = "shiny")) 38 | 39 | app <- AppDriver$new(ex_app_dir, name = "app-shiny_dir", expect_values_screenshot_args = FALSE) 40 | 41 | app$set_inputs(bins = 20) 42 | 43 | il <- rlang::list2(bins = 15) 44 | app$set_inputs(!!!il) 45 | 46 | expect_true(fs::path_has_parent(app$get_dir(), tempdir())) 47 | }) 48 | -------------------------------------------------------------------------------- /tests/testthat/test-apps.R: -------------------------------------------------------------------------------- 1 | app_dir <- test_path("apps/files-app-rmd") 2 | if (!dir.exists(file.path(app_dir, "tests", "testthat"))) { 3 | skip("App test folders have been ignored") 4 | } 5 | 6 | # Test reporter displays info 7 | # Similar to 8 | # v | 4 | apps 9 | # v | 1 | apps - custom name - shinytest2 [0.3s] 10 | # ✔ | 4 | apps 11 | test_that("before", { 12 | expect_equal(1, 1) 13 | expect_equal(1, 1) 14 | expect_equal(1, 1) 15 | }) 16 | test_that("wrapper", { 17 | expect_equal(1, 1) 18 | test_app(app_dir, name = "custom name 1") 19 | expect_equal(1, 1) 20 | }) 21 | test_that("after", { 22 | expect_equal(1, 1) 23 | expect_equal(1, 1) 24 | expect_equal(1, 1) 25 | }) 26 | 27 | test_that("before", { 28 | expect_equal(1, 1) 29 | expect_equal(1, 1) 30 | expect_equal(1, 1) 31 | }) 32 | test_app(app_dir, name = "custom name 2") 33 | test_that("after", { 34 | expect_equal(1, 1) 35 | expect_equal(1, 1) 36 | expect_equal(1, 1) 37 | }) 38 | 39 | 40 | ## -------------------------------- 41 | 42 | 43 | # Test all apps work as expected 44 | lapply( 45 | fs::dir_ls(test_path("apps"), type = "directory"), 46 | function(shiny_app_dir) { 47 | test_app(shiny_app_dir) 48 | } 49 | ) 50 | -------------------------------------------------------------------------------- /tests/testthat/test-known-names.R: -------------------------------------------------------------------------------- 1 | 2 | test_that("known names are being found", { 3 | tmpfile <- tempfile() 4 | withr::defer({ 5 | if (fs::file_exists(tmpfile)) { 6 | fs::file_delete(tmpfile) 7 | } 8 | }) 9 | cat(file = tmpfile, " 10 | AppDriver$new() 11 | AppDriver$new(name = NULL) 12 | shinytest2::AppDriver$new(name = 'test') 13 | shinytest2:::AppDriver$new(name = 'test2') 14 | some_value <- 'value' 15 | AppDriver$new(name = some_value) 16 | ") 17 | 18 | expect_equal( 19 | known_app_driver_name_values(tmpfile), 20 | list(NULL, NULL, "test", "test2") 21 | ) 22 | }) 23 | -------------------------------------------------------------------------------- /tests/testthat/test-not-testing.R: -------------------------------------------------------------------------------- 1 | require("shiny", quietly = TRUE, character.only = TRUE) 2 | 3 | test_that("Running an app not in testing mode has 404 handled when getting values", { 4 | 5 | app_bg <- callr::r_bg( 6 | function() { 7 | shiny::runApp( 8 | shinyApp("", function(input, output) {}), # nolint: brace_linter 9 | test.mode = FALSE 10 | ) 11 | }, 12 | stderr = "|" 13 | ) 14 | withr::defer(app_bg$kill()) 15 | 16 | # Wait until Shiny server is running 17 | app_url <- NULL 18 | for (i in 1:100) { 19 | lines <- paste0(app_bg$read_error_lines(), collapse = "\n") 20 | if (length(lines) > 0) { 21 | if (grepl("http", lines, fixed = TRUE)) { 22 | lines <- strsplit(lines, "\n")[[1]] 23 | line <- lines[grepl("http", lines, fixed = TRUE)] 24 | app_url <- tail(strsplit(line, " ")[[1]], 1) 25 | break 26 | } 27 | } 28 | Sys.sleep(0.1) 29 | } 30 | 31 | expect_true(!is.null(app_url)) 32 | 33 | app <- AppDriver$new(app_url) 34 | 35 | expect_error( 36 | app$get_values(), 37 | "Shiny server returned 404" 38 | ) 39 | 40 | expect_error( 41 | app$expect_values(), 42 | "Shiny server returned 404" 43 | ) 44 | }) 45 | -------------------------------------------------------------------------------- /tests/testthat/test-shinytest2.R: -------------------------------------------------------------------------------- 1 | skip_on_cran() # CI is good enough 2 | 3 | # If testthat is not a `Depends` package, then `testthat` is guarenteed to be loaded when shinytest2 is loaded. 4 | # This will cause confusion when only `library(shinytest2)` is called. 5 | test_that("testthat is a depends package", { 6 | depends <- as.list(read.dcf(system.file("DESCRIPTION", package = "shinytest2"))[1, ])$Depends 7 | expect_match(depends, "testthat") 8 | }) 9 | 10 | 11 | 12 | test_that("AppDriver can print while working with `missing_arg()` values", { 13 | app <- AppDriver$new( 14 | shinyApp("", function(input, output) {}) # nolint: brace_linter 15 | ) 16 | expect_error( 17 | utils::capture.output({ 18 | print(app) 19 | }), 20 | NA 21 | ) 22 | }) 23 | -------------------------------------------------------------------------------- /tests/testthat/test-url.R: -------------------------------------------------------------------------------- 1 | 2 | test_that("Url Class behaves as expected", { 3 | 4 | expect_url <- function(url, expected_url) { 5 | expect_equal(Url$new()$set(url)$get(), expected_url) 6 | } 7 | 8 | expect_url("http://a.b.com", "http://a.b.com/") 9 | expect_url("https://a.b.com/", "https://a.b.com/") 10 | expect_url("http://a.b.com:1020", "http://a.b.com:1020/") 11 | expect_url("http://a.b.com:1020/", "http://a.b.com:1020/") 12 | expect_url("http://a.b.com:1020/abc", "http://a.b.com:1020/abc") 13 | expect_url("http://a.b.com:1020/abc/", "http://a.b.com:1020/abc/") 14 | expect_url("http://a.b.com/abc/", "http://a.b.com/abc/") 15 | expect_url("http://user@a.b.com/", "http://user@a.b.com/") 16 | expect_url("http://user:pass@a.b.com/", "http://user:pass@a.b.com/") 17 | 18 | # Malformed URLs, or non-http/https protocol 19 | expect_url_error <- function(url, ...) { 20 | expect_error(Url$new()$set(url), ...) 21 | } 22 | expect_url_error("http:/a.b.com/", "url hostname") 23 | expect_warning( 24 | expect_url_error("http://a.b.com:12ab/", "url port") 25 | ) 26 | expect_url_error("ftp://a.b.com/", "url scheme") 27 | }) 28 | -------------------------------------------------------------------------------- /todo.md: -------------------------------------------------------------------------------- 1 | Future release: 2 | * GHA integration 3 | * upload an artifact with updated snapshots 4 | * like fix_all_branches, it must be initiated manually, but _automated_ 5 | ### Vignettes: 6 | * Getting started 7 | * Medium difficulty example: 8 | * Use an `$expect_screenshot()` with a `variant` 9 | * explain what a variant is 10 | * How to review different variants 11 | -------------------------------------------------------------------------------- /vignettes/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | *.R 3 | !simple-app/** 4 | !non-optimized-app/** 5 | -------------------------------------------------------------------------------- /vignettes/images/diffviewer-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/vignettes/images/diffviewer-1.png -------------------------------------------------------------------------------- /vignettes/images/gremlins-attack-refined.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/vignettes/images/gremlins-attack-refined.gif -------------------------------------------------------------------------------- /vignettes/images/gremlins-attack.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/vignettes/images/gremlins-attack.gif -------------------------------------------------------------------------------- /vignettes/images/gremlins-inject.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/vignettes/images/gremlins-inject.png -------------------------------------------------------------------------------- /vignettes/images/gremlins-logs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/vignettes/images/gremlins-logs.png -------------------------------------------------------------------------------- /vignettes/images/gremlins-slider-handle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/vignettes/images/gremlins-slider-handle.png -------------------------------------------------------------------------------- /vignettes/images/gremlins-start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/vignettes/images/gremlins-start.png -------------------------------------------------------------------------------- /vignettes/images/plot-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/vignettes/images/plot-app.png -------------------------------------------------------------------------------- /vignettes/images/record-name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/vignettes/images/record-name.png -------------------------------------------------------------------------------- /vignettes/images/record-simple-app-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/vignettes/images/record-simple-app-2.png -------------------------------------------------------------------------------- /vignettes/images/record-simple-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/vignettes/images/record-simple-app.png -------------------------------------------------------------------------------- /vignettes/images/screenshot-exports-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/vignettes/images/screenshot-exports-app.png -------------------------------------------------------------------------------- /vignettes/images/screenshot-recorder-random-seed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/vignettes/images/screenshot-recorder-random-seed.png -------------------------------------------------------------------------------- /vignettes/images/shinytest2-loadtest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/vignettes/images/shinytest2-loadtest.png -------------------------------------------------------------------------------- /vignettes/images/shinytest2-shinyloadtest-optimized.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/vignettes/images/shinytest2-shinyloadtest-optimized.png -------------------------------------------------------------------------------- /vignettes/simple-app/app.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | ui <- fluidPage( 3 | textInput("name", "What is your name?"), 4 | actionButton("greet", "Greet"), 5 | textOutput("greeting") 6 | ) 7 | server <- function(input, output, session) { 8 | output$greeting <- renderText({ 9 | req(input$greet) 10 | paste0("Hello ", isolate(input$name), "!") 11 | }) 12 | } 13 | shinyApp(ui, server) 14 | -------------------------------------------------------------------------------- /vignettes/simple-app/tests/testthat.R: -------------------------------------------------------------------------------- 1 | shinytest2::test_app() 2 | -------------------------------------------------------------------------------- /vignettes/simple-app/tests/testthat/_snaps/shinytest2/simple-app-001.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "greet": 1, 4 | "name": "Barret" 5 | }, 6 | "output": { 7 | "greeting": "Hello Barret!" 8 | }, 9 | "export": { 10 | 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /vignettes/simple-app/tests/testthat/_snaps/shinytest2/simple-app-001.new.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "greet": 1, 4 | "name": "Hadley" 5 | }, 6 | "output": { 7 | "greeting": "Hello Hadley!" 8 | }, 9 | "export": { 10 | 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /vignettes/simple-app/tests/testthat/_snaps/shinytest2/simple-app-001_.new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/vignettes/simple-app/tests/testthat/_snaps/shinytest2/simple-app-001_.new.png -------------------------------------------------------------------------------- /vignettes/simple-app/tests/testthat/_snaps/shinytest2/simple-app-001_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/shinytest2/bcac429ff584af0d49afdbb09f1f973fbd2238a3/vignettes/simple-app/tests/testthat/_snaps/shinytest2/simple-app-001_.png -------------------------------------------------------------------------------- /vignettes/simple-app/tests/testthat/test-shinytest2.R: -------------------------------------------------------------------------------- 1 | library(shinytest2) 2 | 3 | test_that("{shinytest2} recording: simple-app", { 4 | app <- AppDriver$new(name = "simple-app", height = 407, width = 348) 5 | app$set_inputs(name = "Hadley") 6 | app$click("greet") 7 | app$expect_values() 8 | }) 9 | --------------------------------------------------------------------------------