查找xpath并提取文本&循环中复选框/单选按钮的状态

时间:2017-12-08 11:51:46

标签: java selenium selenium-webdriver

我有一个页面,我需要从xpath中提取文本以及与文本关联的单选按钮或复选框的状态。 每个元素都包含在一个名为“c-form-group”的类中,所以我编写了一个循环来迭代以提取“Text”,这将是页面上找到的4个元素。但它在元素3& 4,我的xpath必定有问题。我还没有添加复选框/单选按钮的检查,

前两个元素返回我需要的值,然后在element3上失败。

以下是我要提取的4个文本元素:

B计划保修(出租车)&细分恢复

车辆资产保护 - 标准封面

负资产保障

您确认已收到VAP关键事实传单吗?

以下是循环的代码。

WebElement elem = driver.findElement(By.className("c-form-group"));
System.out.println("a");    
List<WebElement> elementz =  elem.findElements(By.xpath("//label[contains(@class,'c-option')]"));

for(int i = 0 ; i< elementz.size() ; i++){
    System.out.println("Loop : " + i);   
     String vapval1 = elementz.get(i).findElement(By.xpath("//label[@class='c-option c-option--right u-px u-py-sm u-clearfix ng-scope' and not(@class='ng-pristine ng-untouched ng-valid ng-valid-required') and not (@class='c-option__radio')]")).getText();
     System.out.println("0 = " + vapval1);
     String vapval2 = elementz.get(i).findElement(By.xpath("//label[@class='c-option c-option--right u-px u-py-sm u-clearfix' and not(@class='ng-pristine ng-untouched ng-valid ng-valid-required') and not (@class='c-option__radio')]")).getText();
     System.out.println("1 = " + vapval2);
     String vapval3 = elementz.get(i).findElement(By.xpath("//label[@class,'c-option c-option--right u-px u-py-sm u-clearfix ng-scope' and not(@class='ng-pristine ng-untouched ng-valid') and not (@class='c-option__checkbox')]")).getText();
     System.out.println("3 = " + vapval3);
     String vapval4 = elementz.get(i).findElement(By.xpath("//label[@class,'c-option c-option--right u-px u-py-sm u-clearfix' and not(@class='ng-pristine ng-untouched ng-valid ng-valid-required') and not (@class='c-option__checkbox')]")).getText();
     System.out.println("4 = " + vapval4);
    }

这是完整的HTML,这可能会有所帮助。

<!DOCTYPE html>
<html class="ng-scope" ng-app="dan">
<head>
<body class="u-scroll-y ng-scope" ng-controller="CoreController as cc">
<div class="c-animate c-animate--show u-pos-f-t ng-hide" ng-show="global.alerts.length">
<div class="o-grid-fluid u-h-100 u-pl-0">
<div class="o-grid__row u-ml-0 u-h-100">
<div class="c-loader ng-hide" ng-show="loadingHome" style="">
<nav class="o-grid__col-xl-2 o-grid__col-lg-3 o-grid__col-xs-4 u-p-0 c-card__block u-h-100 u-shadowed u-pos-f-t ng-scope" ng-if="global.loggedIn">
<div class="u-p-0 u-h-100 o-grid__col-xl-10 o-grid__col-lg-9 o-grid__col-xs-8 u-pull-right" ng-class="{ 'o-grid__col-xl-10 o-grid__col-lg-9 o-grid__col-xs-8 u-pull-right' : global.loggedIn }">
<header class="o-layout-table__row u-bg-primary u-shadowed u-clearfix u-px ng-scope" ng-if="global.loggedIn">
<main class="o-view-container">
<div class="o-grid-fluid u-py-md">
<div class="o-grid__row">
<div class="c-animate c-animate--view-slide-in-right c-animate--view-slide-out-right ng-scope" ng-view="" style="">
<div class="o-grid__col-md-10 o-grid__col-xl-8 o-grid__col-xl-offset-2 o-grid__col-md-offset-1 ng-scope">
<div class="u-mb-lg u-text-center">
<h1 class="u-text-bold">Recommendations</h1>
</div>
<form class="ng-valid ng-valid-min ng-valid-max ng-valid-required ng-dirty ng-valid-parse" name="recommend" ng-submit="recommend.$valid" style="">
<div class="o-media c-card c-card__block u-shadowed u-mb-lg ng-scope" ng-if="rc.WarrantyEligible && !rc.prevWarranty()">
<label class="c-form-control-label u-px u-py-sm u-w-100">Warranty Options:</label>
<div class="c-form-group u-p-0 u-mb-sm u-clearfix">
<div class="o-grid__col-md-8">
<label class="c-form-control-label u-text-normal">Product Recommendations (Years):</label>
</div>
<div class="o-grid__col-md-4">
<input class="c-form-control ng-pristine ng-untouched ng-valid ng-valid-min ng-valid-max ng-valid-required" required="" placeholder="Years" ng-model="rc.recommend.year" min="1" max="3" type="number">
</div>
</div>
<div class="c-form-group ng-scope" ng-if="data.answer_taxi">
<label class="c-option c-option--right u-px u-py-sm u-clearfix ng-scope" ng-if="!rc.planA && !rc.prestige" ng-click="cc.utils.audit('recommendation_warranty_plan_taxi_b')">
<input class="ng-pristine ng-untouched ng-valid ng-valid-required" required="" ng-model="rc.recommend.warrantyPlan" value="taxiB" name="warrantyPlan" type="radio">
<i class="c-option__radio"></i>
Plan B Warranty (Taxi) & Breakdown Recovery
</label>
</div>
</div>
<div class="o-media c-card c-card__block u-shadowed u-mb-lg u-text-body u-bg-success" ng-if="!rc.prevVap() && rc.VapEligible ">
<div class="c-form-group">
<label class="c-form-control-label u-px u-py-sm u-w-100">Vehicle Asset Protection Options:</label>
<label class="c-option c-option--right u-px u-py-sm u-clearfix" ng-click="cc.utils.audit('recommend_vap')">
<input class="ng-pristine ng-untouched ng-valid ng-valid-required" required="" ng-model="rc.recommend.vapPlan.plan" value="standard" name="vapPlan" type="radio">
<i class="c-option__radio"></i>
Vehicle Asset Protection - Standard Cover
</label>
<label class="c-option c-option--right u-px u-py-sm u-clearfix ng-scope" ng-if="data.answer_equity == true" ng-click="cc.utils.audit('recommend_negative_equity')">
<input class="ng-untouched ng-valid ng-dirty ng-valid-parse" ng-model="rc.recommend.vapPlan.equity" name="vapPlanEquity" type="checkbox" style="">
<i class="c-option__checkbox"></i>
Negative Equity Cover
</label>
<label class="c-option c-option--right u-px u-py-sm u-clearfix" ng-click="cc.utils.audit('vap_key_facts_checked')">
<input class="ng-pristine ng-untouched ng-valid ng-valid-required" required="" ng-model="rc.recommend.vapCheck" name="vapCheck" type="checkbox">
<i class="c-option__checkbox"></i>
You confirm that you have received the VAP key facts leaflet?
</label>
</div>
</div>
</form>
<div class="c-form-group">
</div>
</div>
</div>
</div>
</main>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js">
<script src="./build/app.js?v=2.13" defer="">
<script src="/build/standalone/jspdf.js" defer="">
<script src="/build/standalone/sigWebTablet.js" defer="">
</body>
</html>

1 个答案:

答案 0 :(得分:1)

我对你要做的事感到有点困惑。您提到从元素中获取文本并获取复选框的状态。外部和内部循环上的XPath重叠。您的elementz列表是从包含LABEL类的c-option中提取的,但是您从elementz开始使用元素,并在XPath的第一部分重复搜索包含LABEL类的c-option

有一种更简单的方法可以做到这一点。这些复选框/单选按钮中的每一个都是INPUT个标签,并且具有特定于其值的name

B计划保修(出租车)&amp;细分恢复:<input ... name="warrantyPlan" type="radio">

车辆资产保护 - 标准保险:<input ... name="vapPlan" type="radio">

负资产保障:<input ... name="vapPlanEquity" type="checkbox" style="">

您确认已收到VAP关键事实传单?:<input ... name="vapCheck" type="checkbox">

因此,使用该信息,您可以使用CSS选择器(例如

)获取每个INPUT
By.cssSelector("input[name='warrantyPlan']")

获得INPUT元素后,您可以使用.isSelected()检查是否已选中该元素。

如果你真的需要文字,你可以得到标签,因为它是我们刚刚得到的INPUT的父母。我们可以使用XPath By.xpath("..")来做到这一点,它获取当前元素的父级。

我们可以像

一样把这些放在一起
// Plan B Warranty (Taxi) & Breakdown Recovery
WebElement e = driver.findElement(By.cssSelector("input[name='warrantyPlan']"));
System.out.println(e.isSelected()); // false
System.out.println(e.findElement(By.xpath("..")).getText()); // Plan B Warranty (Taxi) & Breakdown Recovery

// Vehicle Asset Protection - Standard Cover
e = driver.findElement(By.cssSelector("input[name='vapPlan']"));
System.out.println(e.isSelected()); // false
System.out.println(e.findElement(By.xpath("..")).getText()); // Vehicle Asset Protection - Standard Cover

我刚做了前两个。您可以看到模式并将其应用于最后两个模式。