如何使用Geb单击特定的表行

时间:2017-07-18 15:21:38

标签: geb

我是Geb的新手,我正在尝试点击特定的表格列/行。

例如,我想找到并点击名为"删除"的链接。对于名为foo的行。当然,没有表id类或名称可供选择,以使这更具挑战性。任何帮助表示赞赏

My Table

== HTML for table ==

<div class="k-grid-header-wrap">
<table role="grid">
<colgroup>
<thead role="rowgroup">
<tr role="row">
<th id="564a14e5-657d-4dd4-babe-0d13d56fb7d1" class="k-header ng-scope" data-index="0" data-title="Criteria Name" rowspan="1" data-field="name" role="columnheader" data-role="columnsorter">
<a class="k-link">Criteria Name</a>
</th>
<th id="4f9e5c37-ac63-4e2b-a4ba-a8c5d3673179" class="k-header ng-scope" data-index="1" data-title="Start Date" rowspan="1" data-field="startDateTime" role="columnheader" data-role="columnsorter">
<th id="25ef77e5-6d6e-4376-9bf2-fea1becfabe9" class="k-header ng-scope" data-index="2" data-title="End Date" rowspan="1" data-field="endDateTime" role="columnheader" data-role="columnsorter">
<th id="41725a3a-d62e-43e2-ac81-5008da54ca74" class="k-header ng-scope" data-index="3" data-title="Location Name(s)" rowspan="1" data-field="locationNames" role="columnheader" data-role="columnsorter">
<th id="7c719826-0c9a-4751-bf64-344e0885e237" class="k-header ng-scope" data-index="4" data-title="Classification(s)" rowspan="1" data-field="classifNames" role="columnheader" data-role="columnsorter">
<th id="d7abbc0a-ea63-4b2f-8c79-44ca133d2e85" class="k-header ng-scope" data-index="5" data-title="Employee Name(s)" rowspan="1" data-field="empNames" role="columnheader" data-role="columnsorter">
<th id="17a9317e-30f5-4a30-8822-ff3b302e0071" class="k-header ng-scope" data-index="6" rowspan="1" role="columnheader"></th>
<th id="c2f499a2-fffa-4994-98f4-833e4d844cfc" class="k-header ng-scope" data-index="7" rowspan="1" role="columnheader"></th>
</tr>
</thead>
</table>
</div>
<div class="k-grid-content">
<table role="grid">
<colgroup>
<tbody role="rowgroup">
<tr class="ng-scope" role="row" data-uid="dc5a6a0e-7fec-45d7-9978-25e9af65bbd7">
<tr class="k-alt ng-scope" role="row" data-uid="aee1377f-0c41-4e6e-9054-25cbb564cb00">
<td role="gridcell">
<span class="ng-binding" ng-bind="dataItem.name">Crit_12_30_17</span>
</td>
<td role="gridcell">12/4/2017 12:00 AM</td>
<td role="gridcell">12/29/2017 11:59 PM</td>
<td role="gridcell">
<td role="gridcell">
<td role="gridcell">
<td role="gridcell">
<span>
<a ng-click="selectCriteria($event)" style="cursor: pointer;">Select Criteria</a>
</span>
</td>
<td role="gridcell">
<span>
<a ng-click="deleteCriteria(683)" style="cursor: pointer;">Delete</a>
</span>
</td>
</tr>
<tr class="ng-scope" role="row" data-uid="309c009d-08a8-4a7c-bb2c-fef5a295e72d">
<td role="gridcell">
<span class="ng-binding" ng-bind="dataItem.name">my_saved_criteria</span>
</td>
<td role="gridcell">7/18/2017 6:32 AM</td>
<td role="gridcell">7/21/2017 6:32 AM</td>
<td role="gridcell">
<td role="gridcell">
<td role="gridcell">
<td role="gridcell">
<span>
<a ng-click="selectCriteria($event)" style="cursor: pointer;">Select Criteria</a>
</span>
</td>
<td role="gridcell">
<span>
<a ng-click="deleteCriteria(729)" style="cursor: pointer;">Delete</a>
</span>
</td>
</tr>
<tr class="k-alt ng-scope" role="row" data-uid="fabed2df-b5c6-45dd-8595-e411e70c6594">
<td role="gridcell">
<span class="ng-binding" ng-bind="dataItem.name">foo</span>
</td>
<td role="gridcell">7/18/2017 12:00 AM</td>
<td role="gridcell">7/19/2017 11:59 PM</td>
<td role="gridcell">
<td role="gridcell">
<td role="gridcell">
<td role="gridcell">
<span>
<a ng-click="selectCriteria($event)" style="cursor: pointer;">Select Criteria</a>
</span>
</td>
<td role="gridcell">
<span>
<a ng-click="deleteCriteria(730)" style="cursor: pointer;">Delete</a>
</span>
 </td>
</tr>
</tbody>
</table>

2 个答案:

答案 0 :(得分:1)

作为另一个答案的替代方案,请考虑使用Module对表进行建模,并使用moduleList来收集所有行。

import geb.Module
import geb.Page

class MyPage extends Page {

    static at = {
        title == "whatever"
    }

    static content = {

        savedCriteriaTable { $(".k-grid-content > table") }
        tableRows { savedCriteriaTable.$('tbody > tr').moduleList(TableRows) }
    }

    static def findAndDeleteRow(String textToFind){

        def row = tableRows.findResult { it.criteriaName == textToFind ? it : null}
        row.deleteLink.click()
    }
}

class TableRows extends Module
{
    static content = {
        cell { $("td") }
        criteriaName { cell[0].text() }
        startDate { cell[1].text() }
        endDate { cell[2].text() }
        locationName { cell[3].text() }
        classifications { cell[4].text() }
        employeeName { cell[5].text() }
        selectCriteriaLink { cell[6].$("a") }
        deleteLink { cell[7].$("a") }
    }
}

例如,调用findAndDeleteRow(&#34; Criteria651&#34;)应该单击相应行的删除链接。

虽然我已经尝试将代码与您的HTML进行匹配,但我没有对其进行测试,猜测您可能需要稍微调整一下。

答案 1 :(得分:0)

有多种方法可以做你想做的事情,但在处理桌子时,我倾向于采用这种方法:

这就是为这个页面创建一个结构良好的页面Object类。

class YourPage extends Page{
    static content = {
        //first start by defining the table Navigator (you don't have to use xpath like I did)
        table {$(By.xpath("//table")}
    }

    //next I make a set of Table access methods like so (you may need to adjust for your case, but the idea still remains):

    //grabs a table row based on index
    getRow(int index){
        return table.children().getAt(index)
    }

    //You can do the same thing as above, but based on text instead:
    getRow(String name){
        return table.children().find{ it.text() == name } 
    }

    //next I typically make methods to access a particular column given a row like so:
    getCriteriaName(row){
        return row.children().getAt(0)
    }

    getStartData(row){
        return row.children().getAt(1)
    }

    //following this pattern, to get the delete element of a given row would be:
    getDeleteButton(row){
        return row.children().getAt(7)
    }
}

现在从你的主脚本中,如果你想点击该特定行的特定删除按钮,你会说:

at YourPage
getDeleteButton(getRow(3)).click()

现在我没有太仔细地查看你的HTML,就像我说的那样,你可能需要在索引匹配之前删除Headers,但通常Tables会遵循相同的模式,如果你这样做,你可以访问表格中的任何元素都很容易。