Skip to content

Commit

Permalink
feat: Option/envvar to choose headless mode (#172)
Browse files Browse the repository at this point in the history
* chromote.headless
* CHROMOTE_HEADLESS
* Also adds `chromote.launch.echo_cmd`
  • Loading branch information
gadenbuie authored Aug 29, 2024
1 parent f030285 commit 3ee92d9
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 2 deletions.
6 changes: 6 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# chromote (development version)

* The headless mode used by Chrome can now be selected with the `chromote.headless` option or `CHROMOTE_HEADLESS` environment variable.

In Chrome v128, a [new headless mode](https://developer.chrome.com/docs/chromium/new-headless) became the default. The new mode uses the same browser engine as the regular Chrome browser, whereas the old headless mode is built on a separate architecture. The old headless mode may be faster to launch and is still well-suited to many of the tasks for which chromote is used.

For now, to avoid disruption, chromote defaults to using the old headless mode. In the future, chromote will follow Chrome and default to `"new"` headless mode. (And at some point, Chrome intends to remove the old headless mode which is now offered as [a separate binary](https://developer.chrome.com/blog/chrome-headless-shell).) To test the new headless mode, use `options(chromote.headless = "new")` or `CHROMOTE_HEADLESS="new"` (in `.Renviron` or via `Sys.setenv()`). (#172)

# chromote 0.2.0

## Breaking changes
Expand Down
31 changes: 29 additions & 2 deletions R/chrome.R
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,32 @@ inform_if_chrome_not_found <- function(
NULL
}

chrome_headless_mode <- function() {
opt <- getOption("chromote.headless", NULL)
env <- Sys.getenv("CHROMOTE_HEADLESS", NULL)

# TODO Chrome v128 changed the default from --headless=old to --headless=new
# in 2024-08. Old headless mode was effectively a separate browser render,
# and while more performant did not share the same browser implementation as
# headful Chrome. New headless mode will likely be useful to some, but in most
# chromote use cases -- printing to PDF and testing -- we are not ready to
# move to the new mode. We'll use `--headless=old` as the default for now
# until the new mode is more stable, or until we add support for downloading
# specific versions of Chrome. (See rstudio/chromote#171)
default_mode <- "old"
mode <- tolower(opt %||% env %||% default_mode)

if (!mode %in% c("old", "new")) {
used <- if (!is.null(opt)) "chromote.headless" else "CHROMOTE_HEADLESS"
rlang::inform(
sprintf('Invalid value for `%s`. Using `"%s"`.', used, default_mode)
)
mode <- default_mode
}

sprintf("--headless=%s", mode)
}

launch_chrome <- function(path = find_chrome(), args = get_chrome_args()) {
if (is.null(path)) {
stop("Invalid path to Chrome")
Expand All @@ -173,14 +199,15 @@ launch_chrome_impl <- function(path, args, port) {
p <- process$new(
command = path,
args = c(
"--headless",
chrome_headless_mode(),
paste0("--remote-debugging-port=", port),
paste0("--remote-allow-origins=http://127.0.0.1:", port),
args
),
supervise = TRUE,
stdout = tempfile("chrome-stdout-", fileext = ".log"),
stderr = tempfile("chrome-stderr-", fileext = ".log")
stderr = tempfile("chrome-stderr-", fileext = ".log"),
echo_cmd = getOption("chromote.launch.echo_cmd", FALSE)
)

connected <- FALSE
Expand Down
25 changes: 25 additions & 0 deletions R/chromote-package.R
Original file line number Diff line number Diff line change
@@ -1,6 +1,31 @@
#' @keywords internal
"_PACKAGE"

#' chromote Options
#'
#' @description
#' These options and environment variables that are used by chromote. Options
#' are lowercase and can be set with `options()`. Environment variables are
#' uppercase and can be set in an `.Renviron` file, with `Sys.setenv()`, or in
#' the shell or process running R. If both an option or environment variable are
#' supported, chromote will use the option first.
#'
#' * `CHROMOTE_CHROME` \cr
#' Path to the Chrome executable. If not set, chromote will
#' attempt to find and use the system installation of Chrome.
#' * `chromote.headless`, `CHROMOTE_HEADLESS` \cr
#' Headless mode for Chrome. Can be `"old"` or `"new"`. See
#' [Chrome Headless mode](https://developer.chrome.com/docs/chromium/new-headless)
#' for more details.
#' * `chromote.timeout` \cr
#' Timeout (in seconds) for Chrome to launch or connect. Default is `10`.
#' * `chromote.launch.echo_cmd` \cr
#' Echo the command used to launch Chrome to the console for debugging.
#' Default is `FALSE`.
#'
#' @name chromote-options
NULL

## usethis namespace: start
#' @import promises later
#' @importFrom fastmap fastmap
Expand Down
26 changes: 26 additions & 0 deletions man/chromote-options.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pkgdown/_pkgdown.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ reference:
- title: Default settings
# desc: ~
contents:
- chromote-options
- default_chrome_args
- default_chromote_object

Expand Down

0 comments on commit 3ee92d9

Please sign in to comment.