Capybara - Clicking a link based another value - html

I'm in a bit of a struggle with finding and clicking a specific link.
All links in a HTML table contain the word 'Edit' (it's an 'Edit' link for a configuration setting).
However, the link varies per environment I'm working on, so only the 'Edit' bit of the link is consistent.
In the HTML of the page, I found that this link is part of a table also containing the configuration setting that I want to edit.
I've been struggling for a few hours now to find this link through Xpath, through CSS... Basically I need someone's help on this. Hence my post here!
The HTML of the page looks like this (I anonymized it -- is that even a word?):
<table>
<thead>
<tr>
<th>edit</th>
<th>Name</th>
<th>Value</th>
<th>Label</th>
</tr>
</thead>
<tbody>
<tr>
<td>Edit</td>
<td>Configuration 1</td>
<td>This is its value</td>
<td>This is its explanation</td>
</tr>
<tr>
<td>Edit</td>
<td>Configuration 2</td>
<td>This is its value</td>
<td>This is its explanation</td>
</tr>
<tr>
<td>Edit</td>
<td>Configuration 3</td>
<td>This is its value</td>
<td>This is its explanation</td>
</tr>
</tbody>
</table>
Can someone please give me some pointers as to how I can get to each 'Edit' link, based on the 'configuration'?
Thanks a lot in advance. It will really save me a headache!

You can scope Capybaras finds and actions to other elements, therefore
find(:css, 'tr', text: 'Configuration 2').click_link('Edit')
would click the edit link inside the tr that includes the text 'Configuration 2'

Related

Make screen reader to read only the row that changed when all table is reloaded

I have a table with multiple rows and columns. This table as a whole is reloaded by AJAX once in a while. When the table is reloaded, I want to inform screen reader users only about data that changed.
Going further, when there is a change in any cell, the screen reader should read the whole row to the user.
Furthermore - if a new row is added, it also should be read to the user as a whole.
What is the proper aria attributes that should be added and on which tags?
Extra: there also is a column, I don't want to be considered when looking for changes in the aria-live zone. But this cell should still be read if any other cell in the row changes.
Below is an example of code, I hoped to work, but instead of reading only changes, it reads the whole table after each reloads of the table.
<table>
<tr>
<th>Address</th>
<th>Room</th>
<th>State</th>
<th>Time</th>
</tr>
<tr aria-live="polite" aria-atomic="true">
<td>Street 1</td>
<td>Living room</td>
<td>ON</td>
<td aria-live="off">12:45</td>
</tr>
<tr aria-live="polite" aria-atomic="true">
<td>Street 1</td>
<td>Bedroom</td>
<td>OFF</td>
<td aria-live="off">14:06</td>
</tr>
<tr aria-live="polite" aria-atomic="true">
<td>Street 2</td>
<td>Living room</td>
<td>ON</td>
<td aria-live="off">19:59</td>
</tr>
</table>

Why do VoiceOver speaks out the first col of a html table-header?

Good evening clever people,
I have a html table with the following structure:
<thead>
<tr>
<th>title</th>
<th>title1</th>
<th>title2</th>
</tr>
</thead>
<tbody>
<tr>
<td>hello</td>
<td>hello1</td>
<td>hello2</td>
</tr>
</tbody>
When I try VoiceOver on this table in a WebView i become a strange result. If if click on the title2 column VoiceOver speaks out "title" and "title2". I don't know why but it reads out the first col of the header row too.
Can i avoid this?
Thank you & have a nice Day!

HTML Tables - can I have an additional tbody before the thead?

I need add to some elements on top of a table in line with the columns of the said table.
This table contains a <thead> (which is required due to jquery.tablesorter plugin). I assumed that if I put another <tbody> on top of the <thead> I would be able to keep these elements in line with the rest of the columns, but both chrome and firefox render every <tbody> below the <thead>.
Example:
<table>
<tbody>
<tr>
<td>1</td><td>1</td><td>1</td>
</tr>
</tbody>
<thead>
<tr>
<th>head</th><th>head</th><th>head</th>
</tr>
</thead>
<tbody>
<tr>
<td>2</td><td>2</td><td>2</td>
</tr>
<tr>
<td>3</td><td>3</td><td>3</td>
</tr>
<tr>
<td>4</td><td>4</td><td>4</td>
</tr>
</tbody>
</table>
Although I understand this, I still need to find a way to have these elements stay in line with specific columns.
You can use multiple rows in <thead> like this:-
<table>
<thead>
<tr> <td>1</td> <td>1</td> </tr>
<tr> <td>head</td> <td>head</td> </tr>
</thead>
</table>
I recommend that you use an id (#) marker to identify that part that you want the js to work off and have the js use that id.
With that, have the thead first and the tbody last.
The variations you are describing may work - in the browser you using now, on the OS you are ok - and may be compliant a certain version of the HTML spec- but putting things in an unusual order is (in my expereince) just the kind of thing to not work, or work the same, everywhere and to eventually be the cause of much frustration, especially as the site grows in complexity.
One solution is to use another table inside one tr, in your thead. Althought, this is a totally ugly solution.
You can also place a div above your table using CSS.
Correct table structure is:
<table>
<thead>
<tr>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
</tr>
</tbody>
<tfoot>
<tr>
<th></th>
<th></th>
</tr>
</tfoot>
</table>
<thead> will always be on the top and <tfoot> will always be at the bottom.
Using jQuery you can swap <thead> and <tbody> content by:
$(document).ready(function() {
$('#myTrigger').click(function() {
var top = $('thead').html();
var mid = $('tbody').html();
$('thead').html(mid);
$('tbody').html(top);
});
});

Skip <td> in HTML table

Say I have the following table:
<table>
<tr>
<td>Example</td>
</td>One</td>
</tr>
<tr>
<td>Example</td>
</td>Two</td>
</tr>
<tr>
<td>Example</td>
</td>Three</td>
</tr>
<tr>
<!--
Here I want to skip the first <td> cell; use only second. Example:
<td>(empty, possibly )</td>
<td>blah blah blah</td>
-->
</tr>
</table>
If you read my comment in the last row, you can see that in the last row I want to display something in the second column of the table, with the first remaining empty. How would I go about doing this?
As a side note, I read the question/answers in this SO question but colspan is different from what I want. I'm also not familiar with css empty-cell so if that is a solution, please provide a bit of sample code.
HTML
<tr>
<td></td>
<td>content here</td>
</tr>
CSS
table { empty-cells: show;}
Leave the <td> empty, no reason to put a space in there. can act a bit funny at times, especially in tables.
I can't see any reason not to do exactly what you are proposing: Use an empty cell containing only a ("No Break Space") in it:
<tr>
<td> </td>
<td>Whatever</td>
</tr>
CSS code:
table { empty-cells: show; }
Or, alternatively, you can insert in the <td>.

strucure of component inside table html

I want to make a table of orders, for each row there's an arrow that show a bill details related to each order and hide when I click again on the button.
How can I make the structure of the table?
I make like this
<table id="customerTable">
<thead>
<tr>
<td>customer name </td>
<td>order date</td>
<td>sale point</td>
<td>total</td>
</tr>
</thead>
<tr>
<td>customer name </td>
<td>order date</td>
<td>sale point</td>
<td>total</td>
<td>show details</td>
</tr>
//also loop here as the number of bills
<tr>
<td>bill order/td>
<td>product</td>
<td>price</td>
</tr>
I don't think like this structure is correct, and making div inside a table doesn't work, any suggestion please?
Possible structure:
<table id="customerTable">
<thead>
<tr>
<td>customer name </td>
<td>order date</td>
<td>sale point</td>
<td>total</td>
<td></td>
</tr>
</thead>
<tbody>
<tr class="master">
<td>customer name </td>
<td>order date</td>
<td>sale point</td>
<td>total</td>
<td>
show details
</td>
</tr>
<tr class="detail">
<td colspan=5>
<!-- new <table> with your details of this row -->
</td>
</tr>
<!-- ... more rows ... --->
</tbody>
</table>
Example: http://jsfiddle.net/J7szf/
Example 2: http://jsfiddle.net/J7szf/1/
You can probably use a popup near the "Show Details" Link
Example : http://jsfiddle.net/vdcUA/93/
If you want the content to be displayed in the table itself , provide here some idea on how u want the content displayed
In your example, you have an extra unneeded <tr> before your loop. You should have a standard table structure but hide / show the details depending on a click.
You'd better use:
styling with css and classes the standard row and the details
using js to hide / show rows
Actually, you could use jquery plugins to do this kind of stuff. See this example of datatables grouping rows
Jqgrid can also make some row grouping
[EDIT] The easiest way to define your HTML structure is to get inspired from the HTML in these jquery plugin examples