如何使用 jquery 和 selenium 在“chrome://downloads”访问“shadow-root”下的元素?

Posted

技术标签:

【中文标题】如何使用 jquery 和 selenium 在“chrome://downloads”访问“shadow-root”下的元素?【英文标题】:How to access elements under `shadow-root` at 'chrome://downloads' using jquery and selenium? 【发布时间】:2017-11-08 02:07:46 【问题描述】:

我正在尝试在我的 selenium javascript 应用程序中获取最后下载的文件的名称。

我的 selenium 驱动程序使用:driver.get('chrome://downloads'); 导航到 chrome 下载页面,但是当我到达那里时,selenium 无法在下载页面上找到任何元素。

chrome 下载页面 'chrome://downloads' 有一堆 shadow-root 元素,我不知道如何才能访问这些元素我想要的id。 如何访问shadow-root 项目下的标识符?

我想得到 $("#file-link") 如下所示:

但是当我使用jquery查找时,一切都返回null(可能是因为它在shadow-root后面)

这是我所有信息的大图,包括显示“#file-link”完全存在:

我用来等待元素存在的代码与我用于应用程序中所有元素的代码相同,所以我认为这已经在工作了:

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? :(
    );
);

这是我的版本信息:

铬 v54.0.2840.71 节点 v6.5.0 ChromeDriver v2.27.440175 selenium-webdriver v3.4.0

类似问题

Selenium webdriver can't find elements at chrome://downloads(这和我在 python 中遇到的问题相同)

链接

Selenium Javascript API:https://seleniumhq.github.io/selenium/docs/api/javascript/

【问题讨论】:

【参考方案1】:

您示例中的$ 不是JQuery 的简写。 它的功能被页面覆盖,仅通过 id 定位元素:

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

要通过 shadow DOM 进行选择,您需要使用 '/deep/' 组合器。

所以要获取下载页面中的所有链接:

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

还有硒:

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

【讨论】:

【参考方案2】:

为什么不直接检查下载文件夹?我这样做是为了下载 Excel 文件。我首先清除下载文件夹,单击按钮下载文件,等待约 5 秒(因文件大小、互联网速度等而异),然后在文件夹中查找“*.xlsx”文件。这还具有使用任何浏览器的好处。

C# 示例:

/// <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 "";
    

然后在我的测试中我可以Assert.IsEmpty(LocateDownloadedFile); 这样如果断言失败,则打印错误消息。

预期:String.Empty。 实际:不存在文件。

【讨论】:

谢谢!是的,这可能是一个更好的方法。我认为chrome下载所有用户文件的位置有一个变量,所以我可以检查一下最近是否有文件下载。我会试试这个方法,看看它是否更容易开始工作:)

以上是关于如何使用 jquery 和 selenium 在“chrome://downloads”访问“shadow-root”下的元素?的主要内容,如果未能解决你的问题,请参考以下文章

Selenium:如何使用Javascript将密钥发送到JQuery输入

使用 c#、selenium 和 jquery 实现 IE 自动化 - 从动态表中随机获取

Selenium Navigate Back 和 jQuery Dirty Forms 插件

JQuery Javascript 函数以 JSON 格式返回 highchart 图形数据源,并通过 Selenium 和 C# 正确格式化

python+selenium十一:jQuery和js语法js处理iframe

Selenium SendKey 与 jquery 输入掩码冲突