-1

我有一个使用以下 XPath 的自动化 Selenium 测试

"//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

我需要在左侧找到 offsetParent 的元素<td>

任何人都可以通过 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 &amp;&amp; (
                                                                    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 &amp;&amp; (
                    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 &amp;&amp; existingOptionsWG.optionQuantityWG_16.$error.max" aria-hidden="true" class="ng-hide">
            maximum of 999999999.99
        </span>
    <span ng-show="existingOptionsWG.optionQuantityWG_16.$dirty &amp;&amp; existingOptionsWG.optionQuantityWG_16.$error.min" aria-hidden="true" class="ng-hide">
            cannot be zero or less
        </span>
    <span ng-show="existingOptionsWG.optionQuantityWG_16.$dirty &amp;&amp; (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 &amp;&amp; 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>

4

1 回答 1

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()
于 2019-03-13T16:12:43.010 回答