Selenium cannot click onto table row even though manually it works - python-3.x

My page has a table. The rows get dynamically loaded into the table through an API call. A row in the finished table looks like this
<tr class="ant-table-row ant-table-row-level-0" data-row-key="0">
<td class="">Value1</td>
<td class="">Value2</td>
<td class="">Value3</td>
<td class="">Value4</td>
</tr>
I want selenium to click on the first row. My code looks like this:
wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'ant-table-row-level-0')))
time.sleep(3)
rows = self.selenium.find_elements_by_class_name("ant-table-row-level-0")
rows[0].click()
I get the error:
selenium.common.exceptions.ElementNotInteractableException: Message: Element could not be scrolled into view
When the selenium browser builds up, I can see the table and I can click on the row (and then one div that was invisible becomes visible). So when I manually do it, it works, but selenium somehow has problems clicking on this row.
I also increased the timer to 10 and 20 seconds without success and I tried this just to verify I am clicking at the right row:
td = self.selenium.find_elements_by_tag_name("td")
for t in td:
if "Value1" in t.get_attribute("innerHTML"):
t.click()
Nothing works. The onclick listener for the table is on the row itself. So clicking on a td tag should also trigger something.
What am I doing wrong ?

td = self.selenium.find_elements_by_tag_name("td")
for t in td:
if "Value1" in t.get_attribute("innerHTML"):
t.click()
Turns out the above code did work, but does anyone know why the regular thing does not work ?

Related

Why copy/paste html table into Excel has this behavior

So this is not so much a problem solving question, more a question of why this is happening.
For context, assume you have normal html table like this:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Check This Out</title>
</head>
<body>
<table border="1">
<tr>
<td width="75" >This</td>
<td width="75" >is</td>
<td width="75" >row</td>
<td width="75" >one</td>
<td width="75" >Details</td>
</tr>
<tr>
<td>Now</td>
<td>this</td>
<td>is</td>
<td>TWO</td>
<td>Details</td>
</tr>
<tr>
<td>Last</td>
<td>we</td>
<td>have</td>
<td>Three</td>
<td>Details</td>
</tr>
</table>
</body>
</html>
Using Edge or Chrome, when performing a select operation on of all the data on this table you can do it two different ways (let's ignore reverse-selecting for now):
You can start selecting at the top left and move your mouse all the way until you get the the last cell and stop with your mouse cursor just after the 's' in Details. The mouse cursor looks like a text-insertion cursor until you release mouse button to end the selection.
You can start selecting at the top left and move your mouse way past all the data until it is outside the bottom right side of the data. Doing it this way, your mouse cursor stays as a mouse pointer when you release your mouse button to end the selection.
If you select the data the first way, then copy/paste into Excel, you get all your data in nice rows and columns.
If you select the data the second way, then copy/paste into Excel, all your data shows up as plain text in the one cell you selected for your paste.
Why does this happen?
This is related to your operation, and the operation description you mentioned is not very detailed. For example, these two points:
Start selecting location
End selecting location
If the Start selecting position is outside the table, the content copied and pasted into Excel will be in the correct table format. But if it is in the table, the problem you mentioned may appear, and the second point mentioned needs to be considered.
If the End selecting position is in the table, the content copied and pasted into Excel will also be in the correct table format. But if it is outside the table, the problem you mentioned will occur.
I think this is because the different selection positions will result in whether the table structure is also copied. You can even copy the code directly into Excel, and it will display the correct format.
A simple test:

Pupeteer to generate pdf is rendering tables with gaps

I'm using Node Puppeteer to generate a PDF from a webpage using Chrome Headless. It works really well, apart from a small issue I'm coming across where if a table spans over more than one page sometimes one of the rows will appear larger than expected and the date column having text appear at the top of the row.
This is how it looks in the browser
This is how it is rendered on the pdf (some parts are blurred for confidentiality)
As you can see on the created column on the second page in the PDF view the date and time in the first row are distorted. There is nothing unusual about that row in the html version.
The table follows this structure;
<table>
<thead>
<tr>
<th>Project</th>
<th>Status</th>
<th>Creator</th>
<th>Created</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div>Project Name</div>
<div>Reference</div>
</td>
<td>
<img src="status.png" alt="Some Stagus"> Some Status
</td>
<td>
<div class="avatar"></div>
</td>
<td>
<div>29/10/2020</div>
<div>10:00:00</div>
</td>
</tr>
</tbody>
</table>
I'm not sure if this is a bug with chrome headless, when I print preview in chrome is shows the same issue as the generated pdf. Any suggestions or pointers would be very welcome.
This is going to sound stupid, and I hate this answer... but it worked for me.
Add a dummy row in between your normal rows. Something like ...
<tr style="height: 0px; !important"></tr>
You'll notice that the broken row has 2x height. I'm guessing the issue is triggered when the first pixel of a row lands EXACTLY on a page break, and then the renderer attempts to add the row twice, once on the previous page and once on the current page. But since it doesn't fit on the previous page, it rolls over and doubles up on the current page. ( PURELY SPECULATION )
Given this hypothesis, adding a dummy row with no height between every normal row lets you hide this issue by having the dummy row be the target of the bug. I'm assuming that since its height it 0, it can always squeeze in on the previous page without overflowing and/or it does overflow and get doubled, but since its height is 0 it doesn't matter.
Anyways, this was a nightmare to figure out a hack-fix. It worked for me, I truly hope it works for you, and I hope puppeteer releases an update one day that improves on page-break logic.

Send Tab button key press event 10 times and increment it by 1 in a loop

Is there a way where I can send a TAB key press event 10 times using the command (Application.SendKeys "{TAB 90}) and then programmatically increment the count by 1 such that it sends (Application.SendKeys "{DOWN 91}) .
I have a drop down list on a web page where I need to select an item, press a search button ,then scraps items from the resulting searched page and finally going back to the main search page to again select the next item in the drop down list to repeat the above process. The drop down list contain 300 items.
I know there might be a better way to do this. Please enlighten me.
Below is the HTML snippet from the web page containing the details:-
<td style="width: 100%;">
<select name="filter1.F1" tabindex="5" id="filter1.F1" onkeydown="dataExplorerDropDownKeyPress(event)" dataexplorerdropdownstate="Collapsed" dataexplorerdatatype="TABLE">
<option name=""></option><option value="aaa_0">000</option>
<option value="aaa_1">ABC</option>
<option value="aaa_2">BCD</option>
.
.

Python Webdriver - How can I select a radio button based upon the text of a separate label?

Using Python WebDriver, how can I select a radio button based upon the text of a separate element such as this label?
My current code has the ability to click the radio button by id. But I have no idea how it is possible to click it when I am depending on text from a completely separate element.
The following is a pic of what i'm up against.
All help is greatly appreciated! =)
I've created a simplified example of your html on the screenshot, and assuming you want to get radio button which following sibling has "test text2", you need to use xpath axes:
<table>
<tbody>
<tr>
<td><input id="test_id" type="radio" value="123" /></td>
<td>test text</td>
<td>test text2</td>
<td>test text3</td>
</tr>
</tbody>
</table>
XPath would be: //tr/td[contains(text(),"test text2")]/preceding-sibling::td/input
The logic is:
get an element with specific text
go to previous sibling element (sibling == same level element)
now go deeper to td/input from there

how to get data from HTMLDataTable in jsf?

<h:dataTable width="100%" border="1" cellspacing="0"
cellpadding="2" style="border-collapse:collapse;display:block"
styleClass="Header" value="#{adminBean.displayResults}"
var="aResult" binding="#{adminBean.browseResultsHTMLDataTable}">
This is what i am trying to do. I have a dynamic list of data, which i try to display in the HTML Table format using h:dataTable (the bounded value is an arrayList). The table has got a radio button for each row it displays (boolean w/ h:selectOneRadio ) now when i select the radio button in one of these rows, i want to get the values of the row that is selected for which i try to use binding attribute. But i get Row Unavailable exception - is my approach wrong? any suggestions?
Selecting rows by radio button in a datatable is a tricky task since the radio buttons aren't grouped. Long story short: Select row by radio button.
I think you can use <t:selectOneRadio> with layout="spread" and then <t:radio> on each row.

Resources