使用 ShadowDom 对象在 Polymer 网页中定位网页元素

Locating web elements in Polymer web page with ShadowDom objects

我正在使用 Selenium Webdriver 和 Java 自动化网页,我遇到了在 Html 中有 shadowRoot 元素的 Polymer 网页。我无法达到所需的要素。

我需要访问 id="Contain" 和 id="callButton" 的元素,我尝试使用网络中的示例,这让我有了访问的想法,但我无法访问到达元素。我需要了解的是我可以使用 selenium 实现自动化吗?

当我尝试动态获取页面源代码时,无法访问影子根目录下的自动化元素。

上面的快照是我检查元素时拍的。动态地,如果我获取页面源,我会得到以下 html。在这里,我在第一个 shadow-root

之后没有得到任何元素
   '  <!DOCTYPE html>
     <html lang="en">
      <head>
      <meta charset="utf-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta http-equiv="Cache-Control" content="no-cache">
      <meta http-equiv="Cache-Control" content="no-store">
      <meta name="description" content="">
      <meta name="viewport" content="width=device-width,initial- 
      scale=1,minimum-scale=0.5,maximum-scale=3,user-scalable=yes">
      <base href="/">
       <title>Title</title>
      <!--logo Favicon - http://www.favicon-generator.org/--> 
      <link rel="shortcut icon" type="image/x-icon" 
      href="./assets/img/favicon/favicon.ico"> 
      <link rel="apple-touch-icon" sizes="57x57" 
      href="./assets/img/favicon/apple-icon-57x57.png">
      <link rel="apple-touch-icon" sizes="60x60" 
      href="./assets/img/favicon/apple-icon-60x60.png">
     <link rel="apple-touch-icon" sizes="72x72" 
      href="./assets/img/favicon/apple-icon-72x72.png">
     <link rel="apple-touch-icon" sizes="76x76" 
      href="./assets/img/favicon/apple-icon-76x76.png">
      <link rel="apple-touch-icon" sizes="114x114" 
       href="./assets/img/favicon/apple-icon-114x114.png">
       <link rel="apple-touch-icon" sizes="120x120" 
       href="./assets/img/favicon/apple-icon-120x120.png">
       <link rel="apple-touch-icon" sizes="144x144" 
       href="./assets/img/favicon/apple-icon-144x144.png">
       <link rel="apple-touch-icon" sizes="152x152" 
       href="./assets/img/favicon/apple-icon-152x152.png">
       <link rel="apple-touch-icon" sizes="180x180" 
       href="./assets/img/favicon/apple-icon-180x180.png">
       <link rel="icon" type="image/png" sizes="192x192" 
       href="./assets/img/favicon/android-icon-192x192.png">
       <link rel="icon" type="image/png" sizes="32x32" 
        href="./assets/img/favicon/favicon-32x32.png">
        <link rel="icon" type="image/png" sizes="96x96" 
        href="./assets/img/favicon/favicon-96x96.png">
        <link rel="icon" type="image/png" sizes="16x16" 
         href="./assets/img/favicon/favicon-16x16.png">
        <link rel="manifest" href="./assets/img/favicon/manifest.json"> 
        <meta name="msapplication-TileColor" content="#ffffff">
        <meta name="msapplication-TileImage" 
         content="./assets/img/favicon/ms-icon-144x144.png">
        <meta name="theme-color" content="#ffffff">
         <!--End of Favicon section--><!-- Web Fonts -->
         <link href="https://fonts.googleapis.com/css? 
           family=Roboto&subset=latin,latin-ext" rel="stylesheet" 
          type="text/css">
         <link href="styles.6818abb062a6ae399f29.bundle.css" 
         rel="stylesheet"/>
         </head>
         <body>
         <app-login>
         <!--Inline style for loading screen--><style>body, html {
        height: 100%;
        background: #FAFAFA;
    }

    @keyframes spinner {
        to {transform: rotate(360deg);}
    }

    .spinner:before {
        content: '';
        box-sizing: border-box;
        position: absolute;
        top: 50%;
        left: 50%;
        width: 100px;
        height: 100px;
        margin-top: -50px;
        margin-left: -50px;
        border-radius: 50%;
        border: 1px solid #CDCDCD;
        border-top-color: #0277BD;
        animation: spinner .6s linear infinite;
    }

    .app-loading {
        position: relative;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        height: 100%;
       }
       </style>
       <div class="app-loading">
       <div class="spinner">
       </div>
       </div>
       </app-login>
       <script type="text/javascript" 
       src="inline.318b50c57b4eba3d437b.bundle.js"></script>
       <script type="text/javascript" 
       src="polyfills.9a4f082a49343f8da8e1.bundle.js"></script>
       <script type="text/javascript" 
       src="scripts.ccb2e44daa4fd4db3422.bundle.js"></script>
       <script type="text/javascript" 
       src="main.aacb992b6c008772ed3d.bundle.js"></script>
       </body>
       </html>`

我结合使用了 Java 脚本和 XPaths 来获得 :

  1. 标记名影子根之前的第一个元素 // 在这里,我使用 getElementsByTagname 获取标签,该标签获取标签下的所有元素,该标签就在第二个影子根之前。
  2. ' WebElement ironPages = (WebElement) jse.executeScript("return 参数[0].shadowRoot.getElementsByTagName('iron-pages')[0]", 边缘呼叫控制); '
  3. 一旦我得到上述内容,我就可以根据 HTml
  4. 通过每个元素的 "id" 访问每个元素

获取按钮button,其中Button为ID。 ` WebElement 按钮 = (WebElement) jse.executeScript("return arguments[0].shadowRoot.querySelector('#Button')", edgeManualDial);'

我的想法来自“Shadow-dom support for selenium