Search code examples
javascriptjqueryhtmlnode.jsselenium

How to access elements under `shadow-root` at 'chrome://downloads' using jquery and selenium?


I am trying to get the name of the last downloaded file in my selenium javascript application.

I have my selenium driver navigating to the chrome downloads page using: driver.get('chrome://downloads'); , but when I get there, selenium is not able to find ANY elements on the download page.

The chrome downloads page 'chrome://downloads' has a bunch of shadow-root elements that I don't know how to get underneath in order to access the id's that I want. How do I access identifiers beneath shadow-root items?

I want to get $("#file-link") as shown here:

showing file link id

But when I use jquery to find it, everything returns null (probably because it's behind shadow-root)

jquery actions return null jquery actions return null 2

Here's a big picture of all the information I have including showing that "#file-link" totally exists:

html structure of chrome download page

The code I am using to wait for the element to exist is the same that I use for all elements in my application, so I think this is already working:

driver.wait(until.elementLocated(By.id('downloads-manager')), 120000).then(function(){
    console.log("#downloads-manager shows");
    driver.findElement(By.id('downloads-manager')).then(function(dwMan){
        //How do I "open" #shadow-root now? :(
    });
});

Here is my version information:

  • Chromium v54.0.2840.71
  • Node v6.5.0
  • ChromeDriver v2.27.440175
  • selenium-webdriver v3.4.0

Similar Question

Links


Solution

  • The $ from your example is not a shorthand for JQuery. It's function overridden by the page to locate an element by id only:

    function $(id){var el=document.getElementById(id);return el?assertInstanceof(el,HTMLElement):null}
    

    To select through the shadow DOM, you need to use the '/deep/' combinator.

    So to get all the links in the download page:

    document.querySelectorAll("downloads-manager /deep/ downloads-item /deep/ [id=file-link]")
    

    And with Selenium:

    By.css("downloads-manager /deep/ downloads-item /deep/ [id=file-link]")