Reputation: 872
I have a table and I want only to select the buttons on that table. As we can see, there are only 4 buttons on this table:
I have created the following Xpath to filter out these 4 buttons, and no other button on the page:
//*[@id="studentListTable"]/thead/tr/th[contains(., "Actions")]//following::button | //*[@id="studentListTable_info"]//preceding::button
But this is not working.
This XPath is actually locating all the buttons on the page irrespective of the buttons location.
What is wrong here?
How can I fix it so that only the four buttons are located by this expression?
The HTML snippet :
<div _ngcontent-c7="" appcard="" class="card">
<div _ngcontent-c7="" class="card-header">
<h5 _ngcontent-c7="">Student list <!----></h5></div>
<ul _ngcontent-c7="" class="card-actions">
<li _ngcontent-c7="">
<button _ngcontent-c7="" appcardfullscreen="" class="card-action">
<i _ngcontent-c7="" class="fa fa-arrows-alt"></i></button></li>
<li _ngcontent-c7="">
<button _ngcontent-c7="" appcardcollapse="" class="card-action icon-collapse"><i _ngcontent-c7="" class="material-icons">expand_more</i></button></li></ul>
<!---->
<div _ngcontent-c7="" class="card-body">
<div id="studentListTable_wrapper" class="dataTables_wrapper no-footer">
<div class="dataTables_length" id="studentListTable_length">
<label>Show <select name="studentListTable_length" aria-controls="studentListTable" class="">
<option value="10">10</option>
<option value="25">25</option>
<option value="50">50</option><option value="100">100</option>
</select> entries</label></div>
<div id="studentListTable_filter" class="dataTables_filter">
<label>Search:<input type="search" class="" placeholder="" aria-controls="studentListTable"></label>
</div>
<table _ngcontent-c7="" class="table table-striped dataTable no-footer" datatable="" id="studentListTable" role="grid" aria-describedby="studentListTable_info">
<thead _ngcontent-c7="">
<tr _ngcontent-c7="" role="row">
<th _ngcontent-c7="" class="sorting_asc" tabindex="0" aria-controls="studentListTable" rowspan="1" colspan="1" aria-sort="ascending" aria-label="Student ID: activate to sort column descending" style="width: 101px;">Student ID</th>
<th _ngcontent-c7="" class="sorting_disabled" rowspan="1" colspan="1" aria-label="Actions" style="width: 106px;">Actions</th></tr>
</thead><!----><tbody _ngcontent-c7=""><!---->
<tr _ngcontent-c7="" role="row" class="odd">
<td _ngcontent-c7="" class="sorting_1">123456</td>
<td _ngcontent-c7="">
<a href="unsafe:javascript:void(0)">
<i class="material-icons text-warning">info</i> Not Started</a></td>
<td _ngcontent-c7="">Null</td>
<td _ngcontent-c7="" class="text-left"><!----><div _ngcontent-c7="">
<button _ngcontent-c7="" class="btn btn-sm btn-sm-action mr-2 btn-outline-info" container="body" placement="left" popoverclass="btn-popover" triggers="mouseenter:mouseleave" type="button" tabindex="0">
<i _ngcontent-c7="" class="fa fa-arrow-right"></i></button></div><!----><!----><!----></td></tr>
<tr _ngcontent-c7="" role="row" class="even">
<td _ngcontent-c7="" class="sorting_1">153246</td>
<td _ngcontent-c7=""><a href="unsafe:javascript:void(0)"><i class="fa fa-unlock mr-2"></i>In Progress</a></td>
<td _ngcontent-c7="">Herndon MS</td>
<td _ngcontent-c7="" class="text-left"><!----><!----><div _ngcontent-c7=""><!----><div _ngcontent-c7="" class="d-flex align-items-center">
<button _ngcontent-c7="" class="btn btn-sm btn-sm-action mr-2 btn-outline-info col" container="body" placement="left" popoverclass="btn-popover" triggers="mouseenter:mouseleave" type="button" tabindex="0">
<i _ngcontent-c7="" class="fa fa-pencil"></i></button>
<button _ngcontent-c7="" class="btn btn-sm btn-sm-action mr-2 btn-outline-danger col" container="body" placement="left" popoverclass="btn-popover" triggers="mouseenter:mouseleave" type="button">
<i _ngcontent-c7="" class="fa fa-trash-o"></i></button></div><!----></div><!----><!----></td></tr>
<tr _ngcontent-c7="" role="row" class="odd">
<td _ngcontent-c7="" class="sorting_1">234135</td>
<td _ngcontent-c7="" class="text-left"><!----><!----><!---->
<div _ngcontent-c7="">
<button _ngcontent-c7="" class="btn btn-sm btn-sm-action mr-2 btn-outline-info" container="body" placement="left" popoverclass="btn-popover" triggers="mouseenter:mouseleave" type="button" tabindex="0">
<i _ngcontent-c7="" class="fa fa-eye"></i></button></div><!----></td></tr></tbody><!----><!----><!----></table>
<div class="dataTables_info" id="studentListTable_info" role="status" aria-live="polite">Showing 1 to 3 of 3 entries</div>
<div class="dataTables_paginate paging_simple_numbers" id="studentListTable_paginate">
<a class="paginate_button previous disabled" aria-controls="studentListTable" data-dt-idx="0" tabindex="0" id="studentListTable_previous">Previous</a>
<span>
<a class="paginate_button current" aria-controls="studentListTable" data-dt-idx="1" tabindex="0">1</a>
</span>
<a class="paginate_button next disabled" aria-controls="studentListTable" data-dt-idx="2" tabindex="0" id="studentListTable_next">Next</a></div></div></div></div>
Upvotes: 1
Views: 855
Reputation:
You can select buttons by Student Id
using below xpath as example with 153246
id:
//table[@id='studentListTable']//tr[@role='row' and ./td[@class='sorting_1' and .='153246']]//button
Upvotes: 0
Reputation: 25611
The BUTTON
s you want are the only buttons inside the table and the table has an ID, studentListTable
, so all you need are the children BUTTON
s of the ID.
From the HTML you have provided, something simple like the below will work.
XPath
//[@id='studentListTable']//button
CSS selector
#studentListTable button
Upvotes: 0
Reputation: 193108
A few points:
class="odd"
class="even"
To filter out these 4 buttons you can use the following XPath based solution:
"//table[@class='table table-striped dataTable no-footer' and @id='studentListTable']//tbody//tr[@class= 'odd' or @class='even']//td[@class='text-left']//button"
A snapshot of the matching result through xpath checker:
Note: You havn't mentioned the language binding you are using so as the elements are Angular elements to locate the element you have to induce WebDriverWait for the element to be clickable.
Upvotes: 2
Reputation: 89285
If I understand this correctly, the title means you want combine the 2 attempted XPath expressions to get buttons that is located after th
containing text "Actions" and before div
with id "studentListTable_info" :
//*[@id="studentListTable"]/thead/tr/th[contains(., "Actions")]//following::button[
following::*[@id="studentListTable_info"]
]
Upvotes: 0
Reputation: 18582
Difficult to answer your first question what is wrong there.
You are using some |
and two different id
s and maybe it isn't fully correct.
And you used thead
element in your Xpath. Despite the fact that all buttons located at tbody
.
Anyway, your locator gets all HTML buttons from that page.
I tried to modify Xpath to following:
//table//button
And it worked well:
However, it isn't very good Xpath.
So try to bind it to some nearest id
. After update it can be like:
//div[@id='studentListTable_wrapper']//table//button
The result of the evaluation is the same.
And much more redundant version will be (not recomended to use, just for example reason):
//div[@id='studentListTable_wrapper']//table/tbody/tr/td/div//button
BTW to my opinion much better is to use locators like:
//div[@id='...']
instead of:
//*[...]
Difficult to see if it can be the reason of incorrect select.
For sure it is much more readable and easier to understand in the future support.
Upvotes: 2
Reputation: 29022
You can use the following XPath-1.0 expression:
//table[@id="studentListTable" and thead/tr/th/text() = "Actions"]/tbody/tr/td[@class="sorting_1"]
to select the following three items:
<td _ngcontent-c7="" class="sorting_1">123456</td>
<td _ngcontent-c7="" class="sorting_1">153246</td>
<td _ngcontent-c7="" class="sorting_1">234135</td>
To proceed further to get the four button
s contained in these three table
s, the following XPath will do:
//table[@id="studentListTable" and thead/tr/th/text() = "Actions"]/tbody/tr/td[@class="sorting_1"]/../../tr/td//button
Its result consists of the following four items:
<button ... type="button" tabindex="0">
<i _ngcontent-c7="" class="fa fa-arrow-right"/>
</button>
<button ... type="button" tabindex="0">
<i _ngcontent-c7="" class="fa fa-pencil"/>
</button>
<button ... type="button">
<i _ngcontent-c7="" class="fa fa-trash-o"/>
</button>
<button ... type="button" tabindex="0">
<i _ngcontent-c7="" class="fa fa-eye"/>
</button>
Upvotes: 2