From dca0e3c5691a60a29c3ef936ff99e2f6bb2a06b7 Mon Sep 17 00:00:00 2001 From: Garrick Aden-Buie Date: Mon, 8 May 2023 15:29:30 -0400 Subject: [PATCH 01/26] Add 312-bslib-sidebar-resize (manual app) --- inst/apps/312-bslib-sidebar-resize/app.R | 56 ++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 inst/apps/312-bslib-sidebar-resize/app.R diff --git a/inst/apps/312-bslib-sidebar-resize/app.R b/inst/apps/312-bslib-sidebar-resize/app.R new file mode 100644 index 0000000000..e26fbcb7a0 --- /dev/null +++ b/inst/apps/312-bslib-sidebar-resize/app.R @@ -0,0 +1,56 @@ +### Keep this line to manually test this shiny application. Do not edit this line; shinycoreci::::is_manual_app + +library(shiny) +library(bslib) +library(ggplot2) +library(plotly) + +lorem1 <- p( + "Dolor cursus quis sociis, tempus laoreet integer vel,", + "nam suscipit sodales curabitur tristique. Hac massa", + "fames auctor ac posuere, non: primis semper egestas!", + "Porttitor interdum lobortis elementum arcu." +) + +lorem2 <- p( + "Elit aptent vivamus, eu habitasse fringilla venenatis", + "viverra tellus metus. Maecenas ultrices fermentum", + "nunc turpis libero nascetur!" +) + +ui <- page_fixed( + titlePanel("Sidebar Resize", "312 | bslib-sidebar-resize"), + h2("Static plot resizing"), + p( + "The plot in the layout below should stretch while the sidebar is opening", "or closing. After the transition is complete, the server will update the", + "plot with the final dimensions." + ), + layout_sidebar( + sidebar = sidebar(title = "Toggle me", lorem1, lorem2, lorem1), + lorem1, + plotOutput("plot_static"), + lorem2 + ), + h2("Widget plot resizing", class = "mt-4 mb-2"), + p( + "The plot in the layout below should stretch while the sidebar is opening", "or closing. There should be no layout shift after the transition is", "complete." + ), + layout_sidebar( + sidebar = sidebar(title = "Toggle me", lorem1, lorem2, lorem1), + lorem1, + plotlyOutput("plot_widget"), + lorem2 + ), + div(style = "min-height: 100vh") +) + +server <- function(input, output, session) { + plot <- reactive({ + ggplot(mtcars, aes(mpg, wt)) + geom_point() + }) + + output$plot_static <- renderPlot(plot()) + output$plot_widget <- renderPlotly(ggplotly(plot())) +} + +shinyApp(ui, server) From eac7185337d1a8df2cc6354953ce5f9d8e5c91f9 Mon Sep 17 00:00:00 2001 From: Garrick Aden-Buie Date: Tue, 9 May 2023 10:40:33 -0400 Subject: [PATCH 02/26] Use `page_navbar()` for shared sidebar --- inst/apps/312-bslib-sidebar-resize/app.R | 94 +++++++++++++++++------- 1 file changed, 68 insertions(+), 26 deletions(-) diff --git a/inst/apps/312-bslib-sidebar-resize/app.R b/inst/apps/312-bslib-sidebar-resize/app.R index e26fbcb7a0..2c374d4d57 100644 --- a/inst/apps/312-bslib-sidebar-resize/app.R +++ b/inst/apps/312-bslib-sidebar-resize/app.R @@ -1,5 +1,3 @@ -### Keep this line to manually test this shiny application. Do not edit this line; shinycoreci::::is_manual_app - library(shiny) library(bslib) library(ggplot2) @@ -18,39 +16,83 @@ lorem2 <- p( "nunc turpis libero nascetur!" ) -ui <- page_fixed( - titlePanel("Sidebar Resize", "312 | bslib-sidebar-resize"), - h2("Static plot resizing"), - p( - "The plot in the layout below should stretch while the sidebar is opening", "or closing. After the transition is complete, the server will update the", - "plot with the final dimensions." - ), - layout_sidebar( - sidebar = sidebar(title = "Toggle me", lorem1, lorem2, lorem1), - lorem1, - plotOutput("plot_static"), - lorem2 +ui <- page_navbar( + title = "312 | bslib-sidebar-resize", + theme = bs_theme("bslib-sidebar-transition-duration" = "3s"), + sidebar = sidebar( + title = "Shared Sidebar", + open = "open", + p("The plots should resize smoothly when this sidebar or the local sidebar are toggled.") ), - h2("Widget plot resizing", class = "mt-4 mb-2"), - p( - "The plot in the layout below should stretch while the sidebar is opening", "or closing. There should be no layout shift after the transition is", "complete." + nav( + "Static", + h2("Static plot resizing"), + p( + "The plot in the layout below should stretch while the sidebar is", + "opening or closing. After the transition is complete, the server will", + "update the plot with the final dimensions." + ), + layout_sidebar( + sidebar = sidebar(title = "Toggle me", lorem1, lorem2, lorem1), + lorem1, + plotOutput("plot_static1"), + lorem2 + ), + h2("Shared only", class = "my-3"), + p( + "The next plot should resize smoothly only when the shared sidebar is transitioning." + ), + div( + class = "row", + div(class = "col", plotOutput("plot_static2")), + div(class = "col", p(lorem2, lorem1)) + ) ), - layout_sidebar( - sidebar = sidebar(title = "Toggle me", lorem1, lorem2, lorem1), - lorem1, - plotlyOutput("plot_widget"), - lorem2 + nav( + "Widget", + h2("Widget plot resizing", class = "mt-4 mb-2"), + p( + "The plot in the layout below should stretch while the sidebar is opening", + "or closing. There should be no layout shift after the transition is", + "complete." + ), + layout_sidebar( + sidebar = sidebar(title = "Toggle me", lorem1, lorem2, lorem1), + lorem1, + plotlyOutput("plot_widget1"), + lorem2 + ), + h2("Shared only", class = "my-3"), + p( + "The next plot should resize smoothly only when the shared sidebar is transitioning." + ), + div( + class = "row", + div(class = "col", plotlyOutput("plot_widget2")), + div(class = "col", p(lorem2, lorem1)) + ) ), - div(style = "min-height: 100vh") + footer = div(style = "min-height: 100vh") ) server <- function(input, output, session) { plot <- reactive({ - ggplot(mtcars, aes(mpg, wt)) + geom_point() + ggplot(mtcars, aes(mpg, wt)) + + geom_point(aes(color = factor(cyl))) + + labs( + title = "Cars go brrrrr", + x = "Miles per gallon", + y = "Weight (tons)", + color = "Cylinders" + ) + + theme_gray(base_size = 16) }) - output$plot_static <- renderPlot(plot()) - output$plot_widget <- renderPlotly(ggplotly(plot())) + output$plot_static1 <- renderPlot(plot()) + output$plot_static2 <- renderPlot(plot()) + + output$plot_widget1 <- renderPlotly(ggplotly(plot())) + output$plot_widget2 <- renderPlotly(ggplotly(plot())) } shinyApp(ui, server) From daf543859b82515fca767751b08e88cbd5b6b9db Mon Sep 17 00:00:00 2001 From: Garrick Aden-Buie Date: Tue, 9 May 2023 12:00:35 -0400 Subject: [PATCH 03/26] Programmatically test sidebar transition --- inst/apps/312-bslib-sidebar-resize/app.R | 37 ++- .../312-bslib-sidebar-resize/tests/testthat.R | 1 + .../tests/testthat/setup-shinytest2.R | 2 + .../tests/testthat/test-shinytest2.R | 257 ++++++++++++++++++ 4 files changed, 284 insertions(+), 13 deletions(-) create mode 100644 inst/apps/312-bslib-sidebar-resize/tests/testthat.R create mode 100644 inst/apps/312-bslib-sidebar-resize/tests/testthat/setup-shinytest2.R create mode 100644 inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R diff --git a/inst/apps/312-bslib-sidebar-resize/app.R b/inst/apps/312-bslib-sidebar-resize/app.R index 2c374d4d57..23328c1bb1 100644 --- a/inst/apps/312-bslib-sidebar-resize/app.R +++ b/inst/apps/312-bslib-sidebar-resize/app.R @@ -18,9 +18,12 @@ lorem2 <- p( ui <- page_navbar( title = "312 | bslib-sidebar-resize", - theme = bs_theme("bslib-sidebar-transition-duration" = "3s"), + theme = bs_theme( + "bslib-sidebar-transition-duration" = Sys.getenv("SIDEBAR_TRANSITION_TIME", "0.5s") + ), sidebar = sidebar( title = "Shared Sidebar", + id = "sidebar-shared", open = "open", p("The plots should resize smoothly when this sidebar or the local sidebar are toggled.") ), @@ -33,9 +36,13 @@ ui <- page_navbar( "update the plot with the final dimensions." ), layout_sidebar( - sidebar = sidebar(title = "Toggle me", lorem1, lorem2, lorem1), + sidebar = sidebar( + title = "Toggle me", + id = "sidebar-local-static", + lorem1, lorem2, lorem1 + ), lorem1, - plotOutput("plot_static1"), + plotOutput("plot_static_local"), lorem2 ), h2("Shared only", class = "my-3"), @@ -44,8 +51,8 @@ ui <- page_navbar( ), div( class = "row", - div(class = "col", plotOutput("plot_static2")), - div(class = "col", p(lorem2, lorem1)) + div(class = "col-6", plotOutput("plot_static_shared")), + div(class = "col-6", lorem2, lorem1) ) ), nav( @@ -57,9 +64,13 @@ ui <- page_navbar( "complete." ), layout_sidebar( - sidebar = sidebar(title = "Toggle me", lorem1, lorem2, lorem1), + sidebar = sidebar( + title = "Toggle me", + id = "sidebar-local-widget", + lorem1, lorem2, lorem1 + ), lorem1, - plotlyOutput("plot_widget1"), + plotlyOutput("plot_widget_local"), lorem2 ), h2("Shared only", class = "my-3"), @@ -68,8 +79,8 @@ ui <- page_navbar( ), div( class = "row", - div(class = "col", plotlyOutput("plot_widget2")), - div(class = "col", p(lorem2, lorem1)) + div(class = "col-6", plotlyOutput("plot_widget_shared")), + div(class = "col-6", lorem2, lorem1) ) ), footer = div(style = "min-height: 100vh") @@ -88,11 +99,11 @@ server <- function(input, output, session) { theme_gray(base_size = 16) }) - output$plot_static1 <- renderPlot(plot()) - output$plot_static2 <- renderPlot(plot()) + output$plot_static_local <- renderPlot(plot()) + output$plot_static_shared <- renderPlot(plot()) - output$plot_widget1 <- renderPlotly(ggplotly(plot())) - output$plot_widget2 <- renderPlotly(ggplotly(plot())) + output$plot_widget_local <- renderPlotly(ggplotly(plot())) + output$plot_widget_shared <- renderPlotly(ggplotly(plot())) } shinyApp(ui, server) diff --git a/inst/apps/312-bslib-sidebar-resize/tests/testthat.R b/inst/apps/312-bslib-sidebar-resize/tests/testthat.R new file mode 100644 index 0000000000..7d25b5b9e4 --- /dev/null +++ b/inst/apps/312-bslib-sidebar-resize/tests/testthat.R @@ -0,0 +1 @@ +shinytest2::test_app() diff --git a/inst/apps/312-bslib-sidebar-resize/tests/testthat/setup-shinytest2.R b/inst/apps/312-bslib-sidebar-resize/tests/testthat/setup-shinytest2.R new file mode 100644 index 0000000000..be65b4f035 --- /dev/null +++ b/inst/apps/312-bslib-sidebar-resize/tests/testthat/setup-shinytest2.R @@ -0,0 +1,2 @@ +# Load application support files into testing environment +shinytest2::load_app_env() diff --git a/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R b/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R new file mode 100644 index 0000000000..b301e87bb4 --- /dev/null +++ b/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R @@ -0,0 +1,257 @@ +library(shinytest2) + +expect_sidebar_hidden_factory <- function(app) { + function(id) { + state <- app$get_js(js_sidebar_state(id = id)) + expect_true("sidebar-collapsed" %in% state$layout_classes) + expect_equal(state$content_display, "none") + expect_true(state$sidebar_hidden) + } +} + +expect_sidebar_shown_factory <- function(app) { + function(id) { + state <- app$get_js(js_sidebar_state(id = id)) + expect_false("sidebar-collapsed" %in% state$layout_classes) + expect_false(identical(state$content_display, "none")) + expect_false(state$sidebar_hidden) + } +} + +js_sidebar_transition_complete <- function(id) { + sprintf( + "!document.getElementById('%s').parentElement.classList.contains('transitioning');", + id + ) +} + +js_sidebar_state <- function(id) { + sprintf( + "(function() { + return { + layout_classes: Array.from(document.getElementById('%s').closest('.bslib-sidebar-layout').classList), + content_display: window.getComputedStyle(document.querySelector('#%s .sidebar-content')).getPropertyValue('display'), + sidebar_hidden: document.getElementById('%s').hidden + }})();", + id, id, id + ) +} + +js_element_width <- function(selector) { + sprintf( + "document.querySelector('%s').getBoundingClientRect().width;", + selector + ) +} + +# Gather width measurements of plots during the sidebar transition +# +# 1. Measures the `initial` width of plots prior to transition +# 2. Clicks the sidebar toggle +# 3. Samples width of plots `during` transition +# 4. Waits for transition to complete +# 5. Measures the `final` width of plots after transition +# 6. Captures updated shiny `outputs` during the measurement period +watch_sidebar_transition <- function( + app, + sidebar = c("shared", "local"), + page = c("static", "widget") +) { + sidebar <- match.arg(sidebar) + page <- match.arg(page) + + id_sidebar <- if (sidebar == "shared") "sidebar-shared" else paste0("sidebar-local-", page) + sel_plot <- function(which = c("shared", "local")) { + plot_container <- + if (page == "static") { + "img" + } else { + ".plot-container > .svg-container" + } + paste0("#plot_", page, "_", which, " > ", plot_container) + } + sel_plot_img_local <- sel_plot("local") + sel_plot_img_shared <- sel_plot("shared") + + initial <- list( + local = app$get_js(js_element_width(sel_plot_img_local)), + shared = app$get_js(js_element_width(sel_plot_img_shared)) + ) + + during <- list(local = c(), shared = c()) + + app$run_js(" +if (!window.updatedOutputs) { + $(document).on('shiny:value', function(event) { + window.updatedOutputs.push(event.target.id); + }) +} +window.updatedOutputs = []; +") + app$click(selector = sprintf("#%s + .collapse-toggle", id_sidebar)) + + while (!app$get_js(js_sidebar_transition_complete(id_sidebar))) { + Sys.sleep(0.1) + during$local <- c(during$local, app$get_js(js_element_width(sel_plot_img_local))) + during$shared <- c(during$shared, app$get_js(js_element_width(sel_plot_img_shared))) + } + + if (page == "static") { + app$wait_for_js("window.updatedOutputs.length > 0") + Sys.sleep(0.25) + } else { + # widget plots don't trigger shiny:value events, so we just have to wait + Sys.sleep(1) + } + + outputs <- app$get_js("window.updatedOutputs") + final <- list( + local = app$get_js(js_element_width(sel_plot_img_local)), + shared = app$get_js(js_element_width(sel_plot_img_shared)) + ) + + list( + initial = initial, + during = during, + final = final, + outputs = unlist(outputs) + ) +} + +# 312-bslib-sidebar-resize ---------------------------------------------------- +test_that("312-bslib-sidebar-resize", { + app <- AppDriver$new( + name = "312-bslib-sidebar-resize", + variant = platform_variant(), + height = 1600, + width = 1200, + view = interactive(), + options = list(bslib.precompiled = FALSE), + expect_values_screenshot_args = FALSE + ) + + expect_sidebar_hidden <- expect_sidebar_hidden_factory(app) + expect_sidebar_shown <- expect_sidebar_shown_factory(app) + + # STATIC PAGE ================================================================ + + # collapse static shared sidebar -------- + close_static_shared <- watch_sidebar_transition( + app, + sidebar = "shared", + page = "static" + ) + + expect_sidebar_hidden("sidebar-shared") + + # plot output image size changed during collapse for both plots + expect_gt(length(unique(close_static_shared$during$local)), 1) + expect_gt(length(unique(close_static_shared$during$shared)), 1) + + # plot output image size was growing during transition + expect_gt(min(close_static_shared$during$local), close_static_shared$initial$local) + expect_gt(min(close_static_shared$during$shared), close_static_shared$initial$shared) + + # both plots updated at the end of the transition + expect_setequal(close_static_shared$outputs, c("plot_static_local", "plot_static_shared")) + + # collapse static local sidebar -------- + close_static_local <- watch_sidebar_transition( + app, + sidebar = "local", + page = "static" + ) + + expect_sidebar_hidden("sidebar-local-static") + + # plot output image size changed during collapse for local plot only + expect_gt(length(unique(close_static_local$during$local)), 1) + expect_equal(length(unique(close_static_local$during$shared)), 1) + + # plot output image size was growing during transition for local only + expect_gt(min(close_static_local$during$local), close_static_local$initial$local) + expect_equal(unique(close_static_local$during$shared), close_static_local$initial$shared) + + # local plot updated at the end of the transition + expect_equal(close_static_local$outputs, "plot_static_local") + + # expand static shared sidebar -------- + open_static_shared <- watch_sidebar_transition( + app, + sidebar = "shared", + page = "static" + ) + + expect_sidebar_shown("sidebar-shared") + + # plot output image size changed during expand for both plots + expect_gt(length(unique(open_static_shared$during$local)), 1) + expect_gt(length(unique(open_static_shared$during$shared)), 1) + + # plot output image size was shrinking during transition + expect_lt(max(open_static_shared$during$local), open_static_shared$initial$local) + expect_lt(max(open_static_shared$during$shared), open_static_shared$initial$shared) + + # both plots updated at the end of the transition + expect_setequal(open_static_shared$outputs, c("plot_static_local", "plot_static_shared")) + + # SWITCH TO WIDGET PAGE ====================================================== + app$ + click(selector = '.nav-link[data-value="Widget"]')$ + wait_for_js("document.getElementById('js-plotly-tester') ? true : false") + + # now we repeat all of the same tests above, except that the widget resizing + # won't trigger a 'shiny:value' event. + + # collapse widget shared sidebar -------- + close_widget_shared <- watch_sidebar_transition( + app, + sidebar = "shared", + page = "widget" + ) + + expect_sidebar_hidden("sidebar-shared") + + # plot output image size changed during collapse for both plots + expect_gt(length(unique(close_widget_shared$during$local)), 1) + expect_gt(length(unique(close_widget_shared$during$shared)), 1) + + # plot output image size was growing during transition + expect_gt(min(close_widget_shared$during$local), close_widget_shared$initial$local) + expect_gt(min(close_widget_shared$during$shared), close_widget_shared$initial$shared) + + # collapse widget local sidebar -------- + close_widget_local <- watch_sidebar_transition( + app, + sidebar = "local", + page = "widget" + ) + + expect_sidebar_hidden("sidebar-local-widget") + + # plot output image size changed during collapse for local plot only + expect_gt(length(unique(close_widget_local$during$local)), 1) + expect_equal(length(unique(close_widget_local$during$shared)), 1) + + # plot output image size was growing during transition for local only + expect_gt(min(close_widget_local$during$local), close_widget_local$initial$local) + expect_equal(unique(close_widget_local$during$shared), close_widget_local$initial$shared) + + # expand widget shared sidebar -------- + open_widget_shared <- watch_sidebar_transition( + app, + sidebar = "shared", + page = "widget" + ) + + expect_sidebar_shown("sidebar-shared") + + # plot output image size changed during expand for both plots + expect_gt(length(unique(open_widget_shared$during$local)), 1) + expect_gt(length(unique(open_widget_shared$during$shared)), 1) + + # plot output image size was shrinking during transition + expect_lt(max(open_widget_shared$during$local), open_widget_shared$initial$local) + expect_lt(max(open_widget_shared$during$shared), open_widget_shared$initial$shared) + +}) From db7723f7d7fdfdfa4e7f935bdffa847a3f1b2365 Mon Sep 17 00:00:00 2001 From: gadenbuie Date: Tue, 9 May 2023 16:06:40 +0000 Subject: [PATCH 04/26] Generate apps deps (GitHub Actions) --- R/data-apps-deps.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/data-apps-deps.R b/R/data-apps-deps.R index 8df5b19e19..2d259432ac 100644 --- a/R/data-apps-deps.R +++ b/R/data-apps-deps.R @@ -60,4 +60,4 @@ apps_deps_map <- list(`001-hello` = "rsconnect", `012-datatables` = "ggplot2", "rversions"), `305-bslib-value-box` = c("rlang", "rversions" ), `310-bslib-sidebar-dynamic` = c("rversions", "testthat" ), `311-bslib-sidebar-toggle-methods` = c("rversions", "testthat" - )) + ), `312-bslib-sidebar-resize` = "ggplot2") From ff5c45bd19fe8de820359e1aa1635792b52e1d8d Mon Sep 17 00:00:00 2001 From: Garrick Aden-Buie Date: Tue, 9 May 2023 15:59:45 -0400 Subject: [PATCH 05/26] Update tests to use `diff()` and to include labels on all expectations --- .../tests/testthat/test-shinytest2.R | 282 ++++++++++++++++-- 1 file changed, 249 insertions(+), 33 deletions(-) diff --git a/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R b/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R index b301e87bb4..8eba27e464 100644 --- a/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R +++ b/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R @@ -110,6 +110,10 @@ window.updatedOutputs = []; shared = app$get_js(js_element_width(sel_plot_img_shared)) ) + # we only need unique observations between initial and final + during$local <- unique(during$local) + during$shared <- unique(during$shared) + list( initial = initial, during = during, @@ -135,7 +139,7 @@ test_that("312-bslib-sidebar-resize", { # STATIC PAGE ================================================================ - # collapse static shared sidebar -------- + # collapse static shared sidebar -------------------------------------------- close_static_shared <- watch_sidebar_transition( app, sidebar = "shared", @@ -145,17 +149,57 @@ test_that("312-bslib-sidebar-resize", { expect_sidebar_hidden("sidebar-shared") # plot output image size changed during collapse for both plots - expect_gt(length(unique(close_static_shared$during$local)), 1) - expect_gt(length(unique(close_static_shared$during$shared)), 1) + expect_gt( + length(close_static_shared$during$local), + expected = 1, + label = "local plot output size changes during transition" + ) + expect_gt( + length(close_static_shared$during$shared), + expected = 1, + label = "shared plot output size changes during transition" + ) # plot output image size was growing during transition - expect_gt(min(close_static_shared$during$local), close_static_shared$initial$local) - expect_gt(min(close_static_shared$during$shared), close_static_shared$initial$shared) + expect_gt( + min(close_static_shared$during$local), + close_static_shared$initial$local, + label = "minimum local plot output size during transition" + ) + has_local_size_changes <- expect_true( + length(close_static_shared$during$local) > 1, + label = "has local plot output size changes during transition" + ) + if (has_local_size_changes) { + expect_true( + all(diff(close_static_shared$during$local) > 0), + label = "local plot output size was growing during transition" + ) + } + + expect_gt( + min(close_static_shared$during$shared), + close_static_shared$initial$shared, + label = "shared plot output size during transition" + ) + has_shared_size_changes <- expect_true( + length(close_static_shared$during$shared) > 1, + label = "has shared plot output size changes during transition" + ) + if (has_shared_size_changes) { + expect_true( + all(diff(close_static_shared$during$shared) > 0), + label = "shared plot output size was growing during transition" + ) + } # both plots updated at the end of the transition - expect_setequal(close_static_shared$outputs, c("plot_static_local", "plot_static_shared")) + expect_setequal( + close_static_shared$outputs, + c("plot_static_local", "plot_static_shared") + ) - # collapse static local sidebar -------- + # collapse static local sidebar --------------------------------------------- close_static_local <- watch_sidebar_transition( app, sidebar = "local", @@ -165,17 +209,48 @@ test_that("312-bslib-sidebar-resize", { expect_sidebar_hidden("sidebar-local-static") # plot output image size changed during collapse for local plot only - expect_gt(length(unique(close_static_local$during$local)), 1) - expect_equal(length(unique(close_static_local$during$shared)), 1) + expect_gt( + length(close_static_local$during$local), + expected = 1, + label = "local plot output size changes during transition" + ) + expect_equal( + length(close_static_local$during$shared), + expected = 1, + label = "shared plot output size changes during transition" + ) # plot output image size was growing during transition for local only - expect_gt(min(close_static_local$during$local), close_static_local$initial$local) - expect_equal(unique(close_static_local$during$shared), close_static_local$initial$shared) + expect_gt( + min(close_static_local$during$local), + close_static_local$initial$local, + label = "local plot output size was growing during transition" + ) + has_local_size_changes <- expect_true( + length(close_static_local$during$local) > 1, + label = "has local plot output size changes during transition" + ) + if (has_local_size_changes) { + expect_true( + all(diff(close_static_local$during$local) > 0), + label = "local plot output size changes" + ) + } + + expect_equal( + close_static_local$during$shared, + close_static_local$initial$shared, + label = "shared plot output size during transition" + ) # local plot updated at the end of the transition - expect_equal(close_static_local$outputs, "plot_static_local") + expect_equal( + close_static_local$outputs, + "plot_static_local", + label = "plot updates at end of transition" + ) - # expand static shared sidebar -------- + # expand static shared sidebar ---------------------------------------------- open_static_shared <- watch_sidebar_transition( app, sidebar = "shared", @@ -185,15 +260,55 @@ test_that("312-bslib-sidebar-resize", { expect_sidebar_shown("sidebar-shared") # plot output image size changed during expand for both plots - expect_gt(length(unique(open_static_shared$during$local)), 1) - expect_gt(length(unique(open_static_shared$during$shared)), 1) + expect_gt( + length(open_static_shared$during$local), + expected = 1, + label = "local plot output size changes" + ) + expect_gt( + length(open_static_shared$during$shared), + expected = 1, + label = "shared plot output size changes" + ) # plot output image size was shrinking during transition - expect_lt(max(open_static_shared$during$local), open_static_shared$initial$local) - expect_lt(max(open_static_shared$during$shared), open_static_shared$initial$shared) + expect_lt( + max(open_static_shared$during$local), + open_static_shared$initial$local, + label = "local plot output image size changes during transition" + ) + has_local_size_changes <- expect_true( + length(open_static_shared$during$local) > 1, + label = "has local plot output image size changes during transition" + ) + if (has_local_size_changes) { + expect_true( + all(diff(open_static_shared$during$local) < 0), + label = "local plot output image size was shrinking during transition" + ) + } + + expect_lt( + max(open_static_shared$during$shared), + open_static_shared$initial$shared, + label = "shared plot output image size changes during transition" + ) + has_shared_size_changes <- expect_true( + length(open_static_shared$during$shared) > 1, + label = "has shared plot output image size changes during transition" + ) + if (has_shared_size_changes) { + expect_true( + all(diff(open_static_shared$during$shared) < 0), + label = "shared plot output image size was shrinking during transition" + ) + } # both plots updated at the end of the transition - expect_setequal(open_static_shared$outputs, c("plot_static_local", "plot_static_shared")) + expect_setequal( + open_static_shared$outputs, + c("plot_static_local", "plot_static_shared") + ) # SWITCH TO WIDGET PAGE ====================================================== app$ @@ -203,7 +318,7 @@ test_that("312-bslib-sidebar-resize", { # now we repeat all of the same tests above, except that the widget resizing # won't trigger a 'shiny:value' event. - # collapse widget shared sidebar -------- + # collapse widget shared sidebar -------------------------------------------- close_widget_shared <- watch_sidebar_transition( app, sidebar = "shared", @@ -213,14 +328,52 @@ test_that("312-bslib-sidebar-resize", { expect_sidebar_hidden("sidebar-shared") # plot output image size changed during collapse for both plots - expect_gt(length(unique(close_widget_shared$during$local)), 1) - expect_gt(length(unique(close_widget_shared$during$shared)), 1) + expect_gt( + length(close_widget_shared$during$local), + expected = 1, + label = "local plot output size changes during transition" + ) + expect_gt( + length(close_widget_shared$during$shared), + expected = 1, + label = "shared plot output size changes during transition" + ) # plot output image size was growing during transition - expect_gt(min(close_widget_shared$during$local), close_widget_shared$initial$local) - expect_gt(min(close_widget_shared$during$shared), close_widget_shared$initial$shared) + expect_gt( + min(close_widget_shared$during$local), + expected = close_widget_shared$initial$local, + label = "local plot output size changes during transition" + ) + + has_local_size_changes <- expect_true( + length(close_widget_shared$during$local) > 1, + label = "has local plot output size changes during transition" + ) + if (has_local_size_changes) { + expect_true( + all(diff(close_widget_shared$during$local) > 0), + label = "local plot output size was growing during transition" + ) + } - # collapse widget local sidebar -------- + expect_gt( + min(close_widget_shared$during$shared), + expected = close_widget_shared$initial$shared, + label = "shared plot output size changes during transition" + ) + has_shared_size_changes <- expect_true( + length(close_widget_shared$during$shared) > 1, + label = "has shared plot output size changes during transition" + ) + if (has_shared_size_changes) { + expect_true( + all(diff(close_widget_shared$during$shared) > 0), + label = "shared plot output size changes during transition" + ) + } + + # collapse widget local sidebar --------------------------------------------- close_widget_local <- watch_sidebar_transition( app, sidebar = "local", @@ -230,14 +383,41 @@ test_that("312-bslib-sidebar-resize", { expect_sidebar_hidden("sidebar-local-widget") # plot output image size changed during collapse for local plot only - expect_gt(length(unique(close_widget_local$during$local)), 1) - expect_equal(length(unique(close_widget_local$during$shared)), 1) + expect_gt( + length(close_widget_local$during$local), + expected = 1, + label = "local plot output size changes during collapse" + ) + expect_equal( + length(close_widget_local$during$shared), + expected = 1, + label = "shared plot output size changes during collapse" + ) # plot output image size was growing during transition for local only - expect_gt(min(close_widget_local$during$local), close_widget_local$initial$local) - expect_equal(unique(close_widget_local$during$shared), close_widget_local$initial$shared) + expect_gt( + min(close_widget_local$during$local), + close_widget_local$initial$local, + label = "local plot output size changes during transition" + ) + has_local_size_changes <- expect_true( + length(close_widget_local$during$local) > 1, + label = "has local plot output size changes during transition" + ) + if (has_local_size_changes) { + expect_true( + all(diff(close_widget_local$during$local) > 0), + label = "local plot output size changes are increasing" + ) + } - # expand widget shared sidebar -------- + expect_equal( + close_widget_local$during$shared, + close_widget_local$initial$shared, + label = "shared plot output size during transition" + ) + + # expand widget shared sidebar ---------------------------------------------- open_widget_shared <- watch_sidebar_transition( app, sidebar = "shared", @@ -247,11 +427,47 @@ test_that("312-bslib-sidebar-resize", { expect_sidebar_shown("sidebar-shared") # plot output image size changed during expand for both plots - expect_gt(length(unique(open_widget_shared$during$local)), 1) - expect_gt(length(unique(open_widget_shared$during$shared)), 1) + expect_gt( + length(open_widget_shared$during$local), + expected = 1, + label = "local plot output size changes" + ) + expect_gt( + length(open_widget_shared$during$shared), + expected = 1, + label = "shared plot output size changes" + ) # plot output image size was shrinking during transition - expect_lt(max(open_widget_shared$during$local), open_widget_shared$initial$local) - expect_lt(max(open_widget_shared$during$shared), open_widget_shared$initial$shared) + expect_lt( + max(open_widget_shared$during$local), + open_widget_shared$initial$local, + label = "local plot output size during transition" + ) + has_local_size_changes <- expect_true( + length(open_widget_shared$during$local) > 1, + label = "has local plot output size changes during transition" + ) + if (has_local_size_changes) { + expect_true( + all(diff(open_widget_shared$during$local) < 0), + label = "local plot output size changes are decreasing" + ) + } + expect_lt( + max(open_widget_shared$during$shared), + open_widget_shared$initial$shared, + label = "shared plot output size during transition" + ) + has_shared_size_changes <- expect_true( + length(open_widget_shared$during$shared) > 1, + label = "has shared plot output size changes during transition" + ) + if (has_shared_size_changes) { + expect_true( + all(diff(open_widget_shared$during$shared) < 0), + label = "shared plot output size changes are decreasing" + ) + } }) From 3673e292c539b502093c6da49c7f9f8172d1d48d Mon Sep 17 00:00:00 2001 From: gadenbuie Date: Tue, 9 May 2023 20:22:05 +0000 Subject: [PATCH 06/26] Generate apps deps (GitHub Actions) --- R/data-apps-deps.R | 108 ++++++++++++++++++++++----------------------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/R/data-apps-deps.R b/R/data-apps-deps.R index c22d083e1c..30a60ff8a2 100644 --- a/R/data-apps-deps.R +++ b/R/data-apps-deps.R @@ -1,63 +1,63 @@ # Do not edit by hand! # This file is automatically generated by `./inst/gha/data-apps-deps-update.R` -apps_deps <- c("base64enc", "BH", "Cairo", "clipr", "curl", "DBI", "dbplyr", -"DiagrammeR", "dplyr", "evaluate", "future", "ggplot2", "ggvis", -"hexbin", "highcharter", "jsonlite", "knitr", "magrittr", "maps", -"markdown", "memoise", "networkD3", "plogr", "png", "progress", -"pryr", "radiant", "ragg", "RColorBrewer", "reactable", "reactR", -"rlang", "rmarkdown", "rprojroot", "rsconnect", "RSQLite", "rversions", -"scales", "sf", "shinyAce", "shinydashboard", "shinyjs", "showtext", -"sysfonts", "systemfonts", "testthat", "tidyr", "tm", "waldo", +apps_deps <- c("base64enc", "BH", "Cairo", "clipr", "curl", "DBI", "dbplyr", +"DiagrammeR", "dplyr", "evaluate", "future", "ggplot2", "ggvis", +"hexbin", "highcharter", "jsonlite", "knitr", "magrittr", "maps", +"markdown", "memoise", "networkD3", "plogr", "png", "progress", +"pryr", "radiant", "ragg", "RColorBrewer", "reactable", "reactR", +"rlang", "rmarkdown", "rprojroot", "rsconnect", "RSQLite", "rversions", +"scales", "sf", "shinyAce", "shinydashboard", "shinyjs", "showtext", +"sysfonts", "systemfonts", "testthat", "tidyr", "tm", "waldo", "withr", "wordcloud") -apps_deps_map <- list(`001-hello` = "rsconnect", `012-datatables` = "ggplot2", - `016-knitr-pdf` = "rmarkdown", `020-knit-html` = c("evaluate", - "knitr", "rmarkdown"), `021-selectize-plot` = "maps", `022-unicode-chinese` = c("curl", - "showtext", "sysfonts"), `026-shiny-inline` = "rmarkdown", - `027-absolutely-positioned-panels` = "markdown", `047-image-output` = "png", - `048-including-html-text-and-markdown-files` = "markdown", - `051-movie-explorer` = c("DBI", "dbplyr", "dplyr", "ggvis", - "plogr", "RSQLite"), `063-superzip-example` = c("dplyr", - "RColorBrewer", "scales"), `082-word-cloud` = c("BH", "memoise", - "tm", "wordcloud"), `093-plot-interaction-basic` = "ggplot2", - `094-image-interaction-basic` = "png", `095-plot-interaction-advanced` = c("ggplot2", - "scales"), `099-plot-interaction-article-4` = "ggplot2", - `101-plot-interaction-article-6` = "ggplot2", `102-plot-interaction-article-7` = "ggplot2", - `103-plot-interaction-article-8` = "ggplot2", `104-plot-interaction-select` = "ggplot2", - `105-plot-interaction-zoom` = "ggplot2", `106-plot-interaction-exclude` = "ggplot2", - `108-module-output` = c("dplyr", "ggplot2"), `112-generate-report` = "rmarkdown", +apps_deps_map <- list(`001-hello` = "rsconnect", `012-datatables` = "ggplot2", + `016-knitr-pdf` = "rmarkdown", `020-knit-html` = c("evaluate", + "knitr", "rmarkdown"), `021-selectize-plot` = "maps", `022-unicode-chinese` = c("curl", + "showtext", "sysfonts"), `026-shiny-inline` = "rmarkdown", + `027-absolutely-positioned-panels` = "markdown", `047-image-output` = "png", + `048-including-html-text-and-markdown-files` = "markdown", + `051-movie-explorer` = c("DBI", "dbplyr", "dplyr", "ggvis", + "plogr", "RSQLite"), `063-superzip-example` = c("dplyr", + "RColorBrewer", "scales"), `082-word-cloud` = c("BH", "memoise", + "tm", "wordcloud"), `093-plot-interaction-basic` = "ggplot2", + `094-image-interaction-basic` = "png", `095-plot-interaction-advanced` = c("ggplot2", + "scales"), `099-plot-interaction-article-4` = "ggplot2", + `101-plot-interaction-article-6` = "ggplot2", `102-plot-interaction-article-7` = "ggplot2", + `103-plot-interaction-article-8` = "ggplot2", `104-plot-interaction-select` = "ggplot2", + `105-plot-interaction-zoom` = "ggplot2", `106-plot-interaction-exclude` = "ggplot2", + `108-module-output` = c("dplyr", "ggplot2"), `112-generate-report` = "rmarkdown", `118-highcharter-births` = c("dplyr", "highcharter", "tidyr" - ), `121-async-timer` = c("future", "magrittr"), `122-async-outputs` = "future", - `123-async-renderprint` = "future", `124-async-download` = "future", - `125-async-req` = "future", `126-async-ticks` = "future", - `129-async-perf` = c("future", "ggplot2"), `140-selectize-inputs` = "jsonlite", - `141-radiant` = "radiant", `143-async-plot-caching` = "ggplot2", - `147-websocket` = "shinyjs", `150-networkD3-sankey` = c("networkD3", - "shinydashboard"), `151-reactr-input` = "reactR", `153-connection-header` = c("curl", - "future"), `156-subapps` = "rmarkdown", `161-discrete-limits` = c("dplyr", - "ggplot2"), `168-supporting-r-dir` = "withr", `169-prerender` = "rmarkdown", - `173-invalidatelater-leak` = "pryr", `174-throttle-debounce` = "magrittr", - `181-report-image` = c("Cairo", "jsonlite", "ragg", "showtext", - "sysfonts", "systemfonts"), `182-report-png` = c("Cairo", + ), `121-async-timer` = c("future", "magrittr"), `122-async-outputs` = "future", + `123-async-renderprint` = "future", `124-async-download` = "future", + `125-async-req` = "future", `126-async-ticks` = "future", + `129-async-perf` = c("future", "ggplot2"), `140-selectize-inputs` = "jsonlite", + `141-radiant` = "radiant", `143-async-plot-caching` = "ggplot2", + `147-websocket` = "shinyjs", `150-networkD3-sankey` = c("networkD3", + "shinydashboard"), `151-reactr-input` = "reactR", `153-connection-header` = c("curl", + "future"), `156-subapps` = "rmarkdown", `161-discrete-limits` = c("dplyr", + "ggplot2"), `168-supporting-r-dir` = "withr", `169-prerender` = "rmarkdown", + `173-invalidatelater-leak` = "pryr", `174-throttle-debounce` = "magrittr", + `181-report-image` = c("Cairo", "jsonlite", "ragg", "showtext", + "sysfonts", "systemfonts"), `182-report-png` = c("Cairo", "jsonlite", "ragg", "showtext", "sysfonts", "systemfonts" - ), `183-report-cairo` = c("Cairo", "jsonlite", "ragg", "showtext", - "sysfonts", "systemfonts"), `184-report-ragg` = c("Cairo", + ), `183-report-cairo` = c("Cairo", "jsonlite", "ragg", "showtext", + "sysfonts", "systemfonts"), `184-report-ragg` = c("Cairo", "jsonlite", "ragg", "showtext", "sysfonts", "systemfonts" - ), `185-report-theme` = c("Cairo", "jsonlite", "knitr", "ragg", - "rmarkdown", "waldo"), `193-reactlog-dynamic-ui` = "rversions", - `200-flexdashboard-render-text` = c("knitr", "rmarkdown"), - `205-dynamic-tabs-compat` = "withr", `206-freeze-thaw` = "rlang", - `208-bind-cache-event` = "magrittr", `209-datepicker` = c("jsonlite", - "magrittr", "rlang"), `210-future_promise` = c("future", - "magrittr", "shinyjs"), `211-sv-custom-inputs` = "base64enc", - `212-daterangepicker` = "jsonlite", `212-shinymeta` = c("clipr", + ), `185-report-theme` = c("Cairo", "jsonlite", "knitr", "ragg", + "rmarkdown", "waldo"), `193-reactlog-dynamic-ui` = "rversions", + `200-flexdashboard-render-text` = c("knitr", "rmarkdown"), + `205-dynamic-tabs-compat` = "withr", `206-freeze-thaw` = "rlang", + `208-bind-cache-event` = "magrittr", `209-datepicker` = c("jsonlite", + "magrittr", "rlang"), `210-future_promise` = c("future", + "magrittr", "shinyjs"), `211-sv-custom-inputs` = "base64enc", + `212-daterangepicker` = "jsonlite", `212-shinymeta` = c("clipr", "dplyr", "shinyAce"), `216-quosures` = c("DiagrammeR", "rlang" - ), `217-snapshot-info-option` = c("jsonlite", "testthat"), - `217-snapshot-info-url` = c("jsonlite", "testthat"), `221-async-script-dynamic-ui` = "rlang", - `300-bs-themer` = c("curl", "ggplot2", "hexbin", "knitr", - "reactable", "rlang", "rprojroot", "rsconnect"), `301-bs-themes` = c("ggplot2", - "rversions", "sf", "withr"), `302-bootswatch-themes` = c("ggplot2", - "progress", "rversions", "sf", "withr"), `304-bslib-card` = c("rlang", + ), `217-snapshot-info-option` = c("jsonlite", "testthat"), + `217-snapshot-info-url` = c("jsonlite", "testthat"), `221-async-script-dynamic-ui` = "rlang", + `300-bs-themer` = c("curl", "ggplot2", "hexbin", "knitr", + "reactable", "rlang", "rprojroot", "rsconnect"), `301-bs-themes` = c("ggplot2", + "rversions", "sf", "withr"), `302-bootswatch-themes` = c("ggplot2", + "progress", "rversions", "sf", "withr"), `304-bslib-card` = c("rlang", "rversions"), `305-bslib-value-box` = c("rlang", "rversions" - ), `309-flexdashboard-tabs-navs` = "rmarkdown", `310-bslib-sidebar-dynamic` = c("rversions", - "testthat"), `311-bslib-sidebar-toggle-methods` = c("rversions", + ), `309-flexdashboard-tabs-navs` = "rmarkdown", `310-bslib-sidebar-dynamic` = c("rversions", + "testthat"), `311-bslib-sidebar-toggle-methods` = c("rversions", "testthat"), `312-bslib-sidebar-resize` = "ggplot2") From 844bf7fd6ce20b01a66f29576753be35fc4144d7 Mon Sep 17 00:00:00 2001 From: Garrick Aden-Buie Date: Wed, 10 May 2023 10:53:03 -0400 Subject: [PATCH 07/26] Refactor test code to avoid duplication --- .../tests/testthat/test-shinytest2.R | 428 +++++------------- 1 file changed, 116 insertions(+), 312 deletions(-) diff --git a/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R b/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R index 8eba27e464..f28b73d363 100644 --- a/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R +++ b/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R @@ -122,193 +122,141 @@ window.updatedOutputs = []; ) } -# 312-bslib-sidebar-resize ---------------------------------------------------- -test_that("312-bslib-sidebar-resize", { - app <- AppDriver$new( - name = "312-bslib-sidebar-resize", - variant = platform_variant(), - height = 1600, - width = 1200, - view = interactive(), - options = list(bslib.precompiled = FALSE), - expect_values_screenshot_args = FALSE - ) - - expect_sidebar_hidden <- expect_sidebar_hidden_factory(app) - expect_sidebar_shown <- expect_sidebar_shown_factory(app) - - # STATIC PAGE ================================================================ +expect_sidebar_transition <- function( + app, + sidebar = c("shared", "local"), + page = c("static", "widget"), + open_end = c("open", "closed") +) { + sidebar <- match.arg(sidebar) + page <- match.arg(page) + open_end <- match.arg(open_end) - # collapse static shared sidebar -------------------------------------------- - close_static_shared <- watch_sidebar_transition( - app, - sidebar = "shared", - page = "static" - ) + will_transition <- c("local", if (sidebar == "shared") "shared") + change_dir <- if (open_end == "open") "expand" else "collapse" - expect_sidebar_hidden("sidebar-shared") + res <- watch_sidebar_transition(app, sidebar = sidebar, page = page) - # plot output image size changed during collapse for both plots - expect_gt( - length(close_static_shared$during$local), - expected = 1, - label = "local plot output size changes during transition" - ) - expect_gt( - length(close_static_shared$during$shared), - expected = 1, - label = "shared plot output size changes during transition" - ) + sidebar_id <- + if (sidebar == "shared") { + "sidebar-shared" + } else { + paste0("sidebar-local-", page) + } + if (open_end == "open") { + expect_sidebar_shown_factory(app)(sidebar_id) + } else { + expect_sidebar_hidden_factory(app)(sidebar_id) + } - # plot output image size was growing during transition - expect_gt( - min(close_static_shared$during$local), - close_static_shared$initial$local, - label = "minimum local plot output size during transition" - ) - has_local_size_changes <- expect_true( - length(close_static_shared$during$local) > 1, - label = "has local plot output size changes during transition" - ) - if (has_local_size_changes) { - expect_true( - all(diff(close_static_shared$during$local) > 0), - label = "local plot output size was growing during transition" + # Plot output size changes during the transition + if ("local" %in% will_transition) { + expect_gt( + length(res$during$local), + expected = 1, + label = "local plot output size changes during transition" ) } - expect_gt( - min(close_static_shared$during$shared), - close_static_shared$initial$shared, - label = "shared plot output size during transition" - ) - has_shared_size_changes <- expect_true( - length(close_static_shared$during$shared) > 1, - label = "has shared plot output size changes during transition" - ) - if (has_shared_size_changes) { - expect_true( - all(diff(close_static_shared$during$shared) > 0), - label = "shared plot output size was growing during transition" + if ("shared" %in% will_transition) { + expect_gt( + length(res$during$shared), + expected = 1, + label = "shared plot output size changes during transition" ) } - # both plots updated at the end of the transition - expect_setequal( - close_static_shared$outputs, - c("plot_static_local", "plot_static_shared") - ) - - # collapse static local sidebar --------------------------------------------- - close_static_local <- watch_sidebar_transition( - app, - sidebar = "local", - page = "static" - ) - - expect_sidebar_hidden("sidebar-local-static") - - # plot output image size changed during collapse for local plot only - expect_gt( - length(close_static_local$during$local), - expected = 1, - label = "local plot output size changes during transition" - ) - expect_equal( - length(close_static_local$during$shared), - expected = 1, - label = "shared plot output size changes during transition" - ) + expect_grows_or_shrinks <- function(plot = c("local", "shared")) { + if (open_end == "closed") { + # initial size is a lower bound, plots grow as sidebar collapses + expect_gt( + min(res$during[[plot]]), + res$initial[[plot]], + label = sprintf("minimum %s plot output size during transition", plot) + ) + has_size_changes <- expect_true( + length(res$during[[plot]]) > 1, + label = sprintf("has %s plot output size changes during transition", plot) + ) + if (has_size_changes) { + expect_true( + all(diff(res$during[[plot]]) > 0), + label = sprintf("%s plot output size was growing during transition", plot) + ) + } + } else { + # initial size is the upper bound, plots shrink as sidebar expands + expect_lt( + max(res$during[[plot]]), + res$initial[[plot]], + label = sprintf("maximum %s plot output size during transition", plot) + ) + has_size_changes <- expect_true( + length(res$during[[plot]]) > 1, + label = sprintf("has %s plot output size changes during transition", plot) + ) + if (has_size_changes) { + expect_true( + all(diff(res$during[[plot]]) < 0), + label = sprintf("%s plot output size was growing during transition", plot) + ) + } + } + } - # plot output image size was growing during transition for local only - expect_gt( - min(close_static_local$during$local), - close_static_local$initial$local, - label = "local plot output size was growing during transition" - ) - has_local_size_changes <- expect_true( - length(close_static_local$during$local) > 1, - label = "has local plot output size changes during transition" - ) - if (has_local_size_changes) { - expect_true( - all(diff(close_static_local$during$local) > 0), - label = "local plot output size changes" + # plot output image size was growing/shrinking during transition + if ("local" %in% will_transition) { + expect_grows_or_shrinks("local") + } else { + expect_equal( + res$during$local, + res$initial$local, + label = "local plot output size did not change during transition" ) } - expect_equal( - close_static_local$during$shared, - close_static_local$initial$shared, - label = "shared plot output size during transition" - ) + if ("shared" %in% will_transition) { + expect_grows_or_shrinks("shared") + } else { + expect_equal( + res$during$shared, + res$initial$shared, + label = "shared plot output size did not change during transition" + ) + } - # local plot updated at the end of the transition - expect_equal( - close_static_local$outputs, - "plot_static_local", - label = "plot updates at end of transition" - ) + if (page == "static") { + # plots update at the end of the transition + expected_updates <- paste0("plot_static_", will_transition) + expect_setequal(res$outputs, !!expected_updates) + } +} - # expand static shared sidebar ---------------------------------------------- - open_static_shared <- watch_sidebar_transition( - app, - sidebar = "shared", - page = "static" +# 312-bslib-sidebar-resize ---------------------------------------------------- +test_that("312-bslib-sidebar-resize", { + app <- AppDriver$new( + name = "312-bslib-sidebar-resize", + variant = platform_variant(), + height = 1600, + width = 1200, + view = interactive(), + options = list(bslib.precompiled = FALSE), + expect_values_screenshot_args = FALSE ) - expect_sidebar_shown("sidebar-shared") + expect_sidebar_hidden <- expect_sidebar_hidden_factory(app) + expect_sidebar_shown <- expect_sidebar_shown_factory(app) - # plot output image size changed during expand for both plots - expect_gt( - length(open_static_shared$during$local), - expected = 1, - label = "local plot output size changes" - ) - expect_gt( - length(open_static_shared$during$shared), - expected = 1, - label = "shared plot output size changes" - ) + # STATIC PAGE ================================================================ - # plot output image size was shrinking during transition - expect_lt( - max(open_static_shared$during$local), - open_static_shared$initial$local, - label = "local plot output image size changes during transition" - ) - has_local_size_changes <- expect_true( - length(open_static_shared$during$local) > 1, - label = "has local plot output image size changes during transition" - ) - if (has_local_size_changes) { - expect_true( - all(diff(open_static_shared$during$local) < 0), - label = "local plot output image size was shrinking during transition" - ) - } + # collapse static shared sidebar -------------------------------------------- + expect_sidebar_transition(app, "shared", "static", open_end = "closed") - expect_lt( - max(open_static_shared$during$shared), - open_static_shared$initial$shared, - label = "shared plot output image size changes during transition" - ) - has_shared_size_changes <- expect_true( - length(open_static_shared$during$shared) > 1, - label = "has shared plot output image size changes during transition" - ) - if (has_shared_size_changes) { - expect_true( - all(diff(open_static_shared$during$shared) < 0), - label = "shared plot output image size was shrinking during transition" - ) - } + # collapse static local sidebar --------------------------------------------- + expect_sidebar_transition(app, "local", "static", open_end = "closed") - # both plots updated at the end of the transition - expect_setequal( - open_static_shared$outputs, - c("plot_static_local", "plot_static_shared") - ) + # expand static shared sidebar ---------------------------------------------- + expect_sidebar_transition(app, "shared", "static", open_end = "open") # SWITCH TO WIDGET PAGE ====================================================== app$ @@ -319,155 +267,11 @@ test_that("312-bslib-sidebar-resize", { # won't trigger a 'shiny:value' event. # collapse widget shared sidebar -------------------------------------------- - close_widget_shared <- watch_sidebar_transition( - app, - sidebar = "shared", - page = "widget" - ) - - expect_sidebar_hidden("sidebar-shared") - - # plot output image size changed during collapse for both plots - expect_gt( - length(close_widget_shared$during$local), - expected = 1, - label = "local plot output size changes during transition" - ) - expect_gt( - length(close_widget_shared$during$shared), - expected = 1, - label = "shared plot output size changes during transition" - ) - - # plot output image size was growing during transition - expect_gt( - min(close_widget_shared$during$local), - expected = close_widget_shared$initial$local, - label = "local plot output size changes during transition" - ) - - has_local_size_changes <- expect_true( - length(close_widget_shared$during$local) > 1, - label = "has local plot output size changes during transition" - ) - if (has_local_size_changes) { - expect_true( - all(diff(close_widget_shared$during$local) > 0), - label = "local plot output size was growing during transition" - ) - } - - expect_gt( - min(close_widget_shared$during$shared), - expected = close_widget_shared$initial$shared, - label = "shared plot output size changes during transition" - ) - has_shared_size_changes <- expect_true( - length(close_widget_shared$during$shared) > 1, - label = "has shared plot output size changes during transition" - ) - if (has_shared_size_changes) { - expect_true( - all(diff(close_widget_shared$during$shared) > 0), - label = "shared plot output size changes during transition" - ) - } + expect_sidebar_transition(app, "shared", "widget", open_end = "closed") # collapse widget local sidebar --------------------------------------------- - close_widget_local <- watch_sidebar_transition( - app, - sidebar = "local", - page = "widget" - ) - - expect_sidebar_hidden("sidebar-local-widget") - - # plot output image size changed during collapse for local plot only - expect_gt( - length(close_widget_local$during$local), - expected = 1, - label = "local plot output size changes during collapse" - ) - expect_equal( - length(close_widget_local$during$shared), - expected = 1, - label = "shared plot output size changes during collapse" - ) - - # plot output image size was growing during transition for local only - expect_gt( - min(close_widget_local$during$local), - close_widget_local$initial$local, - label = "local plot output size changes during transition" - ) - has_local_size_changes <- expect_true( - length(close_widget_local$during$local) > 1, - label = "has local plot output size changes during transition" - ) - if (has_local_size_changes) { - expect_true( - all(diff(close_widget_local$during$local) > 0), - label = "local plot output size changes are increasing" - ) - } - - expect_equal( - close_widget_local$during$shared, - close_widget_local$initial$shared, - label = "shared plot output size during transition" - ) + expect_sidebar_transition(app, "local", "widget", open_end = "closed") # expand widget shared sidebar ---------------------------------------------- - open_widget_shared <- watch_sidebar_transition( - app, - sidebar = "shared", - page = "widget" - ) - - expect_sidebar_shown("sidebar-shared") - - # plot output image size changed during expand for both plots - expect_gt( - length(open_widget_shared$during$local), - expected = 1, - label = "local plot output size changes" - ) - expect_gt( - length(open_widget_shared$during$shared), - expected = 1, - label = "shared plot output size changes" - ) - - # plot output image size was shrinking during transition - expect_lt( - max(open_widget_shared$during$local), - open_widget_shared$initial$local, - label = "local plot output size during transition" - ) - has_local_size_changes <- expect_true( - length(open_widget_shared$during$local) > 1, - label = "has local plot output size changes during transition" - ) - if (has_local_size_changes) { - expect_true( - all(diff(open_widget_shared$during$local) < 0), - label = "local plot output size changes are decreasing" - ) - } - - expect_lt( - max(open_widget_shared$during$shared), - open_widget_shared$initial$shared, - label = "shared plot output size during transition" - ) - has_shared_size_changes <- expect_true( - length(open_widget_shared$during$shared) > 1, - label = "has shared plot output size changes during transition" - ) - if (has_shared_size_changes) { - expect_true( - all(diff(open_widget_shared$during$shared) < 0), - label = "shared plot output size changes are decreasing" - ) - } + expect_sidebar_transition(app, "shared", "widget", open_end = "open") }) From 6164d43791f9367f544f86c2e14fb3f2d91fbe45 Mon Sep 17 00:00:00 2001 From: Garrick Aden-Buie Date: Wed, 10 May 2023 11:00:29 -0400 Subject: [PATCH 08/26] Another small refactor for better failure backtraces --- .../tests/testthat/test-shinytest2.R | 113 +++++++++++------- 1 file changed, 69 insertions(+), 44 deletions(-) diff --git a/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R b/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R index f28b73d363..18a839bf8c 100644 --- a/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R +++ b/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R @@ -132,10 +132,8 @@ expect_sidebar_transition <- function( page <- match.arg(page) open_end <- match.arg(open_end) - will_transition <- c("local", if (sidebar == "shared") "shared") - change_dir <- if (open_end == "open") "expand" else "collapse" - - res <- watch_sidebar_transition(app, sidebar = sidebar, page = page) + expect_sidebar_shown <- expect_sidebar_shown_factory(app) + expect_sidebar_hidden <- expect_sidebar_hidden_factory(app) sidebar_id <- if (sidebar == "shared") { @@ -143,11 +141,26 @@ expect_sidebar_transition <- function( } else { paste0("sidebar-local-", page) } - if (open_end == "open") { - expect_sidebar_shown_factory(app)(sidebar_id) - } else { - expect_sidebar_hidden_factory(app)(sidebar_id) - } + + will_transition <- c("local", if (sidebar == "shared") "shared") + change_dir <- if (open_end == "open") "expand" else "collapse" + + # test sidebar state before transition + switch( + open_end, + open = expect_sidebar_hidden(sidebar_id), + closed = expect_sidebar_shown(sidebar_id) + ) + + # toggle the sidebar and measure the transition + res <- watch_sidebar_transition(app, sidebar = sidebar, page = page) + + # test sidebar state after transition + switch( + open_end, + open = expect_sidebar_shown(sidebar_id), + closed = expect_sidebar_hidden(sidebar_id) + ) # Plot output size changes during the transition if ("local" %in% will_transition) { @@ -166,47 +179,55 @@ expect_sidebar_transition <- function( ) } - expect_grows_or_shrinks <- function(plot = c("local", "shared")) { - if (open_end == "closed") { - # initial size is a lower bound, plots grow as sidebar collapses - expect_gt( - min(res$during[[plot]]), - res$initial[[plot]], - label = sprintf("minimum %s plot output size during transition", plot) - ) - has_size_changes <- expect_true( - length(res$during[[plot]]) > 1, - label = sprintf("has %s plot output size changes during transition", plot) - ) - if (has_size_changes) { - expect_true( - all(diff(res$during[[plot]]) > 0), - label = sprintf("%s plot output size was growing during transition", plot) - ) - } - } else { - # initial size is the upper bound, plots shrink as sidebar expands - expect_lt( - max(res$during[[plot]]), - res$initial[[plot]], - label = sprintf("maximum %s plot output size during transition", plot) + expect_plot_grows <- function(plot = c("local", "shared")) { + plot <- match.arg(plot) + + # initial size is a lower bound, plots grow as sidebar collapses + expect_gt( + min(res$during[[plot]]), + res$initial[[!!plot]], + label = sprintf("minimum %s plot output size during transition", plot) + ) + has_size_changes <- expect_true( + length(res$during[[plot]]) > 1, + label = sprintf("has %s plot output size changes during transition", plot) + ) + if (has_size_changes) { + expect_true( + all(diff(res$during[[plot]]) > 0), + label = sprintf("%s plot output size was growing during transition", plot) ) - has_size_changes <- expect_true( - length(res$during[[plot]]) > 1, - label = sprintf("has %s plot output size changes during transition", plot) + } + } + + expect_plot_shrinks <- function(plot = c("local", "shared")) { + plot <- match.arg(plot) + + # initial size is the upper bound, plots shrink as sidebar expands + expect_lt( + max(res$during[[plot]]), + res$initial[[!!plot]], + label = sprintf("maximum %s plot output size during transition", plot) + ) + has_size_changes <- expect_true( + length(res$during[[plot]]) > 1, + label = sprintf("has %s plot output size changes during transition", plot) + ) + if (has_size_changes) { + expect_true( + all(diff(res$during[[plot]]) < 0), + label = sprintf("%s plot output size was growing during transition", plot) ) - if (has_size_changes) { - expect_true( - all(diff(res$during[[plot]]) < 0), - label = sprintf("%s plot output size was growing during transition", plot) - ) - } } } # plot output image size was growing/shrinking during transition if ("local" %in% will_transition) { - expect_grows_or_shrinks("local") + switch( + open_end, + open = expect_plot_shrinks("local"), + closed = expect_plot_grows("local") + ) } else { expect_equal( res$during$local, @@ -216,7 +237,11 @@ expect_sidebar_transition <- function( } if ("shared" %in% will_transition) { - expect_grows_or_shrinks("shared") + switch( + open_end, + open = expect_plot_shrinks("shared"), + closed = expect_plot_grows("shared") + ) } else { expect_equal( res$during$shared, From 9eaee9ae92749b84f0bd2b02ae88085510b8ba26 Mon Sep 17 00:00:00 2001 From: Garrick Aden-Buie Date: Mon, 15 May 2023 13:34:31 -0400 Subject: [PATCH 09/26] Add client-size htmlwidget resizing test --- inst/apps/312-bslib-sidebar-resize/app.R | 33 ++++++++++++- .../tests/testthat/test-shinytest2.R | 49 +++++++++++++------ 2 files changed, 67 insertions(+), 15 deletions(-) diff --git a/inst/apps/312-bslib-sidebar-resize/app.R b/inst/apps/312-bslib-sidebar-resize/app.R index 23328c1bb1..6dbb6a49a0 100644 --- a/inst/apps/312-bslib-sidebar-resize/app.R +++ b/inst/apps/312-bslib-sidebar-resize/app.R @@ -57,7 +57,7 @@ ui <- page_navbar( ), nav( "Widget", - h2("Widget plot resizing", class = "mt-4 mb-2"), + h2("Widget plot resizing"), p( "The plot in the layout below should stretch while the sidebar is opening", "or closing. There should be no layout shift after the transition is", @@ -83,6 +83,37 @@ ui <- page_navbar( div(class = "col-6", lorem2, lorem1) ) ), + nav( + "Client", + h2("Client-side htmlwidget resizing"), + p( + "The plot in the layout below should stretch while the sidebar is opening", + "or closing. There should be no layout shift after the transition is", + "complete." + ), + layout_sidebar( + sidebar = sidebar( + title = "Toggle me", + id = "sidebar-local-client", + lorem1, lorem2, lorem1 + ), + lorem1, + div(id = "plot_client_local", plot_ly(x = rnorm(100))), + lorem2 + ), + h2("Shared only", class = "my-3"), + p( + "The next plot should resize smoothly only when the shared sidebar is transitioning." + ), + div( + class = "row", + div( + class = "col-6", + div(id = "plot_client_shared", plot_ly(x = rnorm(100))) + ), + div(class = "col-6", lorem2, lorem1) + ) + ), footer = div(style = "min-height: 100vh") ) diff --git a/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R b/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R index 18a839bf8c..5ef199878b 100644 --- a/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R +++ b/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R @@ -55,19 +55,24 @@ js_element_width <- function(selector) { watch_sidebar_transition <- function( app, sidebar = c("shared", "local"), - page = c("static", "widget") + page = c("static", "widget", "client") ) { sidebar <- match.arg(sidebar) page <- match.arg(page) - id_sidebar <- if (sidebar == "shared") "sidebar-shared" else paste0("sidebar-local-", page) - sel_plot <- function(which = c("shared", "local")) { - plot_container <- - if (page == "static") { - "img" - } else { - ".plot-container > .svg-container" - } + id_sidebar <- switch( + sidebar, + shared = "sidebar-shared", + paste0("sidebar-local-", page) + ) + + sel_plot <- function(which = c("shared", "local" , "client")) { + plot_container <- switch( + page, + static = "img", + widget = ".plot-container > .svg-container", + client = ".plotly > .plot-container > .svg-container" + ) paste0("#plot_", page, "_", which, " > ", plot_container) } sel_plot_img_local <- sel_plot("local") @@ -125,7 +130,7 @@ window.updatedOutputs = []; expect_sidebar_transition <- function( app, sidebar = c("shared", "local"), - page = c("static", "widget"), + page = c("static", "widget", "client"), open_end = c("open", "closed") ) { sidebar <- match.arg(sidebar) @@ -182,6 +187,8 @@ expect_sidebar_transition <- function( expect_plot_grows <- function(plot = c("local", "shared")) { plot <- match.arg(plot) + browser(expr = length(res$initial[[plot]]) != 1) + # initial size is a lower bound, plots grow as sidebar collapses expect_gt( min(res$during[[plot]]), @@ -269,9 +276,6 @@ test_that("312-bslib-sidebar-resize", { expect_values_screenshot_args = FALSE ) - expect_sidebar_hidden <- expect_sidebar_hidden_factory(app) - expect_sidebar_shown <- expect_sidebar_shown_factory(app) - # STATIC PAGE ================================================================ # collapse static shared sidebar -------------------------------------------- @@ -286,7 +290,7 @@ test_that("312-bslib-sidebar-resize", { # SWITCH TO WIDGET PAGE ====================================================== app$ click(selector = '.nav-link[data-value="Widget"]')$ - wait_for_js("document.getElementById('js-plotly-tester') ? true : false") + wait_for_js("$('#plot_widget_local:visible .svg-container').length > 0") # now we repeat all of the same tests above, except that the widget resizing # won't trigger a 'shiny:value' event. @@ -299,4 +303,21 @@ test_that("312-bslib-sidebar-resize", { # expand widget shared sidebar ---------------------------------------------- expect_sidebar_transition(app, "shared", "widget", open_end = "open") + + # SWITCH TO CLIENT PAGE ====================================================== + app$ + click(selector = '.nav-link[data-value="Client"]')$ + wait_for_js("$('#plot_client_local:visible .svg-container').length > 0") + + # now we repeat all of the same tests above, except that the widget resizing + # won't trigger a 'shiny:value' event. + + # collapse widget shared sidebar -------------------------------------------- + expect_sidebar_transition(app, "shared", "client", open_end = "closed") + + # collapse widget local sidebar --------------------------------------------- + expect_sidebar_transition(app, "local", "client", open_end = "closed") + + # expand widget shared sidebar ---------------------------------------------- + expect_sidebar_transition(app, "shared", "client", open_end = "open") }) From 0f8ef3cfbdce4f34e319401bec05882a64861257 Mon Sep 17 00:00:00 2001 From: Garrick Aden-Buie Date: Mon, 15 May 2023 16:45:02 -0400 Subject: [PATCH 10/26] Remove call to `browser()` --- .../312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R | 1 - 1 file changed, 1 deletion(-) diff --git a/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R b/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R index 5ef199878b..058b24d50a 100644 --- a/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R +++ b/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R @@ -187,7 +187,6 @@ expect_sidebar_transition <- function( expect_plot_grows <- function(plot = c("local", "shared")) { plot <- match.arg(plot) - browser(expr = length(res$initial[[plot]]) != 1) # initial size is a lower bound, plots grow as sidebar collapses expect_gt( From 50767b22071df16a52b30b6ec12195695eeb4c95 Mon Sep 17 00:00:00 2001 From: Garrick Aden-Buie Date: Thu, 18 May 2023 15:33:40 -0400 Subject: [PATCH 11/26] add debugging for windows and limit to just windows --- .github/workflows/apps-test-matrix.yml | 212 +++++++++--------- .../tests/testthat/test-shinytest2.R | 10 + 2 files changed, 116 insertions(+), 106 deletions(-) diff --git a/.github/workflows/apps-test-matrix.yml b/.github/workflows/apps-test-matrix.yml index 092bfbfda8..8339dc600f 100644 --- a/.github/workflows/apps-test-matrix.yml +++ b/.github/workflows/apps-test-matrix.yml @@ -24,116 +24,116 @@ jobs: needs: [precheck] uses: ./.github/workflows/apps-config.yml - macos-release: - if: ${{ ! cancelled() }} - needs: [config, ubuntu-release] - uses: ./.github/workflows/apps-test-os.yml - with: - r-version: ${{ needs.config.outputs.release }} - os: ${{ needs.config.outputs.macos }} - cache-version: ${{ needs.config.outputs.cache-version }} - secrets: - SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - macos-oldrel-1: - if: ${{ ! cancelled() }} - needs: [config, ubuntu-oldrel-1] - uses: ./.github/workflows/apps-test-os.yml - with: - r-version: ${{ needs.config.outputs.oldrel1 }} - os: ${{ needs.config.outputs.macos }} - cache-version: ${{ needs.config.outputs.cache-version }} - secrets: - SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - macos-oldrel-2: - if: ${{ ! cancelled() }} - needs: [config, ubuntu-oldrel-2] - uses: ./.github/workflows/apps-test-os.yml - with: - r-version: ${{ needs.config.outputs.oldrel2 }} - os: ${{ needs.config.outputs.macos }} - cache-version: ${{ needs.config.outputs.cache-version }} - secrets: - SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - macos-oldrel-3: - if: ${{ ! cancelled() }} - needs: [config, ubuntu-oldrel-3] - uses: ./.github/workflows/apps-test-os.yml - with: - r-version: ${{ needs.config.outputs.oldrel3 }} - os: ${{ needs.config.outputs.macos }} - cache-version: ${{ needs.config.outputs.cache-version }} - secrets: - SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - macos-oldrel-4: - if: ${{ ! cancelled() }} - needs: [config, ubuntu-oldrel-4] - uses: ./.github/workflows/apps-test-os.yml - with: - r-version: ${{ needs.config.outputs.oldrel4 }} - os: ${{ needs.config.outputs.macos }} - cache-version: ${{ needs.config.outputs.cache-version }} - secrets: - SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + # macos-release: + # if: ${{ ! cancelled() }} + # needs: [config, ubuntu-release] + # uses: ./.github/workflows/apps-test-os.yml + # with: + # r-version: ${{ needs.config.outputs.release }} + # os: ${{ needs.config.outputs.macos }} + # cache-version: ${{ needs.config.outputs.cache-version }} + # secrets: + # SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} + # SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + # macos-oldrel-1: + # if: ${{ ! cancelled() }} + # needs: [config, ubuntu-oldrel-1] + # uses: ./.github/workflows/apps-test-os.yml + # with: + # r-version: ${{ needs.config.outputs.oldrel1 }} + # os: ${{ needs.config.outputs.macos }} + # cache-version: ${{ needs.config.outputs.cache-version }} + # secrets: + # SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} + # SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + # macos-oldrel-2: + # if: ${{ ! cancelled() }} + # needs: [config, ubuntu-oldrel-2] + # uses: ./.github/workflows/apps-test-os.yml + # with: + # r-version: ${{ needs.config.outputs.oldrel2 }} + # os: ${{ needs.config.outputs.macos }} + # cache-version: ${{ needs.config.outputs.cache-version }} + # secrets: + # SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} + # SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + # macos-oldrel-3: + # if: ${{ ! cancelled() }} + # needs: [config, ubuntu-oldrel-3] + # uses: ./.github/workflows/apps-test-os.yml + # with: + # r-version: ${{ needs.config.outputs.oldrel3 }} + # os: ${{ needs.config.outputs.macos }} + # cache-version: ${{ needs.config.outputs.cache-version }} + # secrets: + # SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} + # SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + # macos-oldrel-4: + # if: ${{ ! cancelled() }} + # needs: [config, ubuntu-oldrel-4] + # uses: ./.github/workflows/apps-test-os.yml + # with: + # r-version: ${{ needs.config.outputs.oldrel4 }} + # os: ${{ needs.config.outputs.macos }} + # cache-version: ${{ needs.config.outputs.cache-version }} + # secrets: + # SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} + # SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - ubuntu-release: - needs: [precheck, config] - uses: ./.github/workflows/apps-test-os.yml - with: - r-version: ${{ needs.config.outputs.release }} - os: ${{ needs.config.outputs.ubuntu }} - cache-version: ${{ needs.config.outputs.cache-version }} - secrets: - SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - ubuntu-oldrel-1: - needs: [precheck, config] - uses: ./.github/workflows/apps-test-os.yml - with: - r-version: ${{ needs.config.outputs.oldrel1 }} - os: ${{ needs.config.outputs.ubuntu }} - cache-version: ${{ needs.config.outputs.cache-version }} - secrets: - SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - ubuntu-oldrel-2: - needs: [precheck, config] - uses: ./.github/workflows/apps-test-os.yml - with: - r-version: ${{ needs.config.outputs.oldrel2 }} - os: ${{ needs.config.outputs.ubuntu }} - cache-version: ${{ needs.config.outputs.cache-version }} - secrets: - SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - ubuntu-oldrel-3: - needs: [precheck, config] - uses: ./.github/workflows/apps-test-os.yml - with: - r-version: ${{ needs.config.outputs.oldrel3 }} - os: ${{ needs.config.outputs.ubuntu }} - cache-version: ${{ needs.config.outputs.cache-version }} - secrets: - SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - ubuntu-oldrel-4: - needs: [precheck, config] - uses: ./.github/workflows/apps-test-os.yml - with: - r-version: ${{ needs.config.outputs.oldrel4 }} - os: ${{ needs.config.outputs.ubuntu }} - cache-version: ${{ needs.config.outputs.cache-version }} - secrets: - SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + # ubuntu-release: + # needs: [precheck, config] + # uses: ./.github/workflows/apps-test-os.yml + # with: + # r-version: ${{ needs.config.outputs.release }} + # os: ${{ needs.config.outputs.ubuntu }} + # cache-version: ${{ needs.config.outputs.cache-version }} + # secrets: + # SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} + # SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + # ubuntu-oldrel-1: + # needs: [precheck, config] + # uses: ./.github/workflows/apps-test-os.yml + # with: + # r-version: ${{ needs.config.outputs.oldrel1 }} + # os: ${{ needs.config.outputs.ubuntu }} + # cache-version: ${{ needs.config.outputs.cache-version }} + # secrets: + # SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} + # SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + # ubuntu-oldrel-2: + # needs: [precheck, config] + # uses: ./.github/workflows/apps-test-os.yml + # with: + # r-version: ${{ needs.config.outputs.oldrel2 }} + # os: ${{ needs.config.outputs.ubuntu }} + # cache-version: ${{ needs.config.outputs.cache-version }} + # secrets: + # SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} + # SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + # ubuntu-oldrel-3: + # needs: [precheck, config] + # uses: ./.github/workflows/apps-test-os.yml + # with: + # r-version: ${{ needs.config.outputs.oldrel3 }} + # os: ${{ needs.config.outputs.ubuntu }} + # cache-version: ${{ needs.config.outputs.cache-version }} + # secrets: + # SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} + # SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + # ubuntu-oldrel-4: + # needs: [precheck, config] + # uses: ./.github/workflows/apps-test-os.yml + # with: + # r-version: ${{ needs.config.outputs.oldrel4 }} + # os: ${{ needs.config.outputs.ubuntu }} + # cache-version: ${{ needs.config.outputs.cache-version }} + # secrets: + # SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} + # SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} windows-release: if: ${{ ! cancelled() }} - needs: [config, macos-release] + needs: [config] uses: ./.github/workflows/apps-test-os.yml with: r-version: ${{ needs.config.outputs.release }} diff --git a/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R b/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R index 058b24d50a..64d1c6e8f3 100644 --- a/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R +++ b/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R @@ -277,6 +277,7 @@ test_that("312-bslib-sidebar-resize", { # STATIC PAGE ================================================================ + withCallingHandlers({ # collapse static shared sidebar -------------------------------------------- expect_sidebar_transition(app, "shared", "static", open_end = "closed") @@ -319,4 +320,13 @@ test_that("312-bslib-sidebar-resize", { # expand widget shared sidebar ---------------------------------------------- expect_sidebar_transition(app, "shared", "client", open_end = "open") + }, error = function(err) { + message("TEST FAILED --------------------------------") + message("Error received: ", conditionMessage(err)) + message("Printing logs...") + print(app$get_logs()) + message("saving screenshot...") + app$expect_screenshot(selector = "viewport") + message("screenshot saved...") + }) }) From 2e443c325b8ff57994189dda2e26b1e80db950dd Mon Sep 17 00:00:00 2001 From: Garrick Aden-Buie Date: Thu, 18 May 2023 16:21:52 -0400 Subject: [PATCH 12/26] debug: try again --- .github/workflows/apps-test-matrix.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/apps-test-matrix.yml b/.github/workflows/apps-test-matrix.yml index 8339dc600f..c308bea9f5 100644 --- a/.github/workflows/apps-test-matrix.yml +++ b/.github/workflows/apps-test-matrix.yml @@ -133,7 +133,7 @@ jobs: windows-release: if: ${{ ! cancelled() }} - needs: [config] + needs: [precheck, config] uses: ./.github/workflows/apps-test-os.yml with: r-version: ${{ needs.config.outputs.release }} @@ -144,7 +144,7 @@ jobs: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} windows-oldrel-1: if: ${{ ! cancelled() }} - needs: [config, macos-oldrel-1] + needs: [precheck, config] uses: ./.github/workflows/apps-test-os.yml with: r-version: ${{ needs.config.outputs.oldrel1 }} @@ -155,7 +155,7 @@ jobs: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} windows-oldrel-2: if: ${{ ! cancelled() }} - needs: [config, macos-oldrel-2] + needs: [precheck, config] uses: ./.github/workflows/apps-test-os.yml with: r-version: ${{ needs.config.outputs.oldrel2 }} @@ -166,7 +166,7 @@ jobs: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} windows-oldrel-3: if: ${{ ! cancelled() }} - needs: [config, macos-oldrel-3] + needs: [precheck, config] uses: ./.github/workflows/apps-test-os.yml with: r-version: ${{ needs.config.outputs.oldrel3 }} @@ -177,7 +177,7 @@ jobs: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} windows-oldrel-4: if: ${{ ! cancelled() }} - needs: [config, macos-oldrel-4] + needs: [precheck, config] uses: ./.github/workflows/apps-test-os.yml with: r-version: ${{ needs.config.outputs.oldrel4 }} From b78e1035f9e6e0331127fe5d2e8c61c5a383216d Mon Sep 17 00:00:00 2001 From: Garrick Aden-Buie Date: Thu, 18 May 2023 16:49:35 -0400 Subject: [PATCH 13/26] debug: more output printing --- .../tests/testthat/test-shinytest2.R | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R b/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R index 64d1c6e8f3..c6083b02f1 100644 --- a/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R +++ b/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R @@ -115,6 +115,19 @@ window.updatedOutputs = []; shared = app$get_js(js_element_width(sel_plot_img_shared)) ) + cat("\n----- Recording", sidebar, "sidebar on", page, "page transition -----") + cat_item <- function(which) { + value <- get(which) + cat("\n", which, ":") + cat("\n shared: ", paste(value[["shared"]], collapse = ", ")) + cat("\n local: ", paste(value[["local"]], collapse = ", ")) + } + cat_item("initial") + cat_item("during") + cat_item("final") + cat_item("outputs") + cat("\n----------------------------------------------\n\n") + # we only need unique observations between initial and final during$local <- unique(during$local) during$shared <- unique(during$shared) @@ -321,12 +334,12 @@ test_that("312-bslib-sidebar-resize", { # expand widget shared sidebar ---------------------------------------------- expect_sidebar_transition(app, "shared", "client", open_end = "open") }, error = function(err) { - message("TEST FAILED --------------------------------") - message("Error received: ", conditionMessage(err)) - message("Printing logs...") + cat("\n\n\n==== TEST FAILED ================================") + cat("\nError received: ", conditionMessage(err)) + cat("\nPrinting logs...") print(app$get_logs()) - message("saving screenshot...") + cat("\nsaving screenshot...") app$expect_screenshot(selector = "viewport") - message("screenshot saved...") + cat("\nscreenshot saved...") }) }) From e7ad0edb0f70a2c296ec4730e5cf1fc469983f8d Mon Sep 17 00:00:00 2001 From: Garrick Aden-Buie Date: Fri, 19 May 2023 10:36:30 -0400 Subject: [PATCH 14/26] Revert debugging changes This reverts commit b78e1035f9e6e0331127fe5d2e8c61c5a383216d. Revert "debug: try again" This reverts commit 2e443c325b8ff57994189dda2e26b1e80db950dd. Revert "add debugging for windows and limit to just windows" This reverts commit 50767b22071df16a52b30b6ec12195695eeb4c95. --- .github/workflows/apps-test-matrix.yml | 220 +++++++++--------- .../tests/testthat/test-shinytest2.R | 23 -- 2 files changed, 110 insertions(+), 133 deletions(-) diff --git a/.github/workflows/apps-test-matrix.yml b/.github/workflows/apps-test-matrix.yml index c308bea9f5..092bfbfda8 100644 --- a/.github/workflows/apps-test-matrix.yml +++ b/.github/workflows/apps-test-matrix.yml @@ -24,116 +24,116 @@ jobs: needs: [precheck] uses: ./.github/workflows/apps-config.yml - # macos-release: - # if: ${{ ! cancelled() }} - # needs: [config, ubuntu-release] - # uses: ./.github/workflows/apps-test-os.yml - # with: - # r-version: ${{ needs.config.outputs.release }} - # os: ${{ needs.config.outputs.macos }} - # cache-version: ${{ needs.config.outputs.cache-version }} - # secrets: - # SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} - # SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - # macos-oldrel-1: - # if: ${{ ! cancelled() }} - # needs: [config, ubuntu-oldrel-1] - # uses: ./.github/workflows/apps-test-os.yml - # with: - # r-version: ${{ needs.config.outputs.oldrel1 }} - # os: ${{ needs.config.outputs.macos }} - # cache-version: ${{ needs.config.outputs.cache-version }} - # secrets: - # SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} - # SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - # macos-oldrel-2: - # if: ${{ ! cancelled() }} - # needs: [config, ubuntu-oldrel-2] - # uses: ./.github/workflows/apps-test-os.yml - # with: - # r-version: ${{ needs.config.outputs.oldrel2 }} - # os: ${{ needs.config.outputs.macos }} - # cache-version: ${{ needs.config.outputs.cache-version }} - # secrets: - # SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} - # SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - # macos-oldrel-3: - # if: ${{ ! cancelled() }} - # needs: [config, ubuntu-oldrel-3] - # uses: ./.github/workflows/apps-test-os.yml - # with: - # r-version: ${{ needs.config.outputs.oldrel3 }} - # os: ${{ needs.config.outputs.macos }} - # cache-version: ${{ needs.config.outputs.cache-version }} - # secrets: - # SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} - # SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - # macos-oldrel-4: - # if: ${{ ! cancelled() }} - # needs: [config, ubuntu-oldrel-4] - # uses: ./.github/workflows/apps-test-os.yml - # with: - # r-version: ${{ needs.config.outputs.oldrel4 }} - # os: ${{ needs.config.outputs.macos }} - # cache-version: ${{ needs.config.outputs.cache-version }} - # secrets: - # SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} - # SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + macos-release: + if: ${{ ! cancelled() }} + needs: [config, ubuntu-release] + uses: ./.github/workflows/apps-test-os.yml + with: + r-version: ${{ needs.config.outputs.release }} + os: ${{ needs.config.outputs.macos }} + cache-version: ${{ needs.config.outputs.cache-version }} + secrets: + SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + macos-oldrel-1: + if: ${{ ! cancelled() }} + needs: [config, ubuntu-oldrel-1] + uses: ./.github/workflows/apps-test-os.yml + with: + r-version: ${{ needs.config.outputs.oldrel1 }} + os: ${{ needs.config.outputs.macos }} + cache-version: ${{ needs.config.outputs.cache-version }} + secrets: + SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + macos-oldrel-2: + if: ${{ ! cancelled() }} + needs: [config, ubuntu-oldrel-2] + uses: ./.github/workflows/apps-test-os.yml + with: + r-version: ${{ needs.config.outputs.oldrel2 }} + os: ${{ needs.config.outputs.macos }} + cache-version: ${{ needs.config.outputs.cache-version }} + secrets: + SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + macos-oldrel-3: + if: ${{ ! cancelled() }} + needs: [config, ubuntu-oldrel-3] + uses: ./.github/workflows/apps-test-os.yml + with: + r-version: ${{ needs.config.outputs.oldrel3 }} + os: ${{ needs.config.outputs.macos }} + cache-version: ${{ needs.config.outputs.cache-version }} + secrets: + SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + macos-oldrel-4: + if: ${{ ! cancelled() }} + needs: [config, ubuntu-oldrel-4] + uses: ./.github/workflows/apps-test-os.yml + with: + r-version: ${{ needs.config.outputs.oldrel4 }} + os: ${{ needs.config.outputs.macos }} + cache-version: ${{ needs.config.outputs.cache-version }} + secrets: + SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - # ubuntu-release: - # needs: [precheck, config] - # uses: ./.github/workflows/apps-test-os.yml - # with: - # r-version: ${{ needs.config.outputs.release }} - # os: ${{ needs.config.outputs.ubuntu }} - # cache-version: ${{ needs.config.outputs.cache-version }} - # secrets: - # SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} - # SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - # ubuntu-oldrel-1: - # needs: [precheck, config] - # uses: ./.github/workflows/apps-test-os.yml - # with: - # r-version: ${{ needs.config.outputs.oldrel1 }} - # os: ${{ needs.config.outputs.ubuntu }} - # cache-version: ${{ needs.config.outputs.cache-version }} - # secrets: - # SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} - # SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - # ubuntu-oldrel-2: - # needs: [precheck, config] - # uses: ./.github/workflows/apps-test-os.yml - # with: - # r-version: ${{ needs.config.outputs.oldrel2 }} - # os: ${{ needs.config.outputs.ubuntu }} - # cache-version: ${{ needs.config.outputs.cache-version }} - # secrets: - # SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} - # SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - # ubuntu-oldrel-3: - # needs: [precheck, config] - # uses: ./.github/workflows/apps-test-os.yml - # with: - # r-version: ${{ needs.config.outputs.oldrel3 }} - # os: ${{ needs.config.outputs.ubuntu }} - # cache-version: ${{ needs.config.outputs.cache-version }} - # secrets: - # SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} - # SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - # ubuntu-oldrel-4: - # needs: [precheck, config] - # uses: ./.github/workflows/apps-test-os.yml - # with: - # r-version: ${{ needs.config.outputs.oldrel4 }} - # os: ${{ needs.config.outputs.ubuntu }} - # cache-version: ${{ needs.config.outputs.cache-version }} - # secrets: - # SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} - # SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + ubuntu-release: + needs: [precheck, config] + uses: ./.github/workflows/apps-test-os.yml + with: + r-version: ${{ needs.config.outputs.release }} + os: ${{ needs.config.outputs.ubuntu }} + cache-version: ${{ needs.config.outputs.cache-version }} + secrets: + SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + ubuntu-oldrel-1: + needs: [precheck, config] + uses: ./.github/workflows/apps-test-os.yml + with: + r-version: ${{ needs.config.outputs.oldrel1 }} + os: ${{ needs.config.outputs.ubuntu }} + cache-version: ${{ needs.config.outputs.cache-version }} + secrets: + SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + ubuntu-oldrel-2: + needs: [precheck, config] + uses: ./.github/workflows/apps-test-os.yml + with: + r-version: ${{ needs.config.outputs.oldrel2 }} + os: ${{ needs.config.outputs.ubuntu }} + cache-version: ${{ needs.config.outputs.cache-version }} + secrets: + SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + ubuntu-oldrel-3: + needs: [precheck, config] + uses: ./.github/workflows/apps-test-os.yml + with: + r-version: ${{ needs.config.outputs.oldrel3 }} + os: ${{ needs.config.outputs.ubuntu }} + cache-version: ${{ needs.config.outputs.cache-version }} + secrets: + SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + ubuntu-oldrel-4: + needs: [precheck, config] + uses: ./.github/workflows/apps-test-os.yml + with: + r-version: ${{ needs.config.outputs.oldrel4 }} + os: ${{ needs.config.outputs.ubuntu }} + cache-version: ${{ needs.config.outputs.cache-version }} + secrets: + SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} windows-release: if: ${{ ! cancelled() }} - needs: [precheck, config] + needs: [config, macos-release] uses: ./.github/workflows/apps-test-os.yml with: r-version: ${{ needs.config.outputs.release }} @@ -144,7 +144,7 @@ jobs: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} windows-oldrel-1: if: ${{ ! cancelled() }} - needs: [precheck, config] + needs: [config, macos-oldrel-1] uses: ./.github/workflows/apps-test-os.yml with: r-version: ${{ needs.config.outputs.oldrel1 }} @@ -155,7 +155,7 @@ jobs: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} windows-oldrel-2: if: ${{ ! cancelled() }} - needs: [precheck, config] + needs: [config, macos-oldrel-2] uses: ./.github/workflows/apps-test-os.yml with: r-version: ${{ needs.config.outputs.oldrel2 }} @@ -166,7 +166,7 @@ jobs: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} windows-oldrel-3: if: ${{ ! cancelled() }} - needs: [precheck, config] + needs: [config, macos-oldrel-3] uses: ./.github/workflows/apps-test-os.yml with: r-version: ${{ needs.config.outputs.oldrel3 }} @@ -177,7 +177,7 @@ jobs: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} windows-oldrel-4: if: ${{ ! cancelled() }} - needs: [precheck, config] + needs: [config, macos-oldrel-4] uses: ./.github/workflows/apps-test-os.yml with: r-version: ${{ needs.config.outputs.oldrel4 }} diff --git a/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R b/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R index c6083b02f1..058b24d50a 100644 --- a/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R +++ b/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R @@ -115,19 +115,6 @@ window.updatedOutputs = []; shared = app$get_js(js_element_width(sel_plot_img_shared)) ) - cat("\n----- Recording", sidebar, "sidebar on", page, "page transition -----") - cat_item <- function(which) { - value <- get(which) - cat("\n", which, ":") - cat("\n shared: ", paste(value[["shared"]], collapse = ", ")) - cat("\n local: ", paste(value[["local"]], collapse = ", ")) - } - cat_item("initial") - cat_item("during") - cat_item("final") - cat_item("outputs") - cat("\n----------------------------------------------\n\n") - # we only need unique observations between initial and final during$local <- unique(during$local) during$shared <- unique(during$shared) @@ -290,7 +277,6 @@ test_that("312-bslib-sidebar-resize", { # STATIC PAGE ================================================================ - withCallingHandlers({ # collapse static shared sidebar -------------------------------------------- expect_sidebar_transition(app, "shared", "static", open_end = "closed") @@ -333,13 +319,4 @@ test_that("312-bslib-sidebar-resize", { # expand widget shared sidebar ---------------------------------------------- expect_sidebar_transition(app, "shared", "client", open_end = "open") - }, error = function(err) { - cat("\n\n\n==== TEST FAILED ================================") - cat("\nError received: ", conditionMessage(err)) - cat("\nPrinting logs...") - print(app$get_logs()) - cat("\nsaving screenshot...") - app$expect_screenshot(selector = "viewport") - cat("\nscreenshot saved...") - }) }) From 6e42aea244b4347e3d93ac32df94bc1e353f41f8 Mon Sep 17 00:00:00 2001 From: Garrick Aden-Buie Date: Fri, 19 May 2023 10:37:48 -0400 Subject: [PATCH 15/26] Use `nav_panel()` --- inst/apps/312-bslib-sidebar-resize/app.R | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/inst/apps/312-bslib-sidebar-resize/app.R b/inst/apps/312-bslib-sidebar-resize/app.R index 6dbb6a49a0..980f4c66b0 100644 --- a/inst/apps/312-bslib-sidebar-resize/app.R +++ b/inst/apps/312-bslib-sidebar-resize/app.R @@ -27,7 +27,7 @@ ui <- page_navbar( open = "open", p("The plots should resize smoothly when this sidebar or the local sidebar are toggled.") ), - nav( + nav_panel( "Static", h2("Static plot resizing"), p( @@ -55,7 +55,7 @@ ui <- page_navbar( div(class = "col-6", lorem2, lorem1) ) ), - nav( + nav_panel( "Widget", h2("Widget plot resizing"), p( @@ -83,7 +83,7 @@ ui <- page_navbar( div(class = "col-6", lorem2, lorem1) ) ), - nav( + nav_panel( "Client", h2("Client-side htmlwidget resizing"), p( From 93831c83d335f12166ca610eb209643eea64ee6f Mon Sep 17 00:00:00 2001 From: Garrick Aden-Buie Date: Fri, 19 May 2023 10:38:13 -0400 Subject: [PATCH 16/26] Rename test file --- .../{test-shinytest2.R => test-312-bslib-sidebar-resize.R} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename inst/apps/312-bslib-sidebar-resize/tests/testthat/{test-shinytest2.R => test-312-bslib-sidebar-resize.R} (100%) diff --git a/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R b/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-312-bslib-sidebar-resize.R similarity index 100% rename from inst/apps/312-bslib-sidebar-resize/tests/testthat/test-shinytest2.R rename to inst/apps/312-bslib-sidebar-resize/tests/testthat/test-312-bslib-sidebar-resize.R From d0f224d598e0b2f23b577d04420ae83203040b1e Mon Sep 17 00:00:00 2001 From: Garrick Aden-Buie Date: Fri, 19 May 2023 10:46:13 -0400 Subject: [PATCH 17/26] Skip transition animation tests on windows --- .../testthat/test-312-bslib-sidebar-resize.R | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-312-bslib-sidebar-resize.R b/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-312-bslib-sidebar-resize.R index 058b24d50a..5b2a12120b 100644 --- a/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-312-bslib-sidebar-resize.R +++ b/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-312-bslib-sidebar-resize.R @@ -167,6 +167,21 @@ expect_sidebar_transition <- function( closed = expect_sidebar_hidden(sidebar_id) ) + # test plot output size changes during the transition + if (shinycoreci::platform() != "win") { + # NOTE: transition isn't animated on Windows in CI, test manually + expect_sidebar_changes_during_transition(res, open_end, will_transition) + } + + if (page == "static") { + # plots update at the end of the transition + expected_updates <- paste0("plot_static_", will_transition) + expect_setequal(res$outputs, !!expected_updates) + } +} + +expect_sidebar_changes_during_transition <- function(res, open_end, will_transition) { + # Plot output size changes during the transition if ("local" %in% will_transition) { expect_gt( @@ -255,12 +270,6 @@ expect_sidebar_transition <- function( label = "shared plot output size did not change during transition" ) } - - if (page == "static") { - # plots update at the end of the transition - expected_updates <- paste0("plot_static_", will_transition) - expect_setequal(res$outputs, !!expected_updates) - } } # 312-bslib-sidebar-resize ---------------------------------------------------- From eb49d670451cfe572e7eaefd892ce0c1f58a2a81 Mon Sep 17 00:00:00 2001 From: Garrick Aden-Buie Date: Fri, 19 May 2023 10:58:40 -0400 Subject: [PATCH 18/26] Split out helper code, split tests into blocks --- inst/apps/312-bslib-sidebar-resize/app.R | 4 + .../tests/testthat/helpers-js.R | 25 ++ .../testthat/helpers-sidebar-animation.R | 228 +++++++++++++ .../tests/testthat/helpers-sidebar-state.R | 17 + .../testthat/test-312-bslib-sidebar-resize.R | 316 ++---------------- 5 files changed, 300 insertions(+), 290 deletions(-) create mode 100644 inst/apps/312-bslib-sidebar-resize/tests/testthat/helpers-js.R create mode 100644 inst/apps/312-bslib-sidebar-resize/tests/testthat/helpers-sidebar-animation.R create mode 100644 inst/apps/312-bslib-sidebar-resize/tests/testthat/helpers-sidebar-state.R diff --git a/inst/apps/312-bslib-sidebar-resize/app.R b/inst/apps/312-bslib-sidebar-resize/app.R index 980f4c66b0..9873addb26 100644 --- a/inst/apps/312-bslib-sidebar-resize/app.R +++ b/inst/apps/312-bslib-sidebar-resize/app.R @@ -118,6 +118,10 @@ ui <- page_navbar( ) server <- function(input, output, session) { + observeEvent(input$open_sidebar_shared, { + sidebar_toggle("sidebar-shared", open = "open") + }) + plot <- reactive({ ggplot(mtcars, aes(mpg, wt)) + geom_point(aes(color = factor(cyl))) + diff --git a/inst/apps/312-bslib-sidebar-resize/tests/testthat/helpers-js.R b/inst/apps/312-bslib-sidebar-resize/tests/testthat/helpers-js.R new file mode 100644 index 0000000000..2b7ee89336 --- /dev/null +++ b/inst/apps/312-bslib-sidebar-resize/tests/testthat/helpers-js.R @@ -0,0 +1,25 @@ +js_sidebar_transition_complete <- function(id) { + sprintf( + "!document.getElementById('%s').parentElement.classList.contains('transitioning');", + id + ) +} + +js_sidebar_state <- function(id) { + sprintf( + "(function() { + return { + layout_classes: Array.from(document.getElementById('%s').closest('.bslib-sidebar-layout').classList), + content_display: window.getComputedStyle(document.querySelector('#%s .sidebar-content')).getPropertyValue('display'), + sidebar_hidden: document.getElementById('%s').hidden + }})();", + id, id, id + ) +} + +js_element_width <- function(selector) { + sprintf( + "document.querySelector('%s').getBoundingClientRect().width;", + selector + ) +} diff --git a/inst/apps/312-bslib-sidebar-resize/tests/testthat/helpers-sidebar-animation.R b/inst/apps/312-bslib-sidebar-resize/tests/testthat/helpers-sidebar-animation.R new file mode 100644 index 0000000000..6c0afd6e04 --- /dev/null +++ b/inst/apps/312-bslib-sidebar-resize/tests/testthat/helpers-sidebar-animation.R @@ -0,0 +1,228 @@ + +# Gather width measurements of plots during the sidebar transition +# +# 1. Measures the `initial` width of plots prior to transition +# 2. Clicks the sidebar toggle +# 3. Samples width of plots `during` transition +# 4. Waits for transition to complete +# 5. Measures the `final` width of plots after transition +# 6. Captures updated shiny `outputs` during the measurement period +watch_sidebar_transition <- function( + app, + sidebar = c("shared", "local"), + page = c("static", "widget", "client") +) { + sidebar <- match.arg(sidebar) + page <- match.arg(page) + + id_sidebar <- switch( + sidebar, + shared = "sidebar-shared", + paste0("sidebar-local-", page) + ) + + sel_plot <- function(which = c("shared", "local" , "client")) { + plot_container <- switch( + page, + static = "img", + widget = ".plot-container > .svg-container", + client = ".plotly > .plot-container > .svg-container" + ) + paste0("#plot_", page, "_", which, " > ", plot_container) + } + sel_plot_img_local <- sel_plot("local") + sel_plot_img_shared <- sel_plot("shared") + + initial <- list( + local = app$get_js(js_element_width(sel_plot_img_local)), + shared = app$get_js(js_element_width(sel_plot_img_shared)) + ) + + during <- list(local = c(), shared = c()) + + app$run_js(" +if (!window.updatedOutputs) { + $(document).on('shiny:value', function(event) { + window.updatedOutputs.push(event.target.id); + }) +} +window.updatedOutputs = []; +") + app$click(selector = sprintf("#%s + .collapse-toggle", id_sidebar)) + + while (!app$get_js(js_sidebar_transition_complete(id_sidebar))) { + Sys.sleep(0.1) + during$local <- c(during$local, app$get_js(js_element_width(sel_plot_img_local))) + during$shared <- c(during$shared, app$get_js(js_element_width(sel_plot_img_shared))) + } + + if (page == "static") { + app$wait_for_js("window.updatedOutputs.length > 0") + Sys.sleep(0.25) + } else { + # widget plots don't trigger shiny:value events, so we just have to wait + Sys.sleep(1) + } + + outputs <- app$get_js("window.updatedOutputs") + final <- list( + local = app$get_js(js_element_width(sel_plot_img_local)), + shared = app$get_js(js_element_width(sel_plot_img_shared)) + ) + + # we only need unique observations between initial and final + during$local <- unique(during$local) + during$shared <- unique(during$shared) + + list( + initial = initial, + during = during, + final = final, + outputs = unlist(outputs) + ) +} + +expect_sidebar_transition <- function( + app, + sidebar = c("shared", "local"), + page = c("static", "widget", "client"), + open_end = c("open", "closed") +) { + sidebar <- match.arg(sidebar) + page <- match.arg(page) + open_end <- match.arg(open_end) + + expect_sidebar_shown <- expect_sidebar_shown_factory(app) + expect_sidebar_hidden <- expect_sidebar_hidden_factory(app) + + sidebar_id <- + if (sidebar == "shared") { + "sidebar-shared" + } else { + paste0("sidebar-local-", page) + } + + will_transition <- c("local", if (sidebar == "shared") "shared") + change_dir <- if (open_end == "open") "expand" else "collapse" + + # test sidebar state before transition + switch( + open_end, + open = expect_sidebar_hidden(sidebar_id), + closed = expect_sidebar_shown(sidebar_id) + ) + + # toggle the sidebar and measure the transition + res <- watch_sidebar_transition(app, sidebar = sidebar, page = page) + + # test sidebar state after transition + switch( + open_end, + open = expect_sidebar_shown(sidebar_id), + closed = expect_sidebar_hidden(sidebar_id) + ) + + # test plot output size changes during the transition + if (shinycoreci::platform() != "win") { + # NOTE: transition isn't animated on Windows in CI, test manually + expect_sidebar_changes_during_transition(res, open_end, will_transition) + } + + if (page == "static") { + # plots update at the end of the transition + expected_updates <- paste0("plot_static_", will_transition) + expect_setequal(res$outputs, !!expected_updates) + } +} + +expect_sidebar_changes_during_transition <- function(res, open_end, will_transition) { + + # Plot output size changes during the transition + if ("local" %in% will_transition) { + expect_gt( + length(res$during$local), + expected = 1, + label = "local plot output size changes during transition" + ) + } + + if ("shared" %in% will_transition) { + expect_gt( + length(res$during$shared), + expected = 1, + label = "shared plot output size changes during transition" + ) + } + + expect_plot_grows <- function(plot = c("local", "shared")) { + plot <- match.arg(plot) + + + # initial size is a lower bound, plots grow as sidebar collapses + expect_gt( + min(res$during[[plot]]), + res$initial[[!!plot]], + label = sprintf("minimum %s plot output size during transition", plot) + ) + has_size_changes <- expect_true( + length(res$during[[plot]]) > 1, + label = sprintf("has %s plot output size changes during transition", plot) + ) + if (has_size_changes) { + expect_true( + all(diff(res$during[[plot]]) > 0), + label = sprintf("%s plot output size was growing during transition", plot) + ) + } + } + + expect_plot_shrinks <- function(plot = c("local", "shared")) { + plot <- match.arg(plot) + + # initial size is the upper bound, plots shrink as sidebar expands + expect_lt( + max(res$during[[plot]]), + res$initial[[!!plot]], + label = sprintf("maximum %s plot output size during transition", plot) + ) + has_size_changes <- expect_true( + length(res$during[[plot]]) > 1, + label = sprintf("has %s plot output size changes during transition", plot) + ) + if (has_size_changes) { + expect_true( + all(diff(res$during[[plot]]) < 0), + label = sprintf("%s plot output size was growing during transition", plot) + ) + } + } + + # plot output image size was growing/shrinking during transition + if ("local" %in% will_transition) { + switch( + open_end, + open = expect_plot_shrinks("local"), + closed = expect_plot_grows("local") + ) + } else { + expect_equal( + res$during$local, + res$initial$local, + label = "local plot output size did not change during transition" + ) + } + + if ("shared" %in% will_transition) { + switch( + open_end, + open = expect_plot_shrinks("shared"), + closed = expect_plot_grows("shared") + ) + } else { + expect_equal( + res$during$shared, + res$initial$shared, + label = "shared plot output size did not change during transition" + ) + } +} diff --git a/inst/apps/312-bslib-sidebar-resize/tests/testthat/helpers-sidebar-state.R b/inst/apps/312-bslib-sidebar-resize/tests/testthat/helpers-sidebar-state.R new file mode 100644 index 0000000000..c67028850a --- /dev/null +++ b/inst/apps/312-bslib-sidebar-resize/tests/testthat/helpers-sidebar-state.R @@ -0,0 +1,17 @@ +expect_sidebar_hidden_factory <- function(app) { + function(id) { + state <- app$get_js(js_sidebar_state(id = id)) + expect_true("sidebar-collapsed" %in% state$layout_classes) + expect_equal(state$content_display, "none") + expect_true(state$sidebar_hidden) + } +} + +expect_sidebar_shown_factory <- function(app) { + function(id) { + state <- app$get_js(js_sidebar_state(id = id)) + expect_false("sidebar-collapsed" %in% state$layout_classes) + expect_false(identical(state$content_display, "none")) + expect_false(state$sidebar_hidden) + } +} diff --git a/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-312-bslib-sidebar-resize.R b/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-312-bslib-sidebar-resize.R index 5b2a12120b..55b9921555 100644 --- a/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-312-bslib-sidebar-resize.R +++ b/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-312-bslib-sidebar-resize.R @@ -1,291 +1,19 @@ library(shinytest2) -expect_sidebar_hidden_factory <- function(app) { - function(id) { - state <- app$get_js(js_sidebar_state(id = id)) - expect_true("sidebar-collapsed" %in% state$layout_classes) - expect_equal(state$content_display, "none") - expect_true(state$sidebar_hidden) - } -} - -expect_sidebar_shown_factory <- function(app) { - function(id) { - state <- app$get_js(js_sidebar_state(id = id)) - expect_false("sidebar-collapsed" %in% state$layout_classes) - expect_false(identical(state$content_display, "none")) - expect_false(state$sidebar_hidden) - } -} - -js_sidebar_transition_complete <- function(id) { - sprintf( - "!document.getElementById('%s').parentElement.classList.contains('transitioning');", - id - ) -} - -js_sidebar_state <- function(id) { - sprintf( - "(function() { - return { - layout_classes: Array.from(document.getElementById('%s').closest('.bslib-sidebar-layout').classList), - content_display: window.getComputedStyle(document.querySelector('#%s .sidebar-content')).getPropertyValue('display'), - sidebar_hidden: document.getElementById('%s').hidden - }})();", - id, id, id - ) -} - -js_element_width <- function(selector) { - sprintf( - "document.querySelector('%s').getBoundingClientRect().width;", - selector - ) -} - -# Gather width measurements of plots during the sidebar transition -# -# 1. Measures the `initial` width of plots prior to transition -# 2. Clicks the sidebar toggle -# 3. Samples width of plots `during` transition -# 4. Waits for transition to complete -# 5. Measures the `final` width of plots after transition -# 6. Captures updated shiny `outputs` during the measurement period -watch_sidebar_transition <- function( - app, - sidebar = c("shared", "local"), - page = c("static", "widget", "client") -) { - sidebar <- match.arg(sidebar) - page <- match.arg(page) - - id_sidebar <- switch( - sidebar, - shared = "sidebar-shared", - paste0("sidebar-local-", page) - ) - - sel_plot <- function(which = c("shared", "local" , "client")) { - plot_container <- switch( - page, - static = "img", - widget = ".plot-container > .svg-container", - client = ".plotly > .plot-container > .svg-container" - ) - paste0("#plot_", page, "_", which, " > ", plot_container) - } - sel_plot_img_local <- sel_plot("local") - sel_plot_img_shared <- sel_plot("shared") - - initial <- list( - local = app$get_js(js_element_width(sel_plot_img_local)), - shared = app$get_js(js_element_width(sel_plot_img_shared)) - ) - - during <- list(local = c(), shared = c()) - - app$run_js(" -if (!window.updatedOutputs) { - $(document).on('shiny:value', function(event) { - window.updatedOutputs.push(event.target.id); - }) -} -window.updatedOutputs = []; -") - app$click(selector = sprintf("#%s + .collapse-toggle", id_sidebar)) - - while (!app$get_js(js_sidebar_transition_complete(id_sidebar))) { - Sys.sleep(0.1) - during$local <- c(during$local, app$get_js(js_element_width(sel_plot_img_local))) - during$shared <- c(during$shared, app$get_js(js_element_width(sel_plot_img_shared))) - } - - if (page == "static") { - app$wait_for_js("window.updatedOutputs.length > 0") - Sys.sleep(0.25) - } else { - # widget plots don't trigger shiny:value events, so we just have to wait - Sys.sleep(1) - } - - outputs <- app$get_js("window.updatedOutputs") - final <- list( - local = app$get_js(js_element_width(sel_plot_img_local)), - shared = app$get_js(js_element_width(sel_plot_img_shared)) - ) - - # we only need unique observations between initial and final - during$local <- unique(during$local) - during$shared <- unique(during$shared) - - list( - initial = initial, - during = during, - final = final, - outputs = unlist(outputs) - ) -} - -expect_sidebar_transition <- function( - app, - sidebar = c("shared", "local"), - page = c("static", "widget", "client"), - open_end = c("open", "closed") -) { - sidebar <- match.arg(sidebar) - page <- match.arg(page) - open_end <- match.arg(open_end) - - expect_sidebar_shown <- expect_sidebar_shown_factory(app) - expect_sidebar_hidden <- expect_sidebar_hidden_factory(app) - - sidebar_id <- - if (sidebar == "shared") { - "sidebar-shared" - } else { - paste0("sidebar-local-", page) - } - - will_transition <- c("local", if (sidebar == "shared") "shared") - change_dir <- if (open_end == "open") "expand" else "collapse" - - # test sidebar state before transition - switch( - open_end, - open = expect_sidebar_hidden(sidebar_id), - closed = expect_sidebar_shown(sidebar_id) - ) - - # toggle the sidebar and measure the transition - res <- watch_sidebar_transition(app, sidebar = sidebar, page = page) - - # test sidebar state after transition - switch( - open_end, - open = expect_sidebar_shown(sidebar_id), - closed = expect_sidebar_hidden(sidebar_id) - ) - - # test plot output size changes during the transition - if (shinycoreci::platform() != "win") { - # NOTE: transition isn't animated on Windows in CI, test manually - expect_sidebar_changes_during_transition(res, open_end, will_transition) - } - - if (page == "static") { - # plots update at the end of the transition - expected_updates <- paste0("plot_static_", will_transition) - expect_setequal(res$outputs, !!expected_updates) - } -} - -expect_sidebar_changes_during_transition <- function(res, open_end, will_transition) { - - # Plot output size changes during the transition - if ("local" %in% will_transition) { - expect_gt( - length(res$during$local), - expected = 1, - label = "local plot output size changes during transition" - ) - } - - if ("shared" %in% will_transition) { - expect_gt( - length(res$during$shared), - expected = 1, - label = "shared plot output size changes during transition" - ) - } - - expect_plot_grows <- function(plot = c("local", "shared")) { - plot <- match.arg(plot) - - - # initial size is a lower bound, plots grow as sidebar collapses - expect_gt( - min(res$during[[plot]]), - res$initial[[!!plot]], - label = sprintf("minimum %s plot output size during transition", plot) - ) - has_size_changes <- expect_true( - length(res$during[[plot]]) > 1, - label = sprintf("has %s plot output size changes during transition", plot) - ) - if (has_size_changes) { - expect_true( - all(diff(res$during[[plot]]) > 0), - label = sprintf("%s plot output size was growing during transition", plot) - ) - } - } - - expect_plot_shrinks <- function(plot = c("local", "shared")) { - plot <- match.arg(plot) - - # initial size is the upper bound, plots shrink as sidebar expands - expect_lt( - max(res$during[[plot]]), - res$initial[[!!plot]], - label = sprintf("maximum %s plot output size during transition", plot) - ) - has_size_changes <- expect_true( - length(res$during[[plot]]) > 1, - label = sprintf("has %s plot output size changes during transition", plot) - ) - if (has_size_changes) { - expect_true( - all(diff(res$during[[plot]]) < 0), - label = sprintf("%s plot output size was growing during transition", plot) - ) - } - } - - # plot output image size was growing/shrinking during transition - if ("local" %in% will_transition) { - switch( - open_end, - open = expect_plot_shrinks("local"), - closed = expect_plot_grows("local") - ) - } else { - expect_equal( - res$during$local, - res$initial$local, - label = "local plot output size did not change during transition" - ) - } - - if ("shared" %in% will_transition) { - switch( - open_end, - open = expect_plot_shrinks("shared"), - closed = expect_plot_grows("shared") - ) - } else { - expect_equal( - res$during$shared, - res$initial$shared, - label = "shared plot output size did not change during transition" - ) - } -} - -# 312-bslib-sidebar-resize ---------------------------------------------------- -test_that("312-bslib-sidebar-resize", { - app <- AppDriver$new( - name = "312-bslib-sidebar-resize", - variant = platform_variant(), - height = 1600, - width = 1200, - view = interactive(), - options = list(bslib.precompiled = FALSE), - expect_values_screenshot_args = FALSE - ) - - # STATIC PAGE ================================================================ - +app <- AppDriver$new( + name = "312-bslib-sidebar-resize", + variant = platform_variant(), + height = 1600, + width = 1200, + view = interactive(), + options = list(bslib.precompiled = FALSE), + expect_values_screenshot_args = FALSE +) + +withr::defer(app$stop()) + +# STATIC PAGE ================================================================ +test_that("Resizing sidebars on page with ggplot2 plots", { # collapse static shared sidebar -------------------------------------------- expect_sidebar_transition(app, "shared", "static", open_end = "closed") @@ -294,11 +22,15 @@ test_that("312-bslib-sidebar-resize", { # expand static shared sidebar ---------------------------------------------- expect_sidebar_transition(app, "shared", "static", open_end = "open") +}) - # SWITCH TO WIDGET PAGE ====================================================== +# SWITCH TO WIDGET PAGE ====================================================== +test_that("Resizing sidebars on page with shiny-backed htmlwidgets", { app$ click(selector = '.nav-link[data-value="Widget"]')$ - wait_for_js("$('#plot_widget_local:visible .svg-container').length > 0") + wait_for_js("$('#plot_widget_local:visible .svg-container').length > 0")$ + run_js("Shiny.setInputValue('open_sidebar_shared', Date.now())")$ + wait_for_js(js_sidebar_transition_complete("sidebar-shared")) # now we repeat all of the same tests above, except that the widget resizing # won't trigger a 'shiny:value' event. @@ -311,11 +43,15 @@ test_that("312-bslib-sidebar-resize", { # expand widget shared sidebar ---------------------------------------------- expect_sidebar_transition(app, "shared", "widget", open_end = "open") +}) - # SWITCH TO CLIENT PAGE ====================================================== +# SWITCH TO CLIENT PAGE ====================================================== +test_that("Resizing sidebars on page with static htmlwidgets", { app$ click(selector = '.nav-link[data-value="Client"]')$ - wait_for_js("$('#plot_client_local:visible .svg-container').length > 0") + wait_for_js("$('#plot_client_local:visible .svg-container').length > 0")$ + run_js("Shiny.setInputValue('open_sidebar_shared', Date.now())")$ + wait_for_js(js_sidebar_transition_complete("sidebar-shared")) # now we repeat all of the same tests above, except that the widget resizing # won't trigger a 'shiny:value' event. From 09ecf09e402e56403dff6c65b6704fea921b538b Mon Sep 17 00:00:00 2001 From: Garrick Aden-Buie Date: Fri, 19 May 2023 11:04:46 -0400 Subject: [PATCH 19/26] Add README for 312 --- inst/apps/312-bslib-sidebar-resize/README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 inst/apps/312-bslib-sidebar-resize/README.md diff --git a/inst/apps/312-bslib-sidebar-resize/README.md b/inst/apps/312-bslib-sidebar-resize/README.md new file mode 100644 index 0000000000..87913675bc --- /dev/null +++ b/inst/apps/312-bslib-sidebar-resize/README.md @@ -0,0 +1,15 @@ +# 312-bslib-sidebar-resize + +## Description + +`312-bslib-sidebar-resize` tests that outputs and htmlwidgets inside the main content area of sidebar layouts animate through the sidebar resizing transition. The test app includes three pages: + +1. A layout with two ggplot2 plots created via `plotOutput()`. During the sidebar resizing transition, the plots should stretch. This causes some visible distortion of the image. When the transition is complete, the server updates the plot at the new resolution and the image should "snap" into place. + +2. A layout with two plotly plots created via `plotlyOutput()`. During the sidebar resizing transition, the plots should grow or shrink smoothly to match the available space in the content area of the layout. + +3. A layout with two htmlwidgets created via `plot_ly()`. During the sidebar resizing transition, the widgets should grow or shrink smoothly to match the available space in the content area of the layout. + +## Notes + +The animation is not smooth on Windows, at least on CI. The test suite currently skips testing around the plot animation on Windows, but does test the sidebar state. Manual testing on Windows should confirm that the animation is smooth. From 38fa35c432ab6f2afbc5b799058433188954820a Mon Sep 17 00:00:00 2001 From: Garrick Aden-Buie Date: Fri, 19 May 2023 11:08:02 -0400 Subject: [PATCH 20/26] skip on windows without help from {shinycoreci} --- .../tests/testthat/helpers-sidebar-animation.R | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/inst/apps/312-bslib-sidebar-resize/tests/testthat/helpers-sidebar-animation.R b/inst/apps/312-bslib-sidebar-resize/tests/testthat/helpers-sidebar-animation.R index 6c0afd6e04..b4d6ef0dca 100644 --- a/inst/apps/312-bslib-sidebar-resize/tests/testthat/helpers-sidebar-animation.R +++ b/inst/apps/312-bslib-sidebar-resize/tests/testthat/helpers-sidebar-animation.R @@ -122,9 +122,13 @@ expect_sidebar_transition <- function( closed = expect_sidebar_hidden(sidebar_id) ) + # NOTE: transition isn't animated on Windows in CI, test manually + is_windows_on_ci <- + identical(.Platform$OS.type, "windows") && + identical(Sys.getenv("CI"), "true") + # test plot output size changes during the transition - if (shinycoreci::platform() != "win") { - # NOTE: transition isn't animated on Windows in CI, test manually + if (!is_windows_on_ci) { expect_sidebar_changes_during_transition(res, open_end, will_transition) } From 610e93c6140e14f2bd39c868b5147eb6cb2f197d Mon Sep 17 00:00:00 2001 From: gadenbuie Date: Sat, 20 May 2023 13:37:46 +0000 Subject: [PATCH 21/26] Generate apps deps (GitHub Actions) --- R/data-apps-deps.R | 113 +++++++++++++++++++++++---------------------- 1 file changed, 57 insertions(+), 56 deletions(-) diff --git a/R/data-apps-deps.R b/R/data-apps-deps.R index 3aa4779ce8..c7a7d68690 100644 --- a/R/data-apps-deps.R +++ b/R/data-apps-deps.R @@ -1,64 +1,65 @@ # Do not edit by hand! # This file is automatically generated by `./inst/gha/data-apps-deps-update.R` -apps_deps <- c("base64enc", "BH", "Cairo", "clipr", "curl", "DBI", "dbplyr", -"DiagrammeR", "dplyr", "evaluate", "future", "ggplot2", "ggvis", -"hexbin", "highcharter", "jsonlite", "knitr", "magrittr", "maps", -"markdown", "memoise", "networkD3", "plogr", "png", "progress", -"pryr", "radiant", "ragg", "RColorBrewer", "reactable", "reactR", -"reshape2", "rlang", "rmarkdown", "rprojroot", "rsconnect", "RSQLite", -"rversions", "scales", "sf", "shinyAce", "shinydashboard", "shinyjs", -"showtext", "sysfonts", "systemfonts", "testthat", "tidyr", "tm", +apps_deps <- c("base64enc", "BH", "Cairo", "clipr", "curl", "DBI", "dbplyr", +"DiagrammeR", "dplyr", "evaluate", "future", "ggplot2", "ggvis", +"hexbin", "highcharter", "jsonlite", "knitr", "magrittr", "maps", +"markdown", "memoise", "networkD3", "plogr", "png", "progress", +"pryr", "radiant", "ragg", "RColorBrewer", "reactable", "reactR", +"reshape2", "rlang", "rmarkdown", "rprojroot", "rsconnect", "RSQLite", +"rversions", "scales", "sf", "shinyAce", "shinydashboard", "shinyjs", +"showtext", "sysfonts", "systemfonts", "testthat", "tidyr", "tm", "waldo", "withr", "wordcloud") -apps_deps_map <- list(`001-hello` = "rsconnect", `012-datatables` = "ggplot2", - `016-knitr-pdf` = "rmarkdown", `020-knit-html` = c("evaluate", - "knitr", "rmarkdown"), `021-selectize-plot` = "maps", `022-unicode-chinese` = c("curl", - "showtext", "sysfonts"), `026-shiny-inline` = "rmarkdown", - `027-absolutely-positioned-panels` = "markdown", `047-image-output` = "png", - `048-including-html-text-and-markdown-files` = "markdown", - `051-movie-explorer` = c("DBI", "dbplyr", "dplyr", "ggvis", - "plogr", "RSQLite"), `063-superzip-example` = c("dplyr", - "RColorBrewer", "scales"), `082-word-cloud` = c("BH", "memoise", - "tm", "wordcloud"), `093-plot-interaction-basic` = "ggplot2", - `094-image-interaction-basic` = "png", `095-plot-interaction-advanced` = c("ggplot2", - "scales"), `099-plot-interaction-article-4` = "ggplot2", - `101-plot-interaction-article-6` = "ggplot2", `102-plot-interaction-article-7` = "ggplot2", - `103-plot-interaction-article-8` = "ggplot2", `104-plot-interaction-select` = "ggplot2", - `105-plot-interaction-zoom` = "ggplot2", `106-plot-interaction-exclude` = "ggplot2", - `108-module-output` = c("dplyr", "ggplot2"), `112-generate-report` = "rmarkdown", +apps_deps_map <- list(`001-hello` = "rsconnect", `012-datatables` = "ggplot2", + `016-knitr-pdf` = "rmarkdown", `020-knit-html` = c("evaluate", + "knitr", "rmarkdown"), `021-selectize-plot` = "maps", `022-unicode-chinese` = c("curl", + "showtext", "sysfonts"), `026-shiny-inline` = "rmarkdown", + `027-absolutely-positioned-panels` = "markdown", `047-image-output` = "png", + `048-including-html-text-and-markdown-files` = "markdown", + `051-movie-explorer` = c("DBI", "dbplyr", "dplyr", "ggvis", + "plogr", "RSQLite"), `063-superzip-example` = c("dplyr", + "RColorBrewer", "scales"), `082-word-cloud` = c("BH", "memoise", + "tm", "wordcloud"), `093-plot-interaction-basic` = "ggplot2", + `094-image-interaction-basic` = "png", `095-plot-interaction-advanced` = c("ggplot2", + "scales"), `099-plot-interaction-article-4` = "ggplot2", + `101-plot-interaction-article-6` = "ggplot2", `102-plot-interaction-article-7` = "ggplot2", + `103-plot-interaction-article-8` = "ggplot2", `104-plot-interaction-select` = "ggplot2", + `105-plot-interaction-zoom` = "ggplot2", `106-plot-interaction-exclude` = "ggplot2", + `108-module-output` = c("dplyr", "ggplot2"), `112-generate-report` = "rmarkdown", `118-highcharter-births` = c("dplyr", "highcharter", "tidyr" - ), `121-async-timer` = c("future", "magrittr"), `122-async-outputs` = "future", - `123-async-renderprint` = "future", `124-async-download` = "future", - `125-async-req` = "future", `126-async-ticks` = "future", - `129-async-perf` = c("future", "ggplot2"), `140-selectize-inputs` = "jsonlite", - `141-radiant` = "radiant", `143-async-plot-caching` = "ggplot2", - `147-websocket` = "shinyjs", `150-networkD3-sankey` = c("networkD3", - "shinydashboard"), `151-reactr-input` = "reactR", `153-connection-header` = c("curl", - "future"), `156-subapps` = "rmarkdown", `161-discrete-limits` = c("dplyr", - "ggplot2"), `168-supporting-r-dir` = "withr", `169-prerender` = "rmarkdown", - `173-invalidatelater-leak` = "pryr", `174-throttle-debounce` = "magrittr", - `181-report-image` = c("Cairo", "jsonlite", "ragg", "showtext", - "sysfonts", "systemfonts"), `182-report-png` = c("Cairo", + ), `121-async-timer` = c("future", "magrittr"), `122-async-outputs` = "future", + `123-async-renderprint` = "future", `124-async-download` = "future", + `125-async-req` = "future", `126-async-ticks` = "future", + `129-async-perf` = c("future", "ggplot2"), `140-selectize-inputs` = "jsonlite", + `141-radiant` = "radiant", `143-async-plot-caching` = "ggplot2", + `147-websocket` = "shinyjs", `150-networkD3-sankey` = c("networkD3", + "shinydashboard"), `151-reactr-input` = "reactR", `153-connection-header` = c("curl", + "future"), `156-subapps` = "rmarkdown", `161-discrete-limits` = c("dplyr", + "ggplot2"), `168-supporting-r-dir` = "withr", `169-prerender` = "rmarkdown", + `173-invalidatelater-leak` = "pryr", `174-throttle-debounce` = "magrittr", + `181-report-image` = c("Cairo", "jsonlite", "ragg", "showtext", + "sysfonts", "systemfonts"), `182-report-png` = c("Cairo", "jsonlite", "ragg", "showtext", "sysfonts", "systemfonts" - ), `183-report-cairo` = c("Cairo", "jsonlite", "ragg", "showtext", - "sysfonts", "systemfonts"), `184-report-ragg` = c("Cairo", + ), `183-report-cairo` = c("Cairo", "jsonlite", "ragg", "showtext", + "sysfonts", "systemfonts"), `184-report-ragg` = c("Cairo", "jsonlite", "ragg", "showtext", "sysfonts", "systemfonts" - ), `185-report-theme` = c("Cairo", "jsonlite", "knitr", "ragg", - "rmarkdown", "waldo"), `193-reactlog-dynamic-ui` = "rversions", - `200-flexdashboard-render-text` = c("knitr", "rmarkdown"), - `205-dynamic-tabs-compat` = "withr", `206-freeze-thaw` = "rlang", - `208-bind-cache-event` = "magrittr", `209-datepicker` = c("jsonlite", - "magrittr", "rlang"), `210-future_promise` = c("future", - "magrittr", "shinyjs"), `211-sv-custom-inputs` = "base64enc", - `212-daterangepicker` = "jsonlite", `216-quosures` = c("DiagrammeR", - "rlang"), `221-async-script-dynamic-ui` = "rlang", `224-shinymeta` = c("clipr", - "dplyr", "shinyAce"), `225-snapshot-info-option` = c("jsonlite", + ), `185-report-theme` = c("Cairo", "jsonlite", "knitr", "ragg", + "rmarkdown", "waldo"), `193-reactlog-dynamic-ui` = "rversions", + `200-flexdashboard-render-text` = c("knitr", "rmarkdown"), + `205-dynamic-tabs-compat` = "withr", `206-freeze-thaw` = "rlang", + `208-bind-cache-event` = "magrittr", `209-datepicker` = c("jsonlite", + "magrittr", "rlang"), `210-future_promise` = c("future", + "magrittr", "shinyjs"), `211-sv-custom-inputs` = "base64enc", + `212-daterangepicker` = "jsonlite", `216-quosures` = c("DiagrammeR", + "rlang"), `221-async-script-dynamic-ui` = "rlang", `224-shinymeta` = c("clipr", + "dplyr", "shinyAce"), `225-snapshot-info-option` = c("jsonlite", "testthat"), `226-snapshot-info-url` = c("jsonlite", "testthat" - ), `300-bs-themer` = c("curl", "ggplot2", "hexbin", "knitr", - "reactable", "rlang", "rprojroot", "rsconnect"), `301-bs-themes` = c("ggplot2", - "reshape2", "rversions", "sf", "withr"), `302-bootswatch-themes` = c("ggplot2", - "progress", "rversions", "sf", "withr"), `304-bslib-card` = c("rlang", + ), `300-bs-themer` = c("curl", "ggplot2", "hexbin", "knitr", + "reactable", "rlang", "rprojroot", "rsconnect"), `301-bs-themes` = c("ggplot2", + "reshape2", "rversions", "sf", "withr"), `302-bootswatch-themes` = c("ggplot2", + "progress", "rversions", "sf", "withr"), `304-bslib-card` = c("rlang", "rversions"), `305-bslib-value-box` = c("rlang", "rversions" - ), `309-flexdashboard-tabs-navs` = "rmarkdown", `310-bslib-sidebar-dynamic` = c("rversions", - "testthat"), `311-bslib-sidebar-toggle-methods` = c("rversions", - "testthat"), `312-bslib-sidebar-resize` = "ggplot2", `313-bslib-card-tab-focus` = c("rversions", - "testthat", "withr")) + ), `309-flexdashboard-tabs-navs` = "rmarkdown", `310-bslib-sidebar-dynamic` = c("rversions", + "testthat"), `311-bslib-sidebar-toggle-methods` = c("rversions", + "testthat"), `312-bslib-sidebar-resize` = c("ggplot2", "withr" + ), `313-bslib-card-tab-focus` = c("rversions", "testthat", + "withr")) From c11a49446200072e2c640004659008a9bbf70e8a Mon Sep 17 00:00:00 2001 From: Garrick Aden-Buie Date: Sat, 20 May 2023 10:29:11 -0400 Subject: [PATCH 22/26] test again after routine file changes From 52612da552ec3f962a6d39bc1b60296f7a342100 Mon Sep 17 00:00:00 2001 From: Garrick Aden-Buie Date: Mon, 22 May 2023 10:30:58 -0400 Subject: [PATCH 23/26] bring back some debugging output --- .../tests/testthat/helpers-sidebar-animation.R | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/inst/apps/312-bslib-sidebar-resize/tests/testthat/helpers-sidebar-animation.R b/inst/apps/312-bslib-sidebar-resize/tests/testthat/helpers-sidebar-animation.R index b4d6ef0dca..3b8b3efd4b 100644 --- a/inst/apps/312-bslib-sidebar-resize/tests/testthat/helpers-sidebar-animation.R +++ b/inst/apps/312-bslib-sidebar-resize/tests/testthat/helpers-sidebar-animation.R @@ -70,6 +70,20 @@ window.updatedOutputs = []; shared = app$get_js(js_element_width(sel_plot_img_shared)) ) + cat("\n----- Recording", sidebar, "sidebar on", page, "page transition -----") + cat_item <- function(which) { + value <- get(which) + cat("\n", which, ":", sep = "\n") + cat("\n shared:", paste(value[["shared"]], collapse = ", ")) + cat("\n local: ", paste(value[["local"]], collapse = ", ")) + } + cat_item("initial") + cat_item("during") + cat_item("final") + cat_item("outputs") + cat("\n-----------------------------------------------------------------\n\n") + + # we only need unique observations between initial and final during$local <- unique(during$local) during$shared <- unique(during$shared) From bee1c5750e82ed6226a9442f969b120712011858 Mon Sep 17 00:00:00 2001 From: Garrick Aden-Buie Date: Mon, 22 May 2023 10:32:05 -0400 Subject: [PATCH 24/26] slow down transition to see if that helps --- .../tests/testthat/test-312-bslib-sidebar-resize.R | 2 ++ 1 file changed, 2 insertions(+) diff --git a/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-312-bslib-sidebar-resize.R b/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-312-bslib-sidebar-resize.R index 55b9921555..86bcab27d5 100644 --- a/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-312-bslib-sidebar-resize.R +++ b/inst/apps/312-bslib-sidebar-resize/tests/testthat/test-312-bslib-sidebar-resize.R @@ -1,5 +1,7 @@ library(shinytest2) +withr::local_envvar(list(SIDEBAR_TRANSITION_TIME = "1s")) + app <- AppDriver$new( name = "312-bslib-sidebar-resize", variant = platform_variant(), From 452178bbdf57fec2857e307cbaf3ad6783a06f29 Mon Sep 17 00:00:00 2001 From: Garrick Aden-Buie Date: Mon, 22 May 2023 11:48:37 -0400 Subject: [PATCH 25/26] Hide debug messages behind envvar --- .../testthat/helpers-sidebar-animation.R | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/inst/apps/312-bslib-sidebar-resize/tests/testthat/helpers-sidebar-animation.R b/inst/apps/312-bslib-sidebar-resize/tests/testthat/helpers-sidebar-animation.R index 3b8b3efd4b..3787545647 100644 --- a/inst/apps/312-bslib-sidebar-resize/tests/testthat/helpers-sidebar-animation.R +++ b/inst/apps/312-bslib-sidebar-resize/tests/testthat/helpers-sidebar-animation.R @@ -70,18 +70,20 @@ window.updatedOutputs = []; shared = app$get_js(js_element_width(sel_plot_img_shared)) ) - cat("\n----- Recording", sidebar, "sidebar on", page, "page transition -----") - cat_item <- function(which) { - value <- get(which) - cat("\n", which, ":", sep = "\n") - cat("\n shared:", paste(value[["shared"]], collapse = ", ")) - cat("\n local: ", paste(value[["local"]], collapse = ", ")) + if (identical(Sys.getenv("DEBUG_APP_312"), "true")) { + cat("\n----- Recording", sidebar, "sidebar on", page, "page transition -----") + cat_item <- function(which) { + value <- get(which) + cat("\n", which, ":", sep = "") + cat("\n shared:", paste(value[["shared"]], collapse = ", ")) + cat("\n local: ", paste(value[["local"]], collapse = ", ")) + } + cat_item("initial") + cat_item("during") + cat_item("final") + cat_item("outputs") + cat("\n-----------------------------------------------------------------\n\n") } - cat_item("initial") - cat_item("during") - cat_item("final") - cat_item("outputs") - cat("\n-----------------------------------------------------------------\n\n") # we only need unique observations between initial and final From 8671d17e57b4b62e5fae62ea985138f9e01bef26 Mon Sep 17 00:00:00 2001 From: Garrick Aden-Buie Date: Mon, 22 May 2023 14:39:33 -0400 Subject: [PATCH 26/26] Add a `$wait_for_js()` to keep test in sync with browser --- .../312-bslib-sidebar-resize/tests/testthat/helpers-js.R | 6 +++++- .../tests/testthat/helpers-sidebar-animation.R | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/inst/apps/312-bslib-sidebar-resize/tests/testthat/helpers-js.R b/inst/apps/312-bslib-sidebar-resize/tests/testthat/helpers-js.R index 2b7ee89336..2fd2826edc 100644 --- a/inst/apps/312-bslib-sidebar-resize/tests/testthat/helpers-js.R +++ b/inst/apps/312-bslib-sidebar-resize/tests/testthat/helpers-js.R @@ -1,6 +1,10 @@ js_sidebar_transition_complete <- function(id) { + paste0("!", js_sidebar_is_transitioning(id)) +} + +js_sidebar_is_transitioning <- function(id) { sprintf( - "!document.getElementById('%s').parentElement.classList.contains('transitioning');", + "document.getElementById('%s').parentElement.classList.contains('transitioning');", id ) } diff --git a/inst/apps/312-bslib-sidebar-resize/tests/testthat/helpers-sidebar-animation.R b/inst/apps/312-bslib-sidebar-resize/tests/testthat/helpers-sidebar-animation.R index 3787545647..3a4bc27f6c 100644 --- a/inst/apps/312-bslib-sidebar-resize/tests/testthat/helpers-sidebar-animation.R +++ b/inst/apps/312-bslib-sidebar-resize/tests/testthat/helpers-sidebar-animation.R @@ -48,7 +48,9 @@ if (!window.updatedOutputs) { } window.updatedOutputs = []; ") - app$click(selector = sprintf("#%s + .collapse-toggle", id_sidebar)) + app$ + click(selector = sprintf("#%s + .collapse-toggle", id_sidebar))$ + wait_for_js(js_sidebar_is_transitioning(id_sidebar)) while (!app$get_js(js_sidebar_transition_complete(id_sidebar))) { Sys.sleep(0.1)