rstudio / DT

R Interface to the jQuery Plug-in DataTables
https://rstudio.github.io/DT/
Other
598 stars 181 forks source link

Testing editable DT with shinytest #716

Open cmaguire485 opened 5 years ago

cmaguire485 commented 5 years ago

I'm trying to create unit tests for a shiny app I've been working on but can't work out how to input values to an editable DT table.

Example app:

library(shiny)
library(DT)

ui <- fluidPage(
  DTOutput("table"), 
  textOutput("mean")
)

server <- function(input, output) {
  tableUpdate <- reactiveVal(0)

  table <- data.frame(A = 1:5, B = 6:10, C = 11:15)

  output$table <- renderDT({table},
    options = list(paging = FALSE, dom = 't'),
    selection = 'none',
    server = FALSE,
    editable = list(target = 'row')
  )

  observeEvent(input$table_cell_edit, {
    table <<- editData(table, input$table_cell_edit)
    tableUpdate(tableUpdate() + 1)
  })

  output$mean <- renderText({
    tableUpdate()
    paste(mean(table$A), mean(table$B), mean(table$C))
  })
}

shinyApp(ui, server)

Example test:

library(shinytest)

app <- ShinyDriver$new(".")
app$setInputs(table_cell_clicked = list(row = 2, col = 2, value = 7), allowInputNoBinding_ = TRUE)
app$setInputs(table_cell_edit = data.frame(row = 2, col = 0:3, value = "1"), 
              allowInputNoBinding_ = TRUE, priority_ = "event", wait_ = FALSE, values_ = FALSE)
app$takeScreenshot()
app$stop()
rm(app)

I've kept this mostly how it came out when I recorded the test (recordTest(".")), but I've corrected the setInputs values of table_cell_edit and table_cell_clicked (which came out as vectors instead of dataframes).

This gives the error: Error in sd_getAllValues(self, private, input, output, export) : Unable to fetch all values from server. Is target app running with options(shiny.testmode=TRUE?)

Running in test mode does not fix the issue.

Have already asked here: https://stackoverflow.com/questions/58097212/testing-editable-dt-using-shinytest


By filing an issue to this repo, I promise that

I understand that my issue may be closed if I don't fulfill my promises.

stla commented 4 years ago

Could you try:

library(jsonlite)

dat <- data.frame(row = 2, col = 0:3, value = "1")
app$setInputs(table_cell_edit = fromJSON(toJSON(dat), simplifyDataFrame = FALSE), 
              allowInputNoBinding_ = TRUE, priority_ = "event", wait_ = FALSE, values_ = FALSE)
cmaguire485 commented 4 years ago

Doesn't make a difference, app still crashes

shrektan commented 4 years ago

I think it may be caused by the fact that the "table_cell_edit" value hasn't been initialized but I don't have time to verify it by now.

@cmaguire485 Would you mind to install this branch and see if it works?

remotes::install_github('rstudio/DT', ref = "fix716")
stla commented 4 years ago

Doesn't make a difference, app still crashes

Perhaps there's another error. I'm pretty sure that the good "format" for table_cell_edit is

table_cell_edit = fromJSON(toJSON(dat), simplifyDataFrame = FALSE)

stla commented 4 years ago

For me there's no crash with this shinytest:

app <- ShinyDriver$new("../", loadTimeout = 1e+05, 
                       shinyOptions = list(test.mode = TRUE))
app$snapshotInit("mytest")

dat <- data.frame(row = 2, col = 0:3, value = "1")
library(jsonlite) 

app$setInputs(table_cell_edit = fromJSON(toJSON(dat), simplifyDataFrame = FALSE), 
              allowInputNoBinding_ = TRUE, timeout_ = 10000, priority_ = "event", wait_ = FALSE, values_ = FALSE)
app$snapshot()
cmaguire485 commented 4 years ago

Is it working for you, or just not crashing?

For me, running that code produces a screenshot where the 3 numbers at the bottom are unchanged. If you introduce a Sys.sleep(1) immediately before the snapshot then the screenshot it produces is now greyed out.

stla commented 4 years ago

Yes, it doesn't crash, but nothing happens.

cmaguire485 commented 4 years ago

@shrektan apologies, forgot to get back to you - no, it didn't work