selenium-webdriver - 使用 ShadowDom 对象在 Polymer 网页中定位 Web 元素
问题描述
我正在使用 Selenium Webdriver 和 Java 自动化网页,我遇到了在 Html 中有 shadowRoot 元素的 Polymer 网页。我无法达到所需的元素。
我需要使用 id="Contain" 和 id="callButton" 访问元素,我尝试使用网络中的示例,这些示例给了我访问的想法,但我无法访问该元素。我可以用 selenium 实现这个自动化是我需要了解的。
当我尝试动态获取页面源时,无法访问 shadow-root 下的自动化元素。
上面的快照是我检查元素的时候。动态地,如果我获取页面源,我会得到以下 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 脚本和 XPath 的组合来获得:
- 通过标记名在影子根之前的第一个元素 // 这里我使用 getElementsByTagname 来获取标记,该标记获取第二个影子根之前的标记下的所有元素。
- ' WebElement ironPages = (WebElement) jse.executeScript("return arguments[0].shadowRoot.getElementsByTagName('iron-pages')[0]", edgeCallControl); '
- 一旦我得到上述信息,我就可以根据 HTml 通过每个元素的“id”访问每个元素
获取按钮 button ,其中 Button 是 ID。` WebElement button = (WebElement) jse.executeScript("return arguments[0].shadowRoot.querySelector('#Button')", edgeManualDial);'
这个想法来自“ Shadow-dom support for selenium ”
推荐阅读
- django - 将 django 站点部署到 elasticbeanstalk:NotAuthorizedError:操作被拒绝。请求中包含的安全令牌无效
- pipe - 使用 scanf 从管道读取失败
- xml - 使用 XPath string() 从 bash 脚本中的 XML 获取属性值
- python - 如何使用 apply 将列作为参数传递给类
- neo4j - 如何将关系文件导入 Neo4j 以创建现有标签之间的关系?
- stackblitz - 安装依赖项后在 StackBlitz 中找不到包 src
- azure - Azure 自定义域计费
- javascript - 为什么方法 history.pushState() 在我的本地 HTML 中不起作用?
- node.js - NodeJs 降级问题
- android - 如何更改上下文菜单的颜色背景?