Commands and events

Commands and Events

The Chrome DevTools Protocol has two types of methods: commands and events. Methods like Page$navigate() and DOM$querySelector() are commands. That is, they tell the browser to do something; the browser does it, and then sends back some data.

Events are quite different from commands. When, for example, you run b$Page$loadEventFired(), it does not send a message to the browser. Rather, this method tells the R process to wait until it receives a Page.loadEventFired message from the browser.

Here is an example of how that event can be used. Note that these two lines of code must be run together, without any delay at all (this can be enforced by wrapping both lines of code in { .... }).

library(chromote)
b <- ChromoteSession$new()

# Send a command to navigate to a page
b$Page$navigate("https://www.r-project.org")
#> $frameId
#> [1] "0ADE3CFBAF764B0308ADE1ACCC33358B"
#>
#> $loaderId
#> [1] "112AF4AC0C13FF4A95BED8173C3F4C7F"

# Wait for the Page.loadEventFired event
b$Page$loadEventFired()
#> $timestamp
#> [1] 680.7603

After running these two lines, the R process will be blocked. While it’s blocked, the browser will load the page, and then send a message to the R process saying that the Page.loadEventFired event has occurred. The message looks something like this:

{"method":"Page.loadEventFired","params":{"timestamp":699232.345338}}

After the R process receives this message, the function returns the value, which looks like this:

$timestamp
[1] 699232.3

Note: This sequence of commands, with Page$navigate() and then Page$loadEventFired() works interactively when you run the commands slowly, but it will not work 100% of the time. See vignette("example-loading-page") for a reliable approach to page loading that works in all situations.

Automatic Events

Chromote insulates the user from some of the details of how the CDP implements event notifications. Event notifications are not sent from the browser to the R process by default; you must first send a command to enable event notifications for a domain. For example Page.enable enables event notifications for the Page domain – the browser will send messages for all Page events. (See the Events section in this page). These notifications will continue to be sent until the browser receives a Page.disable command.

By default, Chromote hides this implementation detail. When you call b$Page$loadEventFired(), Chromote sends a Page.enable command automatically, and then waits until it receives the Page.loadEventFired event notification. Then it sends a Page.disable command.

Note that in asynchronous mode, the behavior is slightly more sophisticated: it maintains a counter of how many outstanding events it is waiting for in a given domain. When that count goes from 0 to 1, it sends the X.enable command; when the count goes from 1 to 0, it sends the X.disable command. For more information, see vignette("sync-async").

If you need to customize the arguments used by the automatically-run enable command, you can use the $auto_events_enable_args() method of a Chromote or ChromoteSession instance, e.g. b$auto_events_enable_args("Page", enableFileChooserOpenedEvent = TRUE).

If you do not want automatic event enabling and disabling, then when creating the ChromoteSession object, use ChromoteSession$new(auto_events = FALSE).