Selenium Python how do i find the right checkbox element from a HTML table within a table using XPath - python-2.7

I have a dialog displayed having clicked on an element. In this dialog there are 2 tables (HTML). A table within a table.
Table 1 has the text "Match audit codes"
Table 2 has some rows and columns. Column 1 has a checkbox. Column 2 has a char value, e.g. the letter "I")
Column 3 has some text e.g. "Matched to full address"
I would like to locate the checkbox from column 1 which has the text description "Matched to Full Address" and the parent table has the text "Match audit codes"
I tried the following Xpath which locates the checkbox which has the text "Matched to full address"
//div[contains(text(), "Matched to full address")]/ancestor::tr[1]/td[1]//input
My Selenium Python script will not click this checkbox. The developer says there could be more than 1 "Matched to full address" in the HTML somewhere.
I need the Xpath to start from the parent table which has the text "Match audit codes" and then go down to the next table which has the text "Matched to full address" and then locate the checkbox.
How can i build the Xpath please?
The HTML is:
<table class="GJPPK2LBAL" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td align="left" style="vertical-align: top;">
<div class="GJPPK2LBPK">Match audit codes</div>
</td>
<td align="left" style="vertical-align: top;">
<button class="gwt-Button GJPPK2LBLK" type="button">X</button>
</td>
</tr>
</tbody>
</table>
<table class="GJPPK2LBOK" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td align="left" style="vertical-align: middle;">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr>
<tr>
<td align="left" style="vertical-align: top;">
<div style="overflow: auto; position: relative; width: 25em;">
<div style="position: relative;">
<table class="GJPPK2LBJE" cellspacing="0"
__gwtcellbasedwidgetimpldispatchingfocus="true"
__gwtcellbasedwidgetimpldispatchingblur="true">
<thead aria-hidden="false">
<colgroup>
<tbody>
<tr class="GJPPK2LBCD" __gwt_subrow="0" __gwt_row="0">
<td class="GJPPK2LBBD GJPPK2LBDD GJPPK2LBED">
<div __gwt_cell="cell-gwt-uid-5972" style="outline-style:none;">
<input type="checkbox" tabindex="-1"/>
</div>
</td>
<td class="GJPPK2LBBD GJPPK2LBDD">
<div __gwt_cell="cell-gwt-uid-5973" style="outline-style:none;">I</div>
</td>
<td class="GJPPK2LBBD GJPPK2LBDD GJPPK2LBOD">
<div __gwt_cell="cell-gwt-uid-5974" style="outline-style:none;">Matched to
full address
</div>
</td>
</tr>
<tr class="GJPPK2LBCE" __gwt_subrow="0" __gwt_row="1">
<td class="GJPPK2LBBD GJPPK2LBDE GJPPK2LBED">
<div __gwt_cell="cell-gwt-uid-5972" style="outline-style:none;">
<input type="checkbox" tabindex="-1"/>
</div>
</td>
<td class="GJPPK2LBBD GJPPK2LBDE">
<div __gwt_cell="cell-gwt-uid-5973" style="outline-style:none;">B</div>
</td>
<td class="GJPPK2LBBD GJPPK2LBDE GJPPK2LBOD">
<div __gwt_cell="cell-gwt-uid-5974" style="outline-style:none;">Matched to
building
</div>
</td>
</tr>
<tr class="GJPPK2LBCD" __gwt_subrow="0" __gwt_row="2">
<tr class="GJPPK2LBCE" __gwt_subrow="0" __gwt_row="3">
</tbody>
<tbody style="display: none;">
<tfoot style="display: none;" aria-hidden="true"/>
</table>
Thanks,
Riaz

I'm not sure if I'm getting your question. You want to locate the table containing "Match audit codes", then move on to the next table containing "Matched to full address", and inside that table search for the checkbox in the same row as the "Matched to full address" text?
If so, then it should look like this:
//table[.//div[text()='Match audit codes']]/following-sibling::table[.//div[.='Matched to full address']][1]//div[.='Matched to full address']/ancestor::tr[1]/td//input[#type='checkbox'][1]
If .='Matched to full address' doesn't work, try contains(.,'Matched to full address') instead.

Here is a tip:
Find all elements with text to be matched.
List<WebElement> texts = driver.findElements(By.xpath("//td[#class='GJPPK2LBBD GJPPK2LBDE GJPPK2LBOD']"));
Now store the indexes of elements which contains your desired text.
List<Integer> list = new ArrayList<>();
for(int i=0;i<list.size();i++){
if(text.get(i).getText().equals("Matched to full address"))
list.add(i);
}
Now you have the list of all indexes with text as 'Matched to full address'. You can now call the corresponding check boxes and play.
List<WebElement> checks = driver.findElements(By.xpath("//td[#class='GJPPK2LBBD GJPPK2LBDE GJPPK2LBED']"));
for(int index:checks){
WebElement cb = checks.get(index);
//Do something with cb
}
Hope it helps.

Related

Selenium XPATH how can i get text out from table column 4 where text is in table column 2

I have a HTML table with some columns and rows. I am trying to find the text from column 5 and the text from column 3.
The text I would like to find from col 5 is 101 THE BatCave|GOTHAM CITY| and the text 14 from col 3
To start I first find the text 14 from col 3 with the following XAPTH:
//table[#id="reporting_view_report_dg_main_body"]//tr//td[3]/div/span[#title="14"]
But I don't know how to get the text from column 5 also.
I have tried:
//table[#id="reporting_view_report_dg_main_body"]//tr//td[3]/div/span[#title="14"] and td[5]//span[contains(text(), "101 THE BatCave|GOTHAM CITY|"])
//table[#id="reporting_view_report_dg_main_body"]//tr//td[3]/div/span[#title="14"]/following::td[5]
The HTML snippet is:
<table id="reporting_view_report_dg_main_body" cellspacing="0" style="table-layout: fixed; width: 100%; margin-bottom: 17px;">
<colgroup>
<tbody>
<tr class="GFNQNVHJM" __gwt_subrow="0" __gwt_row="0" />
<tr class="GFNQNVHIN" __gwt_subrow="0" __gwt_row="1"/>
<tr class="GFNQNVHJM" __gwt_subrow="0" __gwt_row="2"/>
<tr class="GFNQNVHJM GFNQNVHAN" __gwt_subrow="0" __gwt_row="12"/>
<td class="GFNQNVHIM GFNQNVHKM GFNQNVHLM GFNQNVHBN"/>
<td class="GFNQNVHIM GFNQNVHKM GFNQNVHBN"/>
<td class="GFNQNVHIM GFNQNVHKM GFNQNVHBN"/>
<div __gwt_cell="cell-gwt-uid-319" style="outline-style:none;"/>
<span title="14" style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;empty-cells:show;display:block;padding-right: 1px;">14</span>
</div>
</td>
<td class="GFNQNVHIM GFNQNVHKM GFNQNVHBN">
<td class="GFNQNVHIM GFNQNVHKM GFNQNVHBN">
<div __gwt_cell="cell-gwt-uid-321" style="outline-style:none;">
<span title="101 BatCave|GOTHAM CITY|" style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;empty-cells:show;display:block;padding-right: 1px;">101 THE BatCave|GOTHAM CITY|</span>
</div>
</td>
<td class="GFNQNVHIM GFNQNVHKM GFNQNVHBN">
<td class="GFNQNVHIM GFNQNVHKM GFNQNVHBN"/>
<td class="GFNQNVHIM GFNQNVHKM GFNQNVHBN"/>
<td class="GFNQNVHIM GFNQNVHKM GFNQNVHBN"/>
<td class="GFNQNVHIM GFNQNVHKM GFNQNVHBN"/>
<td class="GFNQNVHIM GFNQNVHKM GFNQNVHFN GFNQNVHBN"/>
</tr>
<tr class="GFNQNVHIN" __gwt_subrow="0" __gwt_row="13"/>
<tr class="GFNQNVHJM" __gwt_subrow="0" __gwt_row="14"/>
</tbody>
Thanks, Riaz
Not sure about the reliability of this approach in your particular case, but given what provided, you can get both elements by getting span elements with title attribute:
elements = driver.find_elements_by_xpath("//table[#id='reporting_view_report_dg_main_body']//span[#title]")
for element in elements:
print(element.text)
This is impossible to combine both columns together using xpath and get their text combination. You can find only these two columns in the list and then combine their text through loop as below :
combineText = ""
columns = driver.find_element_by_id("reporting_view_report_dg_main_body").find_elements_by_xpath(".//span[#title = '14'] | .//span[#title = '101 BatCave|GOTHAM CITY|']")
for column in columns:
combineText += column.text
print(combineText)

Selenium XPATH I am looking for an input field in a HTML table which has a specific text value

I have a HTML table with some rows of input fields. Each input field has a value.
The input field I am looking for is any input field which contains the text "filter"
The actual text is "filter2" or it could be "filter3"
Can i use the contains keyword in the Xpath to find "filter" for the #value attribute?
The XPATH i have constructed is:
//table[#id="reporting_add_report_tab_manual_ct_match_filters"]/tbody//tr//td//input[#value="filter2"]
I would like to find the input field where it has filter in the value attribute, exclude the number 2
The HTML snippet is:
<table id="reporting_add_report_tab_manual_ct_match_filters" class="GJPPK2LBAV border" cellspacing="0"
__gwtcellbasedwidgetimpldispatchingfocus="true" __gwtcellbasedwidgetimpldispatchingblur="true">
<thead aria-hidden="false">
<colgroup>
<tbody style="">
<tr class="GJPPK2LBCD GJPPK2LBMD" __gwt_subrow="0" __gwt_row="0">
<td class="GJPPK2LBBD GJPPK2LBDD GJPPK2LBED">
<div __gwt_cell="cell-gwt-uid-684" style="outline-style:none;">
<input type="checkbox" tabindex="-1"/>
</div>
</td>
<td class="GJPPK2LBBD GJPPK2LBDD">
<div __gwt_cell="cell-gwt-uid-685" style="outline-style:none;">
<span>
<input type="text" tabindex="-1" value="rule1"/>
</span>
<span>
</div>
</td>
<td class="GJPPK2LBBD GJPPK2LBDD GJPPK2LBOD">
</tr>
<tr class="GJPPK2LBCE" __gwt_subrow="0" __gwt_row="1">
<td class="GJPPK2LBBD GJPPK2LBDE GJPPK2LBED">
<div __gwt_cell="cell-gwt-uid-684" style="outline-style:none;">
<input type="checkbox" tabindex="-1"/>
</div>
</td>
<td class="GJPPK2LBBD GJPPK2LBDE">
<div __gwt_cell="cell-gwt-uid-685" style="outline-style:none;">
<span>
<input type="text" tabindex="-1" value="filter2"/>
</span>
<span>
<div style="color:red;font-style:italic;"/>
</span>
</div>
</td>
<td class="GJPPK2LBBD GJPPK2LBDE GJPPK2LBOD">
</tr>
</tbody>
<tbody style="display: none;">
<tfoot style="display: none;" aria-hidden="true"/>
</table>
Thanks,
Riaz
//table[#id="reporting_add_report_tab_manual_ct_match_filters"]/tbody/tr/td//input[#value!="filter2"][contains(#value,"filter")]

Selenium Python I have an Xpath using Ancestor axis can i convert this to a CSS selector

I have an HTML page with a table of checkboxes. Each checkbox has a name.
In col1 is the checkbox. In col2 is the name.
I want to find the checkbox which has the name "Address"
I have managed to find it by using the following Xpath:
//table[#id="reporting_add_report_tab_manual_ct_vars_usn"]/tbody//tr//td//div[contains(text(), "Address")]//ancestor::tr[1]//input[#type="checkbox"]
I locate the column which contains the text "Address"
I then use ancestor to go up 1 row to it's parent of the current node and locate the checkbox
I would like to use CSS, can this xpath be converted to use the CSS locator?
CSS is quicker than Xpath to locate elements on the web page.
The HTML is:
<table id="reporting_add_report_tab_manual_ct_vars_usn" class="GJPPK2LBJE" cellspacing="0" __gwtcellbasedwidgetimpldispatchingfocus="true" __gwtcellbasedwidgetimpldispatchingblur="true">
<thead aria-hidden="false">
<colgroup>
<tbody style="">
<tr class="GJPPK2LBCD GJPPK2LBJD" __gwt_subrow="0" __gwt_row="0">
<td class="GJPPK2LBBD GJPPK2LBDD GJPPK2LBED GJPPK2LBKD">
<div __gwt_cell="cell-gwt-uid-1204" style="outline-style:none;">
<input type="checkbox" tabindex="-1"/>
</div>
</td>
<td class="GJPPK2LBBD GJPPK2LBDD GJPPK2LBKD">
<div __gwt_cell="cell-gwt-uid-1205" style="outline-style:none;">Name</div>
</td>
<td class="GJPPK2LBBD GJPPK2LBDD GJPPK2LBKD">
<div __gwt_cell="cell-gwt-uid-1206" style="outline-style:none;">
<select tabindex="-1">
</div>
</td>
<td class="GJPPK2LBBD GJPPK2LBDD GJPPK2LBKD">
<td class="GJPPK2LBBD GJPPK2LBDD GJPPK2LBOD GJPPK2LBKD">
</tr>
<tr class="GJPPK2LBCE" __gwt_subrow="0" __gwt_row="1">
<td class="GJPPK2LBBD GJPPK2LBDE GJPPK2LBED">
<div __gwt_cell="cell-gwt-uid-1204" style="outline-style:none;">
<input type="checkbox" tabindex="-1"/>
</div>
</td>
<td class="GJPPK2LBBD GJPPK2LBDE">
<div __gwt_cell="cell-gwt-uid-1205" style="outline-style:none;">Address</div>
</td>
<td class="GJPPK2LBBD GJPPK2LBDE">
<td class="GJPPK2LBBD GJPPK2LBDE">
<td class="GJPPK2LBBD GJPPK2LBDE GJPPK2LBOD">
</tr>
<tr class="GJPPK2LBCD" __gwt_subrow="0" __gwt_row="2">
<td class="GJPPK2LBBD GJPPK2LBDD GJPPK2LBED">
<div __gwt_cell="cell-gwt-uid-1204" style="outline-style:none;">
<input type="checkbox" tabindex="-1"/>
</div>
</td>
<td class="GJPPK2LBBD GJPPK2LBDD">
<div __gwt_cell="cell-gwt-uid-1205" style="outline-style:none;">DOB</div>
</td>
<td class="GJPPK2LBBD GJPPK2LBDD">
<td class="GJPPK2LBBD GJPPK2LBDD">
<td class="GJPPK2LBBD GJPPK2LBDD GJPPK2LBOD">
</tr>
<tr class="GJPPK2LBCE" __gwt_subrow="0" __gwt_row="3">
</tbody>
<tbody style="display: none;">
<tfoot style="" aria-hidden="false">
</table>
If the order of the checkboxes is fixed you can use nth-of-type
input[type='checkbox']:nth-of-type(2)
This will find the second occurrence of input[type='checkbox'].
Or you can use nth-child.
table#reporting_add_report_tab_manual_ct_vars_usn tr:nth-child(2) td input
This finds the second tr in the table, in that row a td with an input.

Selenium Python select the link from 3rd column from a table

I have a page with a table with some rows and columns. The first column has a checkbox (index is 0). The 2nd column has the name. The 3rd column has a link called view. There are some rows of data in the table.
I would like to click the view link which has the name "Selenium_CRM_For_Edit_Test"
The name could be anywhere in the table of rows.
I can identify the column name with the following XPATH:
//span[contains(., "Selenium_CRM_Edit_Test")]
I do not know how to get to the next column which has the view link
I have tried the following XPath:
//span[contains(., "Selenium_CRM_Edit_Test")]/../preceding-sibling::td/div/span[contains(text(), "view")]
That does not work. I thought preceding-sibling would go down to the next TD element
The HTML snippet is:
<table id="data_configuration_data_previews_ct_fields_body" cellspacing="0" style="table-layout: fixed; width: 100%;">
<colgroup>
<tbody>
<tr class="GJPPK2LBFG" __gwt_subrow="0" __gwt_row="0">
<tr class="GJPPK2LBEH" __gwt_subrow="0" __gwt_row="1">
<tr class="GJPPK2LBFG GJPPK2LBMG" __gwt_subrow="0" __gwt_row="18">
<td class="GJPPK2LBEG GJPPK2LBGG GJPPK2LBHG GJPPK2LBNG">
<td class="GJPPK2LBEG GJPPK2LBGG GJPPK2LBNG">
<div __gwt_cell="cell-gwt-uid-237" style="outline-style:none;">
<span class="linkhover" title="Selenium_LADEMO_CRM_DONOTCHANGE" style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;empty-cells:show;display:block;color:#00A;cursor:pointer;">Selenium_CRM_For_Edit_Test</span>
</div>
</td>
<td class="GJPPK2LBEG GJPPK2LBGG GJPPK2LBNG">
<div __gwt_cell="cell-gwt-uid-238" style="outline-style:none;">
<span class="linkhover" title="view" style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;empty-cells:show;display:block;color:#00A;cursor:pointer;">view</span>
</div>
</td>
<td class="GJPPK2LBEG GJPPK2LBGG GJPPK2LBNG">
<td class="GJPPK2LBEG GJPPK2LBGG GJPPK2LBBH GJPPK2LBNG">
</tr>
<tr class="GJPPK2LBEH" __gwt_subrow="0" __gwt_row="19">
<tr class="GJPPK2LBFG" __gwt_subrow="0" __gwt_row="20">
</tbody>
How do i get to the link which has the name Selenium_CRM_For_Edit_Test?
Thanks,
Riaz
Assuming you want to locate the
<span class="linkhover" title="view" style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;empty-cells:show;display:block;color:#00A;cursor:pointer;">view</span>
element, based on the text in
<span class="linkhover" title="Selenium_LADEMO_CRM_DONOTCHANGE" style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;empty-cells:show;display:block;color:#00A;cursor:pointer;">Selenium_CRM_For_Edit_Test</span>
you can use the following axis:
//span[contains(., "Selenium_CRM_Edit_Test")]/following::span[#class="linkhover"]

Selenium Python my Xpath won't click the checkbox inside the table 1st column

I have a page with a table with some rows and columns. The first column has a checkbox (index is 0). The 2nd column has the name.
There are some rows of data in the table. I would like to click the checkbox which has the name "Selenium_CRM_For_Edit_Test"
My XPATH won't click the checkbox. I can locate the checkbox using XPATH checker in Firebug. My XPATH is:
//table[#id="data_configuration_data_previews_ct_fields_body"]/tbody/tr//../td//../div/span[contains(text(), "Selenium_CRM_For_Edit_Test")]/preceding::div[1]//../input
The HTML is:
<table id="data_configuration_data_previews_ct_fields_body" cellspacing="0" style="table-layout: fixed; width: 100%;">
<colgroup>
<tbody>
<tr class="GJPPK2LBFG" __gwt_subrow="0" __gwt_row="0">
<tr>.. some more rows here
<tr class="GJPPK2LBEH" __gwt_subrow="0" __gwt_row="15">
<tr class="GJPPK2LBFG" __gwt_subrow="0" __gwt_row="16">
<td class="GJPPK2LBEG GJPPK2LBGG GJPPK2LBHG">
<div __gwt_cell="cell-gwt-uid-1417" style="outline-style:none;">
<input type="checkbox" tabindex="-1"/>
</div>
</td>
<td class="GJPPK2LBEG GJPPK2LBGG">
<div __gwt_cell="cell-gwt-uid-1418" style="outline-style:none;">
<span class="linkhover" title="MegaOne_CHROME" style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;empty-cells:show;display:block;color:#00A;cursor:pointer;">MegaOne_CHROME</span>
</div>
</td>
<td class="GJPPK2LBEG GJPPK2LBGG">
<td class="GJPPK2LBEG GJPPK2LBGG">
<td class="GJPPK2LBEG GJPPK2LBGG GJPPK2LBBH">
</tr>
<tr class="GJPPK2LBEH GJPPK2LBMG" __gwt_subrow="0" __gwt_row="17">
<td class="GJPPK2LBEG GJPPK2LBFH GJPPK2LBHG GJPPK2LBNG">
<div __gwt_cell="cell-gwt-uid-1417" style="outline-style:none;">
<input type="checkbox" tabindex="-1"/>
</div>
</td>
<td class="GJPPK2LBEG GJPPK2LBFH GJPPK2LBNG">
<div __gwt_cell="cell-gwt-uid-1418" style="outline-style:none;">
<span class="linkhover" title="Selenium_CRM_Edit_Test" style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;empty-cells:show;display:block;color:#00A;cursor:pointer;">Selenium_CRM_Edit_Test</span>
</div>
</td>
<td class="GJPPK2LBEG GJPPK2LBFH GJPPK2LBNG">
<div __gwt_cell="cell-gwt-uid-1419" style="outline-style:none;">
<span class="linkhover" title="view" style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;empty-cells:show;display:block;color:#00A;cursor:pointer;">view</span>
</div>
</td>
<td class="GJPPK2LBEG GJPPK2LBFH GJPPK2LBNG">
<div __gwt_cell="cell-gwt-uid-1420" style="outline-style:none;">File</div>
</td>
<td class="GJPPK2LBEG GJPPK2LBFH GJPPK2LBBH GJPPK2LBNG">
<div __gwt_cell="cell-gwt-uid-1421" style="outline-style:none;">498</div>
</td>
</tr>
<tr class="GJPPK2LBFG" __gwt_subrow="0" __gwt_row="18">
<tr class="GJPPK2LBEH" __gwt_subrow="0" __gwt_row="19">
<tr class="GJPPK2LBFG" __gwt_subrow="0" __gwt_row="20">
</tbody>
</table>
My Selenium Python code to select the checkbox is:
def select_a_data_preview(self, data_preview):
# to get to the checkbox By.XPATH //table[#id="data_configuration_data_previews_ct_fields_body"]/tbody/tr//../td//../div/span[contains(text(), "Selenium_LADEMO_CRM_DONOTCHANGE")]/preceding::div[1]//../input
data_preview_element = self.driver.find_element(By.XPATH, '//table[#id="data_configuration_data_previews_ct_fields_body"]/tbody/tr//../td//../div/span[contains(text(), "%s")]/preceding::div[1]//../input' % data_preview)
data_preview_element.click()
return self
I have also tried looping through the table, find the name from col 1 and then click col 0 which is where the checkbox is. It does not work. My code snippet is:
def select_a_data_preview(self, data_preview):
try:
WebDriverWait(self.driver, 20).until(EC.presence_of_element_located((By.ID, 'data_configuration_data_previews_ct_fields_body')))
table_id = WebDriverWait(self.driver, 20).until(EC.presence_of_element_located((By.ID, 'data_configuration_data_previews_ct_fields_body')))
rows = table_id.find_elements(By.TAG_NAME, "tr")
for row in rows:
# Get the columns
col_checkbox = row.find_elements(By.TAG_NAME, "td")[0] # This ist the checkbox col
col_name = row.find_elements(By.TAG_NAME, "td")[1] # This is the Configuration Name column
col_type = row.find_elements(By.TAG_NAME, "td")[3] # This is the Type column
col_rows = row.find_elements(By.TAG_NAME, "td")[4] # This is the Rows column
print "col_name.text = "
print col_name.text
print col_type.text
print col_rows.text
if (col_name.text == data_preview):
col_checkbox.click()
return True
return False
except NoSuchElementException, e:
print "Element not found "
print e
self.save_screenshot("data_previews_page_select_element")
return False
return self
How can i click the checkbox that i want?
Thanks,
Riaz
Here you go:
//tr[td[contains(., "Selenium_CRM_Edit_Test")]]//input
Explanation:
First we look at the tr, then we look at the td with specific text that's in the previously looked at tr and after that we find the needed checkbox very easily.
OR
You can go from behind by looking at the span with text first and then going up and up by each level like so:
//span[#title="Selenium_CRM_Edit_Test"]/ancestor::tr//input