Protractor:如何通过svg或ng-click定位并点击目标元素?
如何定位并点击这个编辑机会的元素?
我尝试点击以下HTML元素:
<a ng-click="vm.showEditOpportunity(3122)" class="btn btn-sm"> <svg class="svg-inline--fa fa-pencil-alt fa-w-16" style="color: #4b286d;" data-toggle="tooltip" title="Edit this Opportunity" aria-labelledby="svg-inline--fa-title-381" data-prefix="fas" data-icon="pencil-alt" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" data-fa-i2svg=""> <title id="svg-inline--fa-title-381">Edit this Opportunity</title> <path fill="currentColor" d="M497.9 142.1l-46.1 46.1c-4.7 4.7-12.3 4.7-17 0l-111-111c-4.7-4.7-4.7-12.3 0-17l46.1-46.1c18.7-18.7 49.1-18.7 67.9 0l60.1 60.1c18.8 18.7 18.8 49.1 0 67.9zM284.2 99.8L21.6 362.4.4 483.9c-2.9 16.4 11.4 30.6 27.8 27.8l121.5-21.3 262.6-262.6c4.7-4.7 4.7-12.3 0-17l-111-111c-4.8-4.7-12.4-4.7-17.1 0zM124.1 339.9c-5.5-5.5-5.5-14.3 0-19.8l154-154c5.5-5.5 14.3-5.5 19.8 0s5.5 14.3 0 19.8l-154 154c-5.5 5.5-14.3 5.5-19.8 0zM88 424h48v36.3l-64.5 11.3-31.1-31.1L51.7 376H88v48z </path> </svg> </a>
我试了下面几种方法,但都失败了,报错信息是no element found using locator: XXXXXX:
element(by.css('[ng-click="vm.showEditOpportunity(3122)"]')).click(); element(by.xpath("//a[contains(text(),'vm.showEditOpportunity(3122)')]")).click(); element(by.xpath("//svg[@title='Edit this Opportunity']")).click();
请问正确的点击该元素的方法是什么?
问题分析与解决方案
先拆解下你之前尝试的定位为什么失效:
- 第一个CSS选择器本身语法没问题,但大概率是元素还没加载完成,或者嵌套在iframe里,导致找不到;
- 第二个XPath完全找错了方向——你用
contains(text(),...)是找a标签的文本内容包含这段ng-click代码,但这段是属性值,不是文本,肯定匹配不到; - 第三个XPath的问题在于:SVG的
title是内部的<title>子元素,不是svg自身的属性,所以@title根本取不到值,自然定位失败。
下面给你几个靠谱的解决方案,按优先级排序:
方案1:用CSS选择器+显式等待(最推荐)
动态页面里,元素加载需要时间,一定要先等元素可点击再操作,这是最常见的“找不到元素”的原因:
// 先引入ExpectedConditions(Protractor自带) const EC = protractor.ExpectedConditions; // 定位元素,加上class缩小范围更精准 const editButton = element(by.css('a.btn.btn-sm[ng-click="vm.showEditOpportunity(3122)"]')); // 等待元素可点击,最多等待10秒 browser.wait(EC.elementToBeClickable(editButton), 10000); editButton.click();
方案2:通过SVG的aria属性定位父级a标签
你的SVG有aria-labelledby="svg-inline--fa-title-381"这个唯一属性,可以通过它找到父级的a标签:
const EC = protractor.ExpectedConditions; const editButton = element(by.xpath("//svg[@aria-labelledby='svg-inline--fa-title-381']/parent::a")); browser.wait(EC.elementToBeClickable(editButton), 10000); editButton.click();
方案3:通过图标class组合定位
如果ng-click的参数(比如3122)可能动态变化,用图标class+按钮class定位更稳定:
const EC = protractor.ExpectedConditions; // 直接点击图标所在的a标签 const editButton = element(by.css('a.btn.btn-sm > svg.fa-pencil-alt')); browser.wait(EC.elementToBeClickable(editButton), 10000); editButton.click();
额外排查要点
- 如果元素在iframe内:需要先切换到iframe,操作完再切回主文档:
// 替换成你的iframe的id/name/定位器 browser.switchTo().frame('opportunityIframe'); // 执行点击操作 // ... // 切回主文档 browser.switchTo().defaultContent(); - 如果页面有多个相同的编辑按钮:用
element.all()获取所有匹配元素,再取对应索引:const editButtons = element.all(by.css('[ng-click*="showEditOpportunity"]')); browser.wait(EC.elementToBeClickable(editButtons.get(0)), 10000); // 索引0是第一个按钮,按需调整 editButtons.get(0).click(); - 检查是否有加载遮罩:如果页面有loading层覆盖元素,需要先等待遮罩消失再点击。
内容的提问来源于stack exchange,提问作者user2683029
相关产品推荐
相关产品推荐

