Search code examples
rselenium-webdriverrselenium

RSelenium - wait for an element to be visible and click


I am trying to click on an checkbox using RSelenium, but from what I understand, the elements needs to be visible before it's clickable. I've found solutions in other questions on how to do this using Python or Java, but I can't replicate them in R using RSelenium. I thought that one option might be to run JS through executeScript(), but I don't know how to do it correctly.

The problem seems to be similar to these other cases: element.clickElement() does not work, but when checking the box manually, element$isElementSelected() does give the correct output.

MWE:

library(RSelenium)
library(netstat)

rd = rsDriver(browser = "chrome", chromever = NULL, port = free_port(), verbose = FALSE)
remo_dr = rd$client

remo_dr$navigate("https://analisis.cis.es/formulario.jsp?dwld=/Microdatos/MD3318.zip")

clickbox = remo_dr$findElement(using = "id", value = "Terminos")
clickbox$isElementEnabled()
clickbox$isElementSelected()
clickbox$clickElement()
clickbox$isElementSelected()

Output:

> clickbox$isElementEnabled()
[[1]]
[1] TRUE

> clickbox$isElementSelected()
[[1]]
[1] FALSE

> clickbox$clickElement()
> clickbox$isElementSelected()
[[1]]
[1] FALSE

sessionInfo():

R version 3.6.3 (2020-02-29)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS  10.16

Matrix products: default
BLAS:   /Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libRblas.0.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libRlapack.dylib

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] netstat_0.1.1   RSelenium_1.7.7

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.10      XML_3.99-0.3     binman_0.1.2     ps_1.7.2         assertthat_0.2.1 rappdirs_0.3.3   bitops_1.0-6     R6_2.5.1        
 [9] jsonlite_1.8.4   semver_0.2.0     httr_1.4.2       curl_4.3         xml2_1.3.3       tools_3.6.3      wdman_0.2.5      processx_3.8.0  
[17] yaml_2.2.1       compiler_3.6.3   askpass_1.1      caTools_1.18.2   openssl_1.4.3   

Solution

  • Your issue checking the "Terminos" checkbox is due to the Javascript that controls it. In short, the check is enabled not by clicking on the box but by clicking on the label above and around it.

    The issue with load times can be easily solved by a wait time period. I propose setting it at 5 seconds initially, and then a single check that waits another 5 seconds. If you need more iterations, turn the check into a while loop.

    library(RSelenium)
    library(netstat)
    library(rvest)
    
    
    rd = rsDriver(browser = "firefox", chromever = NULL, port = free_port(), verbose = FALSE)
    remo_dr = rd$client
    
    remo_dr$navigate("https://analisis.cis.es/formulario.jsp?dwld=/Microdatos/MD3318.zip")
    
    Sys.sleep(time = 5)
    check_if_banner_is_loaded <- # Check from the HTML's DOM if the clickbanner already exists
      remo_dr$getPageSource()[[1]] |> read_html() %>% html_element(xpath = "//p/input[@id = 'Terminos']") |> is_empty() |> isFALSE()
    
    if(check_if_banner_is_loaded == FALSE) { #If the click banner has not loaded already, wait 5 extra seconds.
      Sys.sleep(time = 5)}
    
    clickbanner <- 
      remo_dr$findElement(using = "xpath", value = "//p[@class = 'paceptacion']/label[@for = 'Terminos']")
    clickbox <- remo_dr$findElement(using = "id", value = "Terminos")
    
    clickbanner$clickElement()
    clickbox$isElementSelected()