diff --git a/R/chromote_session.R b/R/chromote_session.R index 09fa073..18bdba2 100644 --- a/R/chromote_session.R +++ b/R/chromote_session.R @@ -197,6 +197,66 @@ ChromoteSession <- R6Class( } }, + #' @description Evaluate JavaScript + #' This is a wrapper around `$Runtime$evaluate()` that has sensible defaults + #' for user interaction. + #' @param script JavaScript (character) expression to evaluate + #' @param ... Arguments to pass to `$Runtime$evaluate()` + #' @param timeout Chrome DevTools Protocol timeout, in milliseconds. If + #' provided, the \pkg{chromote} `timeout_` argument will default to to `2 * + #' timeout`. + #' @param awaitPromise If the JavaScript expression returns a Promise, + #' `awaitPromise` will cause the Chrome DevTools Protocol to block until the + #' promise is resolved. Defaults to `TRUE`, which is different than Chrome + #' DevTools Protocol (`FALSE`). + #' @param returnByValue This signifies if the return value of the script + #' should be returned to the R session. Defaults to `TRUE`, which is + #' different than Chrome DevTools Protocol (`FALSE`). + #' @param wait_ If `FALSE`, return a [promises::promise()] that will resolve + #' when the `ChromoteSession` has finished executing the script. Otherwise, + #' block until the execution of the script has returned. + eval = function( + script, + ..., + returnByValue = TRUE, + awaitPromise = TRUE, + wait_ = TRUE + ) { + + # https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#method-evaluate + p <- + self$Runtime$evaluate( + script, ..., + returnByValue = returnByValue, + wait_ = FALSE + )$ + catch(function(e) { + # Ex: + # ```r + # b$Runtime$evaluate( + # "{let fib = function(n) { if (n < 2) { return n}; return fib(n-1) + fib(n - 2)}; fib(40);}", + # timeout = 100, timeout_ = 10 + # ) + #> Error in onRejected(reason) : code: -32000 + #> message: Execution was terminated + # Have not come across other data in the error object to capture / pass along + + # Return something similar to a timeout object + list(results = list( + type = "object", + subtype = "error", + className = "Error", + description = paste0("Error while evaluating JavaScript: ", as.character(e)) + )) + }) + + if (wait_) { + self$wait_for(p) + } else { + p + } + }, + #' @description Take a PNG screenshot #' #' @param filename File path of where to save the screenshot. diff --git a/man/ChromoteSession.Rd b/man/ChromoteSession.Rd index d2c9cce..80c6f30 100644 --- a/man/ChromoteSession.Rd +++ b/man/ChromoteSession.Rd @@ -205,6 +205,7 @@ wait for a Chrome DevTools Protocol response.} \item \href{#method-new}{\code{ChromoteSession$new()}} \item \href{#method-view}{\code{ChromoteSession$view()}} \item \href{#method-close}{\code{ChromoteSession$close()}} +\item \href{#method-eval}{\code{ChromoteSession$eval()}} \item \href{#method-screenshot}{\code{ChromoteSession$screenshot()}} \item \href{#method-screenshot_pdf}{\code{ChromoteSession$screenshot_pdf()}} \item \href{#method-new_session}{\code{ChromoteSession$new_session()}} @@ -349,6 +350,49 @@ b$close()} } +} +\if{html}{\out{