How to "firmly" locate an element in a table? Selenium - selenium

How can I locate an element "1988" (the fourth line) in the following table:
<table border="0" width="820" cellpadding="2" cellspacing="0">
<tbody>
<tr valign="top">
<td class="default" width="100%">Results <b>1</b> to <b>10</b> of <b>1988</b></td>
</tr>
<tr valign="top">
<td class="default" bgcolor="#C0C0C0"> <font class="resultsheader"> ...etc
</tr>
</tbody>
</table>
IMPORTANT: I know one way that works (By.xpath):
driver.findElement(By.xpath("//td[#width='100%']")).getText();
However, this way does not ALWAYS work. The page is dynamic, so I need a way to locate that element no matter what changes happen to the page.
I tried the following but I am not sure:
By.xpath("//html//body//table//tbody//tr[3]//td//table//tbody//tr//td[2]//table[4]//tbody//tr[1]//td//b[3]"

If you can't change the HTML and want to use attributes for selection, you can write something like this:
//table[#border=0][#width=820]//tbody//tr[1]//td//b[3]

Related

XPATH to use preceding and following sibling in a single statement

I would like to scrape name, address informations between tag contains defendent text and another tag,
My HTML structure is:
<hr>
<H5>Defendant/Respondent Information</H5>
<span class="InfoChargeStatement">(Each Defendant/Respondent is displayed below)</span>
<table>
<tr>
<td><span class="FirstColumnPrompt">Party Type:</span></td><td><span class="Value">Defendant</span><span class="Prompt">Party No.:</span><span class="Value">1</span></td>
</tr>
</table>
<table>
<tr>
<td><span class="FirstColumnPrompt">Name:</span></td><td><span class="Value">Name 1</span></td>
</tr>
</table>
<table>
<tr>
<td><span class="FirstColumnPrompt">Address:</span></td><td><span class="Value">Addr 1</span></td>
</tr>
<tr>
<td><span class="FirstColumnPrompt">City:</span></td><td><span class="Value">city1</span><span class="Prompt">State:</span><span class="Value">aa</span><span class="Prompt">Zip Code:</span><span class="Value">Zip1</span></td>
</tr>
</table>
<hr>
<table>
<tr>
<td><span class="FirstColumnPrompt">Party Type:</span></td><td><span class="Value">Defendant</span><span class="Prompt">Party No.:</span><span class="Value">2</span></td>
</tr>
</table>
<table>
<tr>
<td><span class="FirstColumnPrompt">Name:</span></td><td><span class="Value">Name 2</span></td>
</tr>
</table>
<table>
<tr>
<td><span class="FirstColumnPrompt">Address:</span></td><td><span class="Value">Addr2</span></td>
</tr>
<tr>
<td><span class="FirstColumnPrompt">City:</span></td><td><span class="Value">City2</span><span class="Prompt">State:</span><span class="Value">st2</span><span class="Prompt">Zip Code:</span><span class="Value">zip2</span></td>
</tr>
</table>
<hr>
<H5>Related Persons Information</H5>
<span class="InfoChargeStatement">(Each Related person is displayed below)</span>
<table>
<tr>
<td><span class="FirstColumnPrompt">Name:</span></td><td><span class="Value">Unwanted Name</span></td>
</tr>
</table>
<table>
<tr>
<td><span class="FirstColumnPrompt">Address:</span></td><td><span class="Value">un addr</span></td>
</tr>
<tr>
<td><span class="FirstColumnPrompt">City:</span></td><td><span class="Value">Unwanted City</span><span class="Prompt">State:</span><span class="Value">Unwanted city</span><span class="Prompt">Zip Code:</span><span class="Value">12345</span></td>
</tr>
</table>
<table></table>
<hr>
My current XPATH capturing the first occurence of Name and address properly, but if need to extract the multiple occurences, it also scrape the information from the unwanted h5 tags.
My current XPATH is,
"//*[contains(text(),'Defendant')]//following-sibling::table//span[text()='Name:' or text()='Business or Organization Name:']/ancestor-or-self::td/following-sibling::td//text()")
I tried including preceding sibling and following sibling but nothing gives my expected output,
My current output is..
names - [
Name1,
Name2
Unwanted Name,
]
Expected output is,
[
Name1
Name2
]
Kindly help.
try this:
"//H5[contains(text(),'Defendant')]/following-sibling::table[not(preceding-sibling::H5[not(contains(text(),'Defendant'))])]/tr[td[1][span[text()[.='Name:' ]]]]/td[2]/span/text()"
It first selects the table that has not a preceding-sibling::h5 with text() that not contains 'Defendant' and than
selects from the correct table the tr where the first td meets your requirements and selects the second td
No need for double slashes which is bad for performance
EDIT 1
Since there are more preceding-sibling::h5 than the example shows, this XPath will deal with that:
"//H5[contains(text(),'Defendant')]/following-sibling::table[preceding-sibling::H5[1][contains(text(),'Defendant')]]//tr[td[1][span[text()[.='Name:' ]]]]/td[2]/span/text()"
This will only select those tables that have as there first preceding-sibling::h5 the same h5 as we were interested in
EDIT 2
Actually now the first h5 select is redundant. This XPath will do:
"//table[preceding-sibling::H5[1][contains(text(),'Defendant')]]//tr[td[1][span[text()[.='Name:' ]]]]/td[2]/span/text()"

DOMPDF 0.8.3 how split long vertical table

I have table which have more rows:
This table start on new page and some rows are hidden (are not visible on next page).
I want to place table on previous page and hidden visible display to next page. I use DOMPDF 0.8.3.
I tried:
<table style"page-break-inside: auto;">
<tr style="page-break: auto">
<td>abc</td>
<td>cde</td>
</tr>
<tr style="page-break: auto">
<td>abc</td>
<td>cde</td>
</tr>
<tr style="page-break: auto">
<td>abc</td>
<td>cde</td>
</tr>
</table>
Do not know how to solve this, please?

Selenium - Selecting an item from dropdown list if the values are inside <table> tags and NOT under <option> in html

The below is a snippet from our html code which appears as a drop down list in the application. I am unable to select a particular value from the drop down list using Select class in Selenium - possibly because it doesn't have "Option" tags?. Is there any way to select the item?
-UPDATE: This has a parent tag which talks about visibility. Basically to tell that elements are visible only if the user clicks the drop down arrow.
"< input type="hidden" *****"
For e.g. I need to select 'I am option2' from the list during the test execution.
<div id="xyz" class="DropdownInnerContainer" style="z-index:99999;">
<table id="abc" class="DropdownItemContainer" list="1000020">
<tr class="">
<td value="" index="0" title="">
</td>
<td class="BorderCell"></td>
</tr>
<tr class="">
<td value="I am option1" index="1" plid="1002827">I am option1</td>
<td class="BorderCell"></td>
</tr>
<tr class="">
<td value="I am option2" index="2" plid="1002828">I am option2</td>
<td class="BorderCell"></td>
</tr>
<tr class="">
<td value="I am option3" index="3" plid="1002829">I am option3</td>
<td class="BorderCell"></td>
</tr>
<tr class="">
<td value="I am option4" index="4" plid="1002830">I am option4</td>
<td class="BorderCell"></td>
</tr>
</table>
If the text inside of the td that you want to select is unique, then you can click the table element with the id of 'abc' and then click the following element. The code provided is C#, but can be translated pretty easily.
IWebElement option = _driver.FindElement(By.XPath("//td[text()='I am option2']"));
It appears that since the drop down options were inside a < table >, the Select class was unable to identify the list options. So here's what I did:
First click() the dropdown, which opens up the menu:
driver.findElement(By.xpath(".//*[#id='abc01_tbl']/div/div")).click();
Then pass the value using the contains() method and then click() on it.
driver.findElement(By.xpath(".//*[#id='xyz01_tbl']/tbody/tr/td[1][contains(text(),'I am option2')]")).click();
You can not use Select in this scenario because there is no any select tag for dropdown. Drop down is under table body.
Please use below xpath for select option form drop down.
driver.findElement(By.xpath("//table[#id='abc']/tr[td[text()='your option text']]/td"));

selenium xpath, how to select last matching element in a table?

Given
<table>
<tr>
<td>service1</td>
</tr>
<tr>
<td>service2</td>
</tr>
<tr>
<td>service3</td>
</tr>
<tr>
<td>blip</td>
</tr>
</table>
How can I select the last 'service-n' row when I don't know what n will be?
I have tried adding [last()] but it didn't work.
I have:
//table//tr//td[contains(text(),'service')]
but it selects the 1st row and I want the last one.
I can't use tr[3] because in reality the number of 'service-n' rows is dynamic and changes a lot.
The answer was exactly where I put the [last()] and I had it in the wrong place
It goes here:
//div[#id='content']//table//tr[last()]//td[contains(text(),'service')][last()]/following-sibling::td[2]
Not here:
//div[#id='content']//table//tr[last()]//td[contains(text(),'service')]/following-sibling::td[2][last()]
try with cssSelector, this way.
By.cssSelector("table tr:last-child td")
List<WebElement> allElement=fd.findElements(By.xpath("//table//td[contains(.,'service')]");
int count=allElement.size();
allElement.get(count-1).click();
<table id="table1">
<tbody>
<tr id="tr1">
<td id="td1"></td>
<td id="td2"></td>
<tr>
<tr id="tr2">
<td id="td3"></td>
<td id="td4"></td>
<tr>
<tbody>
</table>
Then to target last td of last tr
we can have xpath as:xpath="//table[#id='table1']//tr[last()]//td[last()]";
(//div[#id='name'])[last()]
By using we can get the last element of the relevant filed.
//div[#id='name'][last()]
Multiple elements in last

Unable to find element with css selector

Using Selenium Webdriver for FF/IE using C# (.Net)
Below is my page source and I am trying to use the CssSelector to find/contains the particular name from my page and i have tried with the below code but resulting in error, any help?
//code
driver.FindElement(By.CssSelector("td:contains('John John')"))
//error:
e {"Unable to find element with css selector == td:contains('John John')"} System.Exception {OpenQA.Selenium.NoSuchElementException}
//my html code:
<div id="ctl00_ContentPlaceHolder1_AddeCardControl1_gv_ctl01_RecordCount" style="float:right; padding-right:10px; margin-top:3px;">
<b>308</b> Items Found
</div>
</td>
</tr>
<tr class="item">
<td align="center">Edit</td>
<td align="center" style="width:15px;"></td>
<td>John John</td>
<td> </td>
<td> </td>
<td> </td>
<td><img src="check.png" alt='Active' style='display: ;' /></td>
<td>9/7/2012 11:15:08 PM</td>
</tr>
<tr class="altItem">
<td align="center">Edit</td>
<td align="center" style="width:15px;"></td>
<td>John Schulz</td>
<td> </td>
<td>Visitors</td>
<td> </td>
<td><img src="check.png" alt='Active' style='display: ;' /></td>
<td>9/7/2012 6:28:29 PM</td>
</tr>
<tr class="item">
<td align="center">Edit</td>
<td align="center" style="width:15px;"></td>
<td>Parker Smith</td>
<td> </td>
<td>Visitors</td>
<td> </td>
<td><img src="check.png" alt='Active' style='display: ;' /></td>
<td>9/7/2012 6:01:28 PM</td>
</tr>
<tr class="altItem">
<td align="center">Edit</td>
<td align="center" style="width:15px;"></td>
<td>Test 123</td>
<td> </td>
<td>Visitors</td>
<td> </td>
<td><img src="check.png" alt='Active' style='display: ;' /></td>
<td>9/7/2012 1:36:45 PM</td>
</tr>
<tr class="item">
<td align="center">Edit</td>
<td align="center" style="width:15px;">
The :contains pseudoselector is not part of the W3C CSS Selector standard. As such, browsers do not support selecting elements using it. Some JavaScript CSS selector engines (Sizzle, the engine used by jQuery, for example) provide a :contains pseudoselector, but its presence cannot be relied on.
If you must find an element by the text contents of the element, your only solution at this point is to use XPath. A (very poorly performing) example of how to find this in your case would be as follows:
IWebElement element = driver.FindElement(By.XPath("//td[contains(., 'John John')"));
Note that a better solution will always be to have the application you're automating have proper IDs for the elements you need to find. You should be using text to find elements only as a last resort.
You can try this
var webElements = (Driver.FindElements(By.XPath(elementXpath))).ToList();
webElements.FindIndex(item => item.Text.Contains("John John").Click()
where "elementXpath" is path to each cell in table "names". So you get the list of names and then just find a match. You'll get your item clicked.
You may have better luck using the javascript executor to click the element. I am using a very slow IE9 64bit emulator and it seems the only way to click on certain buttons is to use the javascript executor.
CSS selectors aren't very useful here, because CSS selectors work on the html structure i.e. type, relationship and attributes of web elements; they don't work well on the html content, which in this case is the internal text content 'John John'.
But, xpath will work for this job. The function you need is text() which returns the element's inner text content:
//td[text()='John John']
So your webdriver code should look like this:
driver.FindElement(By.xpath("//td[text()='John John']"));
P.S. All locators verified using Firepath in firefox.
You can use the below code:
driver.FindElement(By.XPath("//td[contains(text(), 'John John')"));