【问题标题】:Test automation with polymer 2 piercing the shadow dom (/deep/ deprecated)使用聚合物 2 穿透 shadow dom 进行自动化测试(/deep/ 已弃用)
【发布时间】:2018-03-10 11:00:00
【问题描述】:

目前我的组织使用 Selenium、Protractor 和 Mocha 的 Polymer 1,我们使用 shady dom。对于验收测试,我们使用/deep/ 组合器来穿透DOM。对于聚合物 2,不推荐使用 /deep/ 组合器。

我的问题:在编写验收测试时,如果不推荐使用 /deep/ 组合器,我应该如何穿透阴影 DOM

【问题讨论】:

  • 穿刺选择器被丢弃(/deep/ 和 >>>)。目前没有其他替代方法可以通过单个查询搜索整个 DOM。当前的解决方案是实现一个custom selector,采用多个 CSS 段来搜索每个上下文。
  • 我还找到了一些关于如何处理这种情况的解释。直接来自polymer2 docs - “没有直接替代阴影穿透选择器的替代品......自定义CSS属性可能是最好的选择。”
  • @FlorentB。您是否有机会通过对量角器 git 问题中解决方案的解释将其改造成答案?
  • @FlorentB 我也很想看到这样的例子。感谢您的帮助和指导,关于此问题的信息不多

标签: selenium protractor polymer-2.x shadow-dom


【解决方案1】:

@Dilip Meghwal 回答的简化版本:

public static WebElement pierceShadowRoot(String... selectors) {
    WebElement element = null;
    WebElement shadowRoot = null;
    for (String selector : selectors) {
        if (element == null) {
            element = getDriver().findElement(By.cssSelector(selector));
        } else {
            shadowRoot = (WebElement) getDriver().executeScript("return arguments[0].shadowRoot", element);
            element = (WebElement) shadowRoot.findElement(By.cssSelector(selector));
        }
    }
    return element;
}

作为一个例子,这是我使用它来定位 Google Chrome 的清除缓存按钮的方法,由于 Chrome 中使用了 Polymer 框架,其他方法都不起作用:

WebElement targetElement = pierceShadowRoot("body > settings-ui", "#main", "settings-basic-page",
                "#advancedPage > settings-section:nth-child(1) > settings-privacy-page", "settings-clear-browsing-data-dialog",
                "#clearBrowsingDataConfirm");

【讨论】:

    【解决方案2】:

    在互联网上进行了大量研究后,我想出了一个对我来说效果很好的解决方案。

    我遵循的步骤:

    1. 使用chrome开发工具查找JS路径。
    2. 创建一个字符串数组,其中包含所有需要遍历到目标节点的阴影; 3. 可重用函数将返回以目标元素为子元素的父元素。
    3. 使用目标元素的 CSS 路径执行操作。

    见以下代码:

    String[] shadowRootCalender = {"tickets-spa","tickets-config-page","#calendar"};
    String date="2019-04-16";
    FindShadowRootElement(driver, shadowRootCalender).findElement(By.cssSelector("wdat-date[slot='"+date+"']")).click();
    
    
    public static WebElement FindShadowRootElement(WebDriver driver, String[] shadowRootSelector) {
        WebElement root = null;
        for(int i=0; i<shadowRootSelector.length; i++) {
            if(i==0) {
                isjQueryLoaded(driver);
                root = (WebElement)((JavascriptExecutor)driver).executeScript("return document.querySelector(arguments[1]).shadowRoot", root, shadowRootSelector[i]);
            }else {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                root = (WebElement)((JavascriptExecutor)driver).executeScript("return arguments[0].querySelector(arguments[1]).shadowRoot", root, shadowRootSelector[i]);
            }
        }
        return root;
    }
    
    
    public static void isjQueryLoaded(WebDriver driver) {
       // System.out.println("Waiting for ready state complete");
        (new WebDriverWait(driver, 30)).until(new ExpectedCondition<Boolean>() {
            public Boolean apply(WebDriver driver) {
                JavascriptExecutor js = (JavascriptExecutor) driver;
                String readyState = js.executeScript("return document.readyState").toString();
                //System.out.println("Ready State: " + readyState);
                return (Boolean) js.executeScript("return !!window.jQuery && window.jQuery.active == 0");
            }
        });
    }       
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-07
      • 2014-09-06
      • 1970-01-01
      • 1970-01-01
      • 2015-03-05
      • 2014-09-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多