admin管理员组

文章数量:1316694

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:

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

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

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

  • Selenium webdriver can't find elements at chrome://downloads (This is the same problem I am having but in python)

Links

  • Selenium Javascript API: /

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:

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

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

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

  • Selenium webdriver can't find elements at chrome://downloads (This is the same problem I am having but in python)

Links

  • Selenium Javascript API: https://seleniumhq.github.io/selenium/docs/api/javascript/
Share Improve this question edited Jun 6, 2017 at 22:20 Katie asked Jun 6, 2017 at 22:04 KatieKatie 48.3k19 gold badges102 silver badges129 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 5

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/' binator.

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]")

Why not check the downloads folder directly? I do this for downloading Excel files. I first clear the downloads folder, click the button to download the file, wait ~5 sec (varies by file size, internet speed, etc.), and then looking in the folder for a "*.xlsx" file. This also has the benefit of working with any browser.

C# Examples:

/// <summary>
/// Deletes the contents of the current user's "Downloads" folder
/// </summary>
public static void DeleteDownloads()
{
    // Get the default downloads folder for the current user
    string downloadFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "\\Downloads";
    // Delete all existing files
    DirectoryInfo di = new DirectoryInfo(directoryPath);
    foreach (FileInfo file in di.GetFiles())
    {
        file.Delete();
    }
    foreach (DirectoryInfo dir in di.GetDirectories())
    {
        dir.Delete(true);
    }
}

/// <summary>
/// Looks for a file with the given extension (Example: "*.xlsx") in the current user's "Download" folder.
/// </summary>
/// <returns>Empty string if files are found</returns>
public static string LocateDownloadedFile(string fileExtension)
{
    // Get the default downloads folder for the current user
    string downloadFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "\\Downloads";
    DirectoryInfo di = new DirectoryInfo(downloadFolderPath);
    FileInfo[] filesFound = di.GetFiles(fileExtension);
    if (filesFound.Length == 0)
    {
        return "No files present";
    }
    else
    {
        return "";
    }
}

And then in my Test I can Assert.IsEmpty(LocateDownloadedFile); This way if the assert fails, the error message if printed.

Expected: String.Empty. Actual: No files present.

I think this should work with the current version Chrome:

document.getElementsByTagName("downloads-manager")[0]
.shadowRoot.children["mainContainer"]
.getElementsByTagName("downloads-item")[0]
.shadowRoot.getElementById("file-link")
.getAttribute("href")

本文标签: