From f7c1ca8d8f9d5f678ff19e2c355f5c60e696a623 Mon Sep 17 00:00:00 2001 From: christophe dervieux Date: Sun, 22 Mar 2020 14:55:27 +0100 Subject: [PATCH 1/2] add support for a custom user data dir * as a new argument in Chrome$new() * add some tests * new helper function to deactivate verbose in test : without_verbose() --- R/Chrome.R | 31 +++++++++++++++++++++++++++---- tests/testthat/helper-chrome.R | 7 +++++++ 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/R/Chrome.R b/R/Chrome.R index 60a416c..2ea5e7a 100644 --- a/R/Chrome.R +++ b/R/Chrome.R @@ -191,12 +191,16 @@ perform_with_chrome <- function( #' connect to headless Chromium/Chrome. #' * `max_attempts`: Integer scalar, number of tries to connect to headless #' Chromium/Chrome. +#' * `user_data_dir`: Character, for advanced user, it allows to set a path to a +#' custom user data dir. If provided, this folder will be used instead of a +#' new and empty one created by crrri. If it does not exist, this folder will +#' be created but not removed afterwards. It must be done manually. #' * `callback`: Function with one argument. #' * `async`: Does the function return a promise? #' #' @section Details: #' `$new()` opens a new headless Chromium/Chrome. You can deactivate verbose -#' from chrome process launching byt setting option `crrri.verbose` to FALSE. +#' from chrome process launching by setting option `crrri.verbose` to FALSE. #' #' `$connect(callback = NULL)` connects the R session to the remote instance of #' headless Chromium/Chrome. The returned value depends on the value of the @@ -272,7 +276,8 @@ Chrome <- R6::R6Class( public = list( initialize = function( bin = Sys.getenv("HEADLESS_CHROME"), debug_port = 9222L, local = FALSE, - extra_args = NULL, headless = TRUE, retry_delay = 0.2, max_attempts = 15L + extra_args = NULL, headless = TRUE, retry_delay = 0.2, max_attempts = 15L, + user_data_dir = NULL ) { assert_that(is_scalar_character(bin)) assert_that( @@ -286,7 +291,14 @@ Chrome <- R6::R6Class( assert_that(is_scalar_integerish(max_attempts)) private$.bin <- bin - work_dir <- chr_new_data_dir() + work_dir <- if (is.null(user_data_dir)) { + private$.remove_work_dir <- TRUE + chr_new_data_dir() + } else { + assert_that(is_scalar_character(user_data_dir)) + private$.remove_work_dir <- FALSE + normalizePath(user_data_dir) + } chr_process <- chr_launch(bin, debug_port, extra_args, headless, work_dir) private$.work_dir <- work_dir private$.process <- chr_process @@ -331,6 +343,7 @@ Chrome <- R6::R6Class( private = list( .bin = NULL, .work_dir = NULL, + .remove_work_dir = NULL, .process = NULL, .async_finalizer = function() { clients_disconnected <- timeout( @@ -362,7 +375,17 @@ Chrome <- R6::R6Class( } private$.process$wait() } - chr_clean_work_dir(private$.work_dir) + if (private$.remove_work_dir) { + chr_clean_work_dir(private$.work_dir) + } else { + if (getOption("crrri.verbose", TRUE)) { + message(paste0( + "\nCustom user_data_dir has been provided and not deleted by crrri.", + " Delete manually if needed:\n", + private$.work_dir + )) + } + } } ) killed_and_cleaned diff --git a/tests/testthat/helper-chrome.R b/tests/testthat/helper-chrome.R index a1996ec..d426844 100644 --- a/tests/testthat/helper-chrome.R +++ b/tests/testthat/helper-chrome.R @@ -26,3 +26,10 @@ setup_chrome_test <- function(env = rlang::caller_env()) { # we need this because these function are normally called in the test file directly env = env) } + +without_verbose <- function(code) { + old <- getOption("crrri.verbose", TRUE) + options(crrri.verbose = FALSE) + on.exit(options(crrri.verbose = old)) + force(code) +} From c8e6bbbfd753c11c693c3924cd4bbf0b93ab3fec Mon Sep 17 00:00:00 2001 From: christophe dervieux Date: Sun, 22 Mar 2020 15:02:59 +0100 Subject: [PATCH 2/2] devtools::document --- R/Chrome.R | 3 ++- man/Chrome.Rd | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/R/Chrome.R b/R/Chrome.R index 2ea5e7a..1b21946 100644 --- a/R/Chrome.R +++ b/R/Chrome.R @@ -194,7 +194,8 @@ perform_with_chrome <- function( #' * `user_data_dir`: Character, for advanced user, it allows to set a path to a #' custom user data dir. If provided, this folder will be used instead of a #' new and empty one created by crrri. If it does not exist, this folder will -#' be created but not removed afterwards. It must be done manually. +#' be created but not removed afterwards. It must be done manually. +#' [About user data directory in Chrome](https://chromium.googlesource.com/chromium/src/+/master/docs/user_data_dir.md) #' * `callback`: Function with one argument. #' * `async`: Does the function return a promise? #' diff --git a/man/Chrome.Rd b/man/Chrome.Rd index 01a276c..eadaa9e 100644 --- a/man/Chrome.Rd +++ b/man/Chrome.Rd @@ -46,6 +46,11 @@ in headless mode. connect to headless Chromium/Chrome. \item \code{max_attempts}: Integer scalar, number of tries to connect to headless Chromium/Chrome. +\item \code{user_data_dir}: Character, for advanced user, it allows to set a path to a +custom user data dir. If provided, this folder will be used instead of a +new and empty one created by crrri. If it does not exist, this folder will +be created but not removed afterwards. It must be done manually. +\href{https://chromium.googlesource.com/chromium/src/+/master/docs/user_data_dir.md}{About user data directory in Chrome} \item \code{callback}: Function with one argument. \item \code{async}: Does the function return a promise? } @@ -54,7 +59,7 @@ Chromium/Chrome. \section{Details}{ \code{$new()} opens a new headless Chromium/Chrome. You can deactivate verbose -from chrome process launching byt setting option \code{crrri.verbose} to FALSE. +from chrome process launching by setting option \code{crrri.verbose} to FALSE. \code{$connect(callback = NULL)} connects the R session to the remote instance of headless Chromium/Chrome. The returned value depends on the value of the