我有一个自动的Selenium测试,它使用以下XPath
"//tr[td/strong='Riparian 2m Ungrazed - RBS' and td/button[@id='btnDeleteOption_WG']]"
当前,每当查询此XPath时,它都会返回所需的元素,但还会返回另一个不在屏幕上的隐藏元素。
我已经比较了这两个元素,唯一的区别是以下内容
offsetHeight: 39 offsetHeight: 0
offsetLeft: 8 offsetLeft: 0
offsetParent: td offsetParent: null
offsetTop: 10 offsetTop: 0
offsetWidth: 179 offsetWidth: 0
我需要在左侧找到<td>
的offsetParent元素。
任何人都可以通过XPath帮助找到它吗?
谢谢!
下面是元素的HTML
<td class="text-center" style="white-space: nowrap;">
<button id="btnShowItems_WG" class="btn btn-sm btn-primary" ng-disabled="!WG_field.optionHasItems" ng-click="WG_field.optionHasItems ? items.visible = !items.visible : false;" title="View Items" disabled="disabled">
<span class="glyphicon glyphicon-list"></span>
</button>
<button ng-hide="!efsEditRole_RoleAssignedToUser" ng-disabled="false" id="btnAddOptionItem_16_WG" class="btn btn-primary btn-sm" ng-click="appSummaryVm.addItem($index, 'WG'); appSummaryVm.addItemsByOption(WG_field.fieldId, WG_field.tranche, WG_field.optionCode, WG_field.optionTypeId, $index, 'WG');"
title="Add Item" aria-hidden="false">
<span class="glyphicon glyphicon-plus"></span>
</button>
</td>
<td><strong>Riparian 2m Ungrazed - RBS</strong></td>
<td style="width: 10%;">
<input name="optionQuantityWG_16" type="number" class="form-control ng-pristine ng-untouched ng-valid ng-not-empty ng-valid-min ng-valid-max ng-valid-required ng-valid-pattern" ng-class="{
'form-control input-error' : (existingOptionsWG.optionQuantityWG_16.$dirty && (
existingOptionsWG.optionQuantityWG_16.$error.max
|| existingOptionsWG.optionQuantityWG_16.$error.min
|| existingOptionsWG.optionQuantityWG_16.$error.pattern
|| existingOptionsWG.optionQuantityWG_16.$invalid
|| existingOptionsWG.optionQuantityWG_16.$error.required
))
}" ng-change="appSummaryVm.updateOptionTotals(WG_field, 'WG'); appSummaryVm.edit();" ng-model="WG_field.optionQuantity" ng-pattern="/^\d+(\.\d{1,2})?$/" min="" max="" step="0.01" style="text-align: right;" ng-true-value="10.00"
required="" id="optionWGW0316" ng-disabled="!efsEditRole_RoleAssignedToUser" aria-invalid="false">
<div class="form-control inline-errorUp ng-hide" ng-show="existingOptionsWG.optionQuantityWG_16.$dirty && (
existingOptionsWG.optionQuantityWG_16.$error.max
|| existingOptionsWG.optionQuantityWG_16.$error.min
|| existingOptionsWG.optionQuantityWG_16.$error.pattern
|| existingOptionsWG.optionQuantityWG_16.$error.required
|| existingOptionsWG.optionQuantityWG_16.$invalid
)" aria-hidden="true">
<span ng-show="existingOptionsWG.optionQuantityWG_16.$dirty && existingOptionsWG.optionQuantityWG_16.$error.max" aria-hidden="true" class="ng-hide">
maximum of 999999999.99
</span>
<span ng-show="existingOptionsWG.optionQuantityWG_16.$dirty && existingOptionsWG.optionQuantityWG_16.$error.min" aria-hidden="true" class="ng-hide">
cannot be zero or less
</span>
<span ng-show="existingOptionsWG.optionQuantityWG_16.$dirty && (existingOptionsWG.optionQuantityWG_16.$error.pattern || existingOptionsWG.optionQuantityWG_16.$invalid)" ng-hide="existingOptionsWG.optionQuantityWG_16.$error.max || existingOptionsWG.optionQuantityWG_16.$error.min || existingOptionsWG.optionQuantityWG_16.$error.required"
aria-hidden="false" class="">
2 decimal digits only
</span>
<span ng-show="existingOptionsWG.optionQuantityWG_16.$dirty && existingOptionsWG.optionQuantityWG_16.$error.required" aria-hidden="true" class="ng-hide">
required
</span>
</div>
</td>
<td class="text-right">6.00
<!----><span ng-if="WG_field.optionUnitType">/</span>
<!---->m</td>
<td class="text-right">60.00</td>
<td class="text-right">0.70</td>
<td class="text-right">96.00</td>
<td class="text-center">
<button ng-hide="!efsEditRole_RoleAssignedToUser" ng-disabled="false" id="btnDeleteOption_WG" class="btn btn-warning btn-sm" style="width: 110px;" ng-click="appSummaryVm.showRemovePrompt(WG_field, 'option', 'WG', $event); appSummaryVm.edit();" title="Delete 'Riparian 2m Ungrazed' Option from field 3/003/003/3"
aria-hidden="false">
<span class="glyphicon glyphicon-trash"></span> remove option
</button>
</td>
答案 0 :(得分:1)
您可以获取所有元素,并根据可见性对其进行过滤。下面是一个Java代码示例,说明如何从Web元素列表中获取第一个可见元素。
使用Java 8:
List<WebElement> elements = driver.findElements(By.xpath("//tr[td/strong='Riparian 2m Ungrazed - RBS' and td/button[@id='btnDeleteOption_WG']]"));
WebElement element = elements
.stream()
.filter(WebElement::isDisplayed)
.collect(Collectors.toList())
.get(0);
Python:
elements = driver.find_elements_by_xpath("//tr[td/strong='Riparian 2m Ungrazed - RBS' and td/button[@id='btnDeleteOption_WG']]")
visible_one = list(filter(lambda x: x.is_displayed(), elements))[0]
visible_one.click()