如何与元素#影子根(开)内而Chrome浏览器清除浏览数据的使用cssSelector互动

DebanjanB:

我一直在下面讨论如何使用Selenium自动化阴影DOM元素?一起工作#shadow-root (open)的元素。

虽然在定位的过程中Clear data的内键清除浏览数据弹出,而访问的URL出现chrome://settings/clearBrowserData我无法找到以下元素:

#shadow-root (open)
<settings-privacy-page>

快照:

设置 - 隐私页

使用下面是我的代码试验和遇到的相关的错误:

  • 尝试1:

    WebElement root5 = shadow_root4.findElement(By.tagName("settings-privacy-page"));
    
    • 错误:

      Exception in thread "main" org.openqa.selenium.JavascriptException: javascript error: b.getElementsByTagName is not a function
      
  • 尝试2:

    WebElement root5 = shadow_root4.findElement(By.cssSelector("settings-privacy-page"));
    
    • 错误:

      Exception in thread "main" org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"css selector","selector":"settings-privacy-page"}
      
  • 尝试3:

    WebElement root5 = (WebElement)((JavascriptExecutor)shadow_root4).executeScript("return document.getElementsByTagName('settings-privacy-page')[0]");
    
    • 错误:

      Exception in thread "main" java.lang.ClassCastException: org.openqa.selenium.remote.RemoteWebElement cannot be cast to org.openqa.selenium.JavascriptExecutor
      

柜面,如果它是有帮助的初始代码块(直到上面的线)可以完美运行:

driver.get("chrome://settings/clearBrowserData");
WebElement root1 = driver.findElement(By.tagName("settings-ui"));
WebElement shadow_root1 = expand_shadow_element(root1);

WebElement root2 = shadow_root1.findElement(By.cssSelector("settings-main#main"));
WebElement shadow_root2 = expand_shadow_element(root2);

WebElement root3 = shadow_root2.findElement(By.cssSelector("settings-basic-page[role='main']"));
WebElement shadow_root3 = expand_shadow_element(root3);

WebElement root4 = shadow_root3.findElement(By.cssSelector("settings-section[page-title='Privacy and security']"));
WebElement shadow_root4 = expand_shadow_element(root4);

PS:expand_shadow_element()工作完美无瑕。

谁能帮助我出去吗?

supputuri:

如果您想获得“清除数据”元素,那么你可以用下面的JS来获取元素,然后执行。

return document.querySelector('settings-ui').shadowRoot.querySelector('settings-main').shadowRoot.querySelector('settings-basic-page').shadowRoot.querySelector('settings-section > settings-privacy-page').shadowRoot.querySelector('settings-clear-browsing-data-dialog').shadowRoot.querySelector('#clearBrowsingDataDialog').querySelector('#clearBrowsingDataConfirm')

下面是示例脚本。

driver.get("chrome://settings/clearBrowserData");
driver.manage().window().maximize();
JavascriptExecutor js = (JavascriptExecutor) driver; 
WebElement clearData = (WebElement) js.executeScript("return document.querySelector('settings-ui').shadowRoot.querySelector('settings-main').shadowRoot.querySelector('settings-basic-page').shadowRoot.querySelector('settings-section > settings-privacy-page').shadowRoot.querySelector('settings-clear-browsing-data-dialog').shadowRoot.querySelector('#clearBrowsingDataDialog').querySelector('#clearBrowsingDataConfirm')");
// now you can click on clear data button
clearData.click();

编辑2:说明

问题:硒不提供工作的明确支持与阴影DOM元素,因为它们不是在当前的DOM。这就是为什么我们会得到的原因NoSuchElementException时,尝试访问的元素例外shadow dom

影子DOM: 在这里输入图像描述

注意:我们将参照图中所示的条款。所以,请经过图片为更好的理解。

解:

In order to work with shadow element first we have to find the shadow host to which the shadow dom is attached. Here is the simple method to get the shadow root based on the shadowHost.

private static WebElement getShadowRoot(WebDriver driver,WebElement shadowHost) {
    JavascriptExecutor js = (JavascriptExecutor) driver;
    return (WebElement) js.executeScript("return arguments[0].shadowRoot", shadowHost);
}

And then you can access the shadow tree element using the shadowRoot Element.

// get the shadowHost in the original dom using findElement
WebElement shadowHost = driver.findElement(By.cssSelector("shadowHost_CSS"));
// get the shadow root
WebElement shadowRoot = getShadowRoot(driver,shadowHost);
// access shadow tree element
WebElement shadowTreeElement = shadowRoot.findElement(By.cssSelector("shadow_tree_element_css"));

In order to simplify all the above steps created the below method.

public static WebElement getShadowElement(WebDriver driver,WebElement shadowHost, String cssOfShadowElement) {
    WebElement shardowRoot = getShadowRoot(driver, shadowHost);
    return shardowRoot.findElement(By.cssSelector(cssOfShadowElement));
}

Now you can get the shadowTree Element with single method call

WebElement shadowHost = driver.findElement(By.cssSelector("shadowHost_CSS_Goes_here));
WebElement shadowTreeElement = getShadowElement(driver,shadowHost,"shadow_tree_element_css");

And perform the operations as usual like .click(), .getText().

shadowTreeElement.click()

This Looks simple when you have only one level of shadow DOM. But here, in this case we have multiple levels of shadow doms. So we have to access the element by reaching each shadow host and root. 在这里输入图像描述

Below is the snippet using the methods that mentioned above (getShadowElement and getShadowRoot)

// Locate shadowHost on the current dom
WebElement shadowHostL1 = driver.findElement(By.cssSelector("settings-ui"));

// now locate the shadowElement by traversing all shadow levels
WebElement shadowElementL1 = getShadowElement(driver, shadowHostL1, "settings-main");
WebElement shadowElementL2 = getShadowElement(driver, shadowElementL1,"settings-basic-page");
WebElement shadowElementL3 = getShadowElement(driver, shadowElementL2,"settings-section > settings-privacy-page");
WebElement shadowElementL4 = getShadowElement(driver, shadowElementL3,"settings-clear-browsing-data-dialog");
WebElement shadowElementL5 = getShadowElement(driver, shadowElementL4,"#clearBrowsingDataDialog");
WebElement clearData = shadowElementL5.findElement(By.cssSelector("#clearBrowsingDataConfirm"));
System.out.println(clearData.getText());
clearData.click();

您可以实现所有在单个的JS上述步骤呼叫作为在在回答的开头提到的(下面加刚,以减少混乱)。

WebElement clearData = (WebElement) js.executeScript("return document.querySelector('settings-ui').shadowRoot.querySelector('settings-main').shadowRoot.querySelector('settings-basic-page').shadowRoot.querySelector('settings-section > settings-privacy-page').shadowRoot.querySelector('settings-clear-browsing-data-dialog').shadowRoot.querySelector('#clearBrowsingDataDialog').querySelector('#clearBrowsingDataConfirm')");

截图: 在这里输入图像描述

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Chrome浏览器的“清除浏览数据”不会清除打开的隐身标签页的Cookie吗?

如何清除在每次测试之间的chrome浏览器的状态?

如何清除Google Chrome浏览器的预测性搜索?

如何清除Google Chrome浏览器地址栏?

如何使用现代浏览器(具有 shadowDOM 内部编辑器)清除输入元素?

如何检查浏览器是否支持影子DOM

如何使用angularjs清除浏览器缓存?

如何清除Chromium浏览器缓存?

使用python清除浏览器缓存

如何从 Chrome 浏览器获取画布元素坐标

清除浏览器数据还会清除PWA的数据吗?

如何从ionic 3打开谷歌浏览器

如何使用Chrome浏览器API更改chrome:// flags?

如何将Chromium浏览器数据导入Chrome

如何使用AS3打开隐身模式或专用浏览器模式?

如何使用chrome作为浏览器和nginx作为网络服务器清除缓存的javascript文件

我如何通过uiautomator浏览器将元素位置转换为xpath并通过类名,cssselector将其与Java中的appium一起使用

如何从Cordova应用内浏览器获取数据

浏览回到根浏览器容器

如何在不打开 Chrome 浏览器的情况下使用 Selenium 获取数据?

在 ubuntu 上更新 Chrome 会清除我的浏览器数据、cookie、会话存储等吗?

如何通过Selenium在Chrome浏览器中使用Tor

如何使用Google Chrome浏览器播放.swf文件?

勇敢的浏览器如何使用Chrome的开发工具?

如何让Chromium使用Google Chrome浏览器中的Flash?

如何使用插件在 Chrome 浏览器中运行 apk?

如何使用 Selenium 更改浏览器(Chrome)的语言?

如何使用Nightwatchjs将元素带入浏览器的视点

如何使用Safari浏览器检查元素